Home > other >  InternalLinkedHashMap error when trying to parse the DIO response to an object in flutter
InternalLinkedHashMap error when trying to parse the DIO response to an object in flutter

Time:02-15

Im using Dio package to maintain REST API connections.

when I call this particular API end point. I get a response but when I try to parse that to an object it gives me the error

type _internalLinkedHashMap<String, dynamic> is not a subtype of type String occurred

I tried so many things but still no solution worked for me.

Object class

import 'dart:convert';

DetailsModel detailsModelFromJson(String str) =>
    DetailsModel.fromJson(json.decode(str));

String detailsModelToJson(DetailsModel data) => json.encode(data.toJson());

class DetailsModel {
  DetailsModel({
    this.venueId,
    this.lat,
    this.lng,
    this.events,
    this.hasEvents,
    this.categories,
    this.name,
    this.overall,
    this.accuracy,
    this.attitude,
    this.createdTime,
    this.updatedTime,
  });

  String? venueId;
  String? lat;
  String? lng;
  List<Event>? events;
  bool? hasEvents;
  List<Category>? categories;
  String? name;
  String? overall;
  String? accuracy;
  String? attitude;
  DateTime? createdTime;
  DateTime? updatedTime;

  factory DetailsModel.fromJson(Map<String, dynamic> json) => DetailsModel(
        venueId: json["venueId"],
        lat: json["lat"],
        lng: json["lng"],
        events: List<Event>.from(json["events"].map((x) => Event.fromJson(x))),
        hasEvents: json["hasEvents"],
        categories: List<Category>.from(
            json["categories"].map((x) => Category.fromJson(x))),
        name: json["name"],
        overall: json["overall"],
        accuracy: json["accuracy"],
        attitude: json["attitude"],
        createdTime: DateTime.parse(json["createdTime"]),
        updatedTime: DateTime.parse(json["updatedTime"]),
      );

  Map<String, dynamic> toJson() => {
        "venueId": venueId,
        "lat": lat,
        "lng": lng,
        "events": List<dynamic>.from(events!.map((x) => x.toJson())),
        "hasEvents": hasEvents,
        "categories": List<dynamic>.from(categories!.map((x) => x.toJson())),
        "name": name,
        "overall": overall,
        "accuracy": accuracy,
        "attitude": attitude,
        "createdTime": createdTime!.toIso8601String(),
        "updatedTime": updatedTime!.toIso8601String(),
      };
}

class Category {
  Category({
    this.categoryId,
    this.name,
    this.subCategories,
  });

  int? categoryId;
  String? name;
  List<SubCategory>? subCategories;

  factory Category.fromJson(Map<String, dynamic> json) => Category(
        categoryId: json["categoryId"],
        name: json["name"],
        subCategories: List<SubCategory>.from(
            json["subCategories"].map((x) => SubCategory.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "categoryId": categoryId,
        "name": name,
        "subCategories":
            List<dynamic>.from(subCategories!.map((x) => x.toJson())),
      };
}

class SubCategory {
  SubCategory({
    this.subCategoryId,
    this.name,
    this.properties,
  });

  int? subCategoryId;
  String? name;
  List<Property>? properties;

  factory SubCategory.fromJson(Map<String, dynamic> json) => SubCategory(
        subCategoryId: json["subCategoryId"],
        name: json["name"],
        properties: List<Property>.from(
            json["properties"].map((x) => Property.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "subCategoryId": subCategoryId,
        "name": name,
        "properties": List<dynamic>.from(properties!.map((x) => x.toJson())),
      };
}

class Property {
  Property({
    this.propertyId,
    this.name,
  });

  int? propertyId;
  String? name;

  factory Property.fromJson(Map<String, dynamic> json) => Property(
        propertyId: json["propertyId"],
        name: json["name"],
      );

  Map<String, dynamic> toJson() => {
        "propertyId": propertyId,
        "name": name,
      };
}

class Event {
  Event({
    this.eventId,
    this.name,
    this.description,
    this.startTime,
    this.endTime,
    this.ticketPrice,
    this.url,
    this.createdTime,
    this.updatedTime,
  });

  String? eventId;
  String? name;
  String? description;
  DateTime? startTime;
  DateTime? endTime;
  String? ticketPrice;
  String? url;
  DateTime? createdTime;
  DateTime? updatedTime;

  factory Event.fromJson(Map<String, dynamic> json) => Event(
        eventId: json["eventId"],
        name: json["name"],
        description: json["description"],
        startTime: DateTime.parse(json["startTime"]),
        endTime: DateTime.parse(json["endTime"]),
        ticketPrice: json["ticketPrice"],
        url: json["url"],
        createdTime: DateTime.parse(json["createdTime"]),
        updatedTime: DateTime.parse(json["updatedTime"]),
      );

  Map<String, dynamic> toJson() => {
        "eventId": eventId,
        "name": name,
        "description": description,
        "startTime": startTime!.toIso8601String(),
        "endTime": endTime!.toIso8601String(),
        "ticketPrice": ticketPrice,
        "url": url,
        "createdTime": createdTime!.toIso8601String(),
        "updatedTime": updatedTime!.toIso8601String(),
      };
}

json response

{
  "venueId": "ChIJny1e18LOsGoRGigq07mJVR4",
  "lat": "-34.9379400000",
  "lng": "138.6115300000",
  "events": [
    {
      "eventId": "da0dd1c7-3fec-4031-a4ea-e2edf5942a69",
      "name": "",
      "description": "this is test description",
      "startTime": "2022-02-14T07:13:33.598Z",
      "endTime": "2022-02-14T04:32:41.374Z",
      "ticketPrice": "0.00",
      "url": "https://www.isa.org",
      "createdTime": "2022-02-11T20:34:36.177Z",
      "updatedTime": "2022-02-11T20:34:36.177Z"
    }
  ],
  "hasEvents": true,
  "categories": [
    {
      "categoryId": 1,
      "name": "Access",
      "subCategories": [
        {
          "subCategoryId": 7,
          "name": "Path",
          "properties": [
            {
              "propertyId": 9,
              "name": "Flat"
            }
          ]
        }
      ]
    }
  ],
  "name": "Marshmallow Playground",
  "overall": "0.00",
  "accuracy": "0.00",
  "attitude": "0.00",
  "createdTime": "2022-02-11T20:16:09.612Z",
  "updatedTime": "2022-02-11T20:16:09.000Z"
}

The api handler function I implemented is as follows.

Future<dynamic> getVenueDetailsById({String? id}) async {
    late int? _responseCode;
    try {
      final response = await _dio.get(
        APIEndpoints.getVenueById   "$id",
      );
      //
      _responseCode = response.statusCode;
      //
      if (_responseCode == 200) {
        if (response.data != null) {
          

//this is the point where the error shows up
          DetailsModel res =
              await DetailsModel.fromJson(jsonDecode(response.data));
          
          log("get success ------------ ");
          return HTTPResponse<dynamic>(
            true,
            res,
            message: 'success',
            code: _responseCode!,
          );
        }
      } else {
        log("get failed response ------------");
      }
    } on DioError catch (e) {
      log("exception ------------ ${e.message}");
      return HTTPResponse<dynamic>(
        false,
        null,
        message: 'error: ${e.message}',
        code: e.response!.statusCode!,
      );
    }
  }

what should I do to make this success?

CodePudding user response:

A quick look at Dio documentation, it seems you should invoke toString on response.data:

DetailsModel res = await DetailsModel.fromJson(jsonDecode(response.data.toString()));

You can see the implementation here: https://pub.dev/documentation/dio/latest/dio/Response/toString.html

CodePudding user response:

You don't need jsonDecode or await on this line. But it's jsonDecode thats causing the issue.

DetailsModel res = await DetailsModel.fromJson(jsonDecode(response.data));

Your response.data is already in the form of a Map so pass that directly into your DetailsModel.fromJson.

As it stands now you're passing in a Map into jsonDecode which expects a String, which explains the error you're getting.

Just change it to this and you should be good to go.

DetailsModel res = DetailsModel.fromJson(response.data);
  • Related