0

I'm trying to send a nested object to the server with GetConnect. However, after many attempts I fail to do so. I look onto Flutter Docs; nevertheless, it use the same JSON.decode as I am. The content type I set up for the backend is application/json. How I can solve this?

Future<List<MainItem>> addItem() async {
    var mainItem = MainItem(
      name: name,
      description: description,
      itemTypeId: itemTypeId,
      userId: userId,
      itemUuid: itemUuid,
      inventory: Inventory(
          inventoryUuid: '',
          price: 0,
          quantity: 0,
          box: 0,
          pricePerItem: 0,
          itemInBox: 0,
          inStoragePrice: 0,
          inStorageItem: 0),
      image: ItemImage(imageUrl: imageUrl),
      location: InventoryLocation(
          description: locationDescription,
          name: locationName,
          address: Address(
              countryId: countryId,
              stateId: stateId,
              streetAddress: streetAddress,
              city: city,
              zipCode: zipCode)),
    ).toJson();
    print('Values pass to Future: $mainItem', contentType: 'application/json; charset=UTF-8');
    final res = await post('/item/$userId', mainItem);
    if (res.status.hasError) {
      return Future.error(res.statusText!);
    } else {
//I think this shouldn't be decoded since content type is application/json
      return (res.body as List).map((e) => MainItem.fromJson(e)).toList();
    }
  }

When I'm sending the POST request, the console shows this message:

[GETX] Cannot decode server response to json

If I run Chrome for debug, without hot reload, this shows up:

 Expected a value of type 'List<MainItem>?', but got one of type 'TypeErrorImpl'
 at Object.throw_ [as throw] (http://localhost:60831/dart_sdk.js:5037:11)
    at Object.castError (http://localhost:60831/dart_sdk.js:5010:15)
    at Object.cast [as as] (http://localhost:60831/dart_sdk.js:5319:17)
    at dart.NullableType.new.as (http://localhost:60831/dart_sdk.js:6826:60)
    at http://localhost:60831/packages/booking_management_dashboard/screen/pages/tablet/widgets/choice_chip/choice_chip.dart.lib.js:6436:49
    at _RootZone.runUnary (http://localhost:60831/dart_sdk.js:37245:59)
    at _FutureListener.then.handleError (http://localhost:60831/dart_sdk.js:32513:48)
    at handleError (http://localhost:60831/dart_sdk.js:33044:51)
    at Function._propagateToListeners (http://localhost:60831/dart_sdk.js:33070:17)
    at _Future.new.[_completeWithValue] (http://localhost:60831/dart_sdk.js:32914:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:60831/dart_sdk.js:32935:35)
    at Object._microtaskLoop (http://localhost:60831/dart_sdk.js:37497:13)
    at _startMicrotaskLoop (http://localhost:60831/dart_sdk.js:37503:13)
    at http://localhost:60831/dart_sdk.js:33274:9

Here is the MainItem model. There should be 3 more models; but, they code the same as this model. So, the MainItem model alone could present what I'm trying to do.

class MainItem {
  String? name, description, userId, itemUuid, createdAt;
  int? id, itemTypeId;
  InventoryLocation? location;
  ItemImage? image;
  Inventory? inventory;

  MainItem({
    @required this.name,
    @required this.description,
    @required this.location,
    this.itemUuid,
    this.createdAt,
    this.userId,
    this.id,
    this.itemTypeId,
    this.image,
    this.inventory,
  });

  Map<String, dynamic> toJson() {
    final data = <String, dynamic>{};
    data['name'] = name;
    data['id'] = id;
    data['uuid'] = itemUuid;
    data['user_id'] = userId;
    data['createdAt'] = createdAt;
    data['description'] = description;
    data['item_type_id'] = itemTypeId;
    data['location'] = location!.toJson();
    data['item_image'] = image!.toJson();
    data['inventory'] = inventory!.toJson();

    return data;
  }

  factory MainItem.fromJson(Map<String, dynamic> json) => MainItem(
        id: json['id'] as int? ?? 0,
        itemTypeId: json['item_type_id'] as int? ?? 0,
        name: json['name'] ?? 'Nothing found',
        itemUuid: json['uuid'] ?? 'Nothing found',
        userId: json['user_id'] ?? 'Nothing found',
        createdAt: json['createdAt'] ?? 'Nothing found',
        description: json['description'] ?? 'Nothing found',
        image: ItemImage.fromJson(json['item_image']),
        location: InventoryLocation.fromJson(json['location']),
        inventory: Inventory.fromJson(json['inventory']),
      );

  factory MainItem.fromRawJson(String str) =>
      MainItem.fromJson(json.decode(str));

  String toRawJson() => json.encode(toJson());

  @override
  String toString() {
    return 'Values are name: $name, description: $description, location : $location, userId: $userId,  image: $image';
  }
}

The console that print out:

Values pass to Future: {name: aaas, id: null, uuid: 295efed7-b8ab-4329-b857-3acb147a2e3c, user_id: 82670000-effa-4669-936a-d6c1b1ab0583, createdAt: null, description: ssss, item_type_id: 302, location: {id: null, location_name: eee, location_description: rrr,
location_uuid: null, address_uuid: null, address: {id: null, street_address: aaaa, state_id: 7, address_uuid: null, zipcode: 123, city: sssss, country_id: 1}}, item_image: {id: null, image_url:
https://media.istockphoto.com/vectors/red-rubber-stamp-icon-on-transparent-background-vector-id918650450?k=6&m=918650450&s=612x612&w=0&h=eIpOHzRxfCcSsnV83xddS9Jguvpshj5vcvkOrkmGJXk=, image_uuid: null}, inventory: {id: null, inventory_uuid: , box: 0, quantity: 0,
price: 0, itemInBox: 0, pricePerItem: 0, inStorageItem: 0, inStoragePrice: 0}}

Console.log print out the data from backend:

{
  name: 'aaaa',
  uuid: '34360ad5-0427-410e-bacc-3052bb310cd7',
  item_type_id: 302,
  description: 'sssss',
  sku: null,
  user_id: '82670000-effa-4669-936a-d6c1b1ab0583',
  item_image: {
    image_url: 'https://media.istockphoto.com/vectors/red-rubber-stamp-icon-on-transparent-background-vector-id918650450?k=6&m=918650450&s=612x612&w=0&h=eIpOHzRxfCcSsnV83xddS9Jguvpshj5vcvkOrkmGJXk='
  },
  inventory: {
    price: 66666,
    quantity: 231,
    box: 123,
    itemInBox: 23,
    inStoragePrice: 0,
    pricePerItem: 0,
    inStorageItem: 0
  },
  location: {
    location_name: 'eeee',
    location_description: 'rrrr',
    address: {
      id: 108,
      street_address: 'aaaaa',
      state_id: 7,
      country_id: 1,
      zipcode: 123,
      city: 'sssss'
    }
  }
}
  • Can you please include the error message you are getting and the model definition? Specially the toJson and fromJson methods. – S. M. JAHANGIR May 22 '21 at 10:35
  • @S.M.JAHANGIR hi, I have updated my question above. I'm looking forward to seeing your replies. Thank you :) – Kaiser Senpai May 23 '21 at 04:42
  • Can you also include the response.bodyString? – S. M. JAHANGIR May 23 '21 at 08:14
  • @S.M.JAHANGIR hi, I might misinterpret my question a bit. The content type I set up for the backend is application/json. So, the encode step here might be unnecessary. However, the error still the same. I updated the question again. Thank you. – Kaiser Senpai May 24 '21 at 01:59
  • I wanted you to print and include the result of `res.bodyString`, I mean what you are getting back from the server. – S. M. JAHANGIR May 24 '21 at 08:53
  • @S.M.JAHANGIR Hi, I updated the console.log from the backend if it's that you're looking for. – Kaiser Senpai May 25 '21 at 03:30
  • May be I was too unclear. ` final res = await post('/item/$userId', mainItem);` after this line, put `print(res.bodyString);` and include the printed output. – S. M. JAHANGIR May 25 '21 at 03:57
  • @S.M.JAHANGIR after many attempts, I fail to print res.bodyString for some reasons. I tried debugPrint with wrapWidth: 1024 but it failed as well. Packages for logging like logger also fail to reproduce the res.bodyString. I question the GetConnect package if it support the print res.bodyString. Otherwise, if you have other suggestion, please let me know. – Kaiser Senpai May 25 '21 at 10:14
  • You failed to print res.bodyString? Are you sure? Can you please tell what you've did and include your code and logs? I'm using GetConnect without any issues. – S. M. JAHANGIR May 25 '21 at 15:00
  • @S.M.JAHANGIR Hi, I show you what I code above. Since I'm unsure of how this happen, if it's possible, can you show me a demo of how you would normally code. It would save us lots of time to troubleshoot. – Kaiser Senpai May 25 '21 at 15:20
  • Listen, I don't think it has anything to do with how you've done. It looks totally fine. I think the problem lies within the response you are getting from the server. So on your `addItem()` method between the lines `final res=await post(...` and `if(res.status.hasError...` place an `print(res.bodyString)` and let me see the output from the flutter console/run log. Is that clear? Hope so. – S. M. JAHANGIR May 26 '21 at 15:35
  • Hi, bad news is I still fail to produce the res.bodyString in my MainItem model; However, good news is I try with a simple mock data with with print(res.bodyString), I achieve a result. So, I think this has to do with the nested model when I do a deep level JSON return. I guess GetConnect still in a premature state for production since it fails to return nested JSON; otherwise, you can show me how to do it. – Kaiser Senpai May 27 '21 at 04:37
  • Nope. I am using GetConnect in production without any issues. And can you please do what I am asking you to do: and that is, print(res.bodyString) just right after your post request? I did not ask to do it in your model. And it's going beyond frustrating. If you can't provide or do the very simple thing, I am afraid if I can or anyone can help you. – S. M. JAHANGIR May 27 '21 at 08:37

0 Answers0