0

I was trying to create a function to make a GET with query parameters. I was dealing with the Mangadex API and was to send a parameter called 'manga' as an array. I created the code as follows:

Future<http.Response> getCoverArtResponse(String mangaID) async {
  var queryParameters = {
    'limit': '10',
    'manga': [mangaID] //Here
  };
  var unencodedPath = '/cover';
  var response = await http.get(
      Uri.https(authority, unencodedPath, queryParameters),
      headers: {HttpHeaders.contentTypeHeader: 'application/json'});
  return response;
}

However, the response was the following error:

{"result":"error","errors":[{"id":"9c346772-7b14-5982-b4b6-7b5888522762","status":400,"title":"validation_exception","detail":"Error validating \/manga: String value found, but an array is required","context":null}]}

How am I supposed to send the parameters? So far I have tried -

'manga': [mangaID]
'manga': '[$mangaID]'

None of them seem to work.

1
  • It really depends on how their server expects arrays to be encoded in the query string. It does not seem like there is a standard, and the Mangadex documentation doesn't seem to explicitly specify the format, but it does imply that they expect the key to be manga[], not manga. Therefore try: 'manga[]': [mangaID]. Commented Jul 31, 2021 at 20:09

1 Answer 1

1
import 'dart:async';
import 'package:wnetworking/wnetworking.dart';

class MangaDex {
  static const _base = 'https://api.mangadex.org';

  static FutureOr<void> _getter({required String url, required Function(JMap item, int idx) onItem}) async {
    await HttpReqService.getJson<JMap>(url)
      .then((response) {
        var results = response?['results'];
        if (results != null) {
          if (results is List) {
            var i = 0;
            results.forEach((manga) => onItem(manga, ++i));
          } else {
            print(response);
          }
        }
      });
  }

  static FutureOr<void> cover({int limit = 10, int offset=0, String? mangaId, String? coverId}) async {
    final mangas = mangaId != null ? '&manga[]=$mangaId' : '';
    final covers = coverId != null ? '&ids[]=$coverId' : '';
    final url = '$_base/cover?limit=$limit&offset=$offset$mangas$covers';

    await _getter(
      url: url, 
      onItem: (item, idx) {
        print('$idx) "${item['data']?['attributes']?['fileName']}"');
        print('   id: ${item['data']?['id']}\n');
      },
    );
  }
}

void main(List<String> args) async {
  await MangaDex.cover(mangaId: '32d76d19-8a05-4db0-9fc2-e0b0648fe9d0', limit: 2);
  print('\nJob done');
}

Result:

1) "f5873770-80a4-470e-a11c-63b709d87eb3.jpg"
   id: b6c7ce9c-e671-4f26-90b0-e592188e9cd6

2) "e9f926db-b469-48c4-8cc4-a8e523ad75ca.jpg"
   id: 00aae6e0-46bb-4f92-a82a-1c740789b704


Job done

Replace wnetworking package with http package, and JMap with Map<String, dynamic>

NOTE: MangaDex Documentation is lacking and misleading about how to correctly use its endpoints.

Sign up to request clarification or add additional context in comments.

2 Comments

Yeah thank you very much that worked fine. However, this code seems interesting and I would like to know more about it, could you please explain how it works? Or could you please link an article to an example? That would be very kind of you, thanks. I understand the cover function but I don't understand what the _getter is doing.
It is simple, _getter method is responsible for calling GET requests, when getting a valid response (a List), it runs an operation (onItem function) per every item on that response. This method is useful for endpoints with things in common.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.