Home > Enterprise >  Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype
Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype

Time:12-30

I am trying to fetch data from backend and store it in my app. However when I am using method to fetch it i am facing this error Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'StartChapter'. Is my model set up wrong or the fetching function is written wrong? Can someone advice me something? Thanks

Method that fetches data:

  Future<List<Adventures>> getAdventureList() async {
    var response = await getAdventures(apiClient);
    return List<Adventures>.from((response.data["collection"]).map((json) => Adventures.fromJson(json)));
  }

I am trying to fetch data from my backend, example JSON looks like:

{
   "collection":[
      {
         "completed":true,
         "creator_id":"4b94b85f-696e-4682-9534-572d1b2bc47f",
         "creator_nick":"master_of_adventure69",
         "description":"go on a wonderful adventure through the streets of the old town ...",
         "favorite":true,
         "id":"ffcc3fad-8bc2-4ba3-9b8e-59d77b2bff23",
         "name":"The best adventure in the world",
         "start_chapter":{
            "completed":true,
            "description":"at this point you must demonstrate extraordinary intelligence ...",
            "id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
            "name":"first point in adventure",
            "position":{
               "lat":53.01379,
               "lon":18.598444
            },
            "question":[
               {
                  "chapter_id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
                  "description":"What has a tail and barks?",
                  "id":"3718f6a9-fff1-4a15-9a24-ae3fa90b4141",
                  "sort":1,
                  "type":"tip/question"
               }
            ],
            "radius":500,
            "ridle":{
               "answer":"42856",
               "id":"ce8545e6-eeca-41c0-9026-9084df5aad13",
               "type":"number_lock_5"
            },
            "tips":[
               {
                  "chapter_id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
                  "description":"What has a tail and barks?",
                  "id":"3718f6a9-fff1-4a15-9a24-ae3fa90b4141",
                  "sort":1,
                  "type":"tip/question"
               }
            ]
         }
      }
   ],
   "page":1,
   "page_size":50,
   "total_pages":1
}

Model

class Adventure {
  List<Adventures>? collection;
  int page;
  int page_size;
  int total_pages;
  int total_results;

  Adventure({ this.collection, required this.page, required this.page_size, required this.total_pages,
     required this.total_results });

  factory Adventure.fromJson(Map<String, dynamic> json) {
    return Adventure(
      collection: json['collection'].map((item) => Adventures.fromJson(item)).toList(),
      page: json['page'],
      page_size: json['page_size'],
      total_pages: json['total_pages'],
      total_results: json['total_results']
    );
  }
}

class Adventures {
  bool completed;
  String creatorId;
  String creatorNick;
  String? description;
  bool favorite;
  String id;
  String name;
  StartChapter startChapter;

  Adventures(
      {required this.completed,
      required this.creatorId,
      required this.creatorNick,
        this.description,
      required this.favorite,
      required this.id,
      required this.name,
      required this.startChapter});

  factory Adventures.fromJson(Map<String, dynamic> json) {
    return Adventures(
        completed: json['completed'],
        creatorId: json['creator_id'],
        creatorNick: json['creator_nick'],
        description: json['description'],
        favorite: json['favorite'],
        id: json['id'],
        name: json['name'],
        startChapter: json['start_chapter']
    );
  }
}
and so on

CodePudding user response:

If you have a already StartChapter model and 'fromJson' method,
try to change like below.

class Adventures {
  bool completed;
  String creatorId;
  String creatorNick;
  String? description;
  bool favorite;
  String id;
  String name;
  StartChapter startChapter;

  Adventures(
      {required this.completed,
      required this.creatorId,
      required this.creatorNick,
        this.description,
      required this.favorite,
      required this.id,
      required this.name,
      required this.startChapter});

  factory Adventures.fromJson(Map<String, dynamic> json) {
    return Adventures(
        completed: json['completed'],
        creatorId: json['creator_id'],
        creatorNick: json['creator_nick'],
        description: json['description'],
        favorite: json['favorite'],
        id: json['id'],
        name: json['name'],
        startChapter: json['start_chapter'] != null ? StartChapter.fromJson(json['start_chapter']) : null
    );
  }
}

If not, define 'fromJson' into the StartChapter class.
Or change startChapter's type from 'StartChapter' to 'Map<String, dynamic>' class.

class Adventures {
  bool completed;
  String creatorId;
  String creatorNick;
  String? description;
  bool favorite;
  String id;
  String name;
  Map<String, dynamic> startChapter;
...

CodePudding user response:

This error occurred because you are passing wrong data type value to the variable.

start_chapter accepts type of StartChapter but you are passing Map here :

"start_chapter":{
            "completed":true,
            "description":"at this point you must demonstrate extraordinary intelligence ...",
            "id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
            "name":"first point in adventure",
            "position":{
               "lat":53.01379,
               "lon":18.598444
            },
            "question":[
               {
                  "chapter_id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
                  "description":"What has a tail and barks?",
                  "id":"3718f6a9-fff1-4a15-9a24-ae3fa90b4141",
                  "sort":1,
                  "type":"tip/question"
               }
            ],
            "radius":500,
            "ridle":{
               "answer":"42856",
               "id":"ce8545e6-eeca-41c0-9026-9084df5aad13",
               "type":"number_lock_5"
            },
            "tips":[
               {
                  "chapter_id":"5130dd90-9738-4a26-aeea-10d7d9c905b5",
                  "description":"What has a tail and barks?",
                  "id":"3718f6a9-fff1-4a15-9a24-ae3fa90b4141",
                  "sort":1,
                  "type":"tip/question"
               }
            ]
         }
      }

You need to pass data type of StartChapter to solve this issue.

Use below model :

import 'dart:convert';

Adventure adventureFromJson(String str) => Adventure.fromJson(json.decode(str));

String adventureToJson(Adventure data) => json.encode(data.toJson());

class Adventure {
    Adventure({
        this.collection,
        this.page,
        this.pageSize,
        this.totalPages,
    });

    List<Collection> collection;
    int page;
    int pageSize;
    int totalPages;

    factory Adventure.fromJson(Map<String, dynamic> json) => Adventure(
        collection: json["collection"] == null ? null : List<Collection>.from(json["collection"].map((x) => Collection.fromJson(x))),
        page: json["page"] == null ? null : json["page"],
        pageSize: json["page_size"] == null ? null : json["page_size"],
        totalPages: json["total_pages"] == null ? null : json["total_pages"],
    );

    Map<String, dynamic> toJson() => {
        "collection": collection == null ? null : List<dynamic>.from(collection.map((x) => x.toJson())),
        "page": page == null ? null : page,
        "page_size": pageSize == null ? null : pageSize,
        "total_pages": totalPages == null ? null : totalPages,
    };
}

class Collection {
    Collection({
        this.completed,
        this.creatorId,
        this.creatorNick,
        this.description,
        this.favorite,
        this.id,
        this.name,
        this.startChapter,
    });

    bool completed;
    String creatorId;
    String creatorNick;
    String description;
    bool favorite;
    String id;
    String name;
    StartChapter startChapter;

    factory Collection.fromJson(Map<String, dynamic> json) => Collection(
        completed: json["completed"] == null ? null : json["completed"],
        creatorId: json["creator_id"] == null ? null : json["creator_id"],
        creatorNick: json["creator_nick"] == null ? null : json["creator_nick"],
        description: json["description"] == null ? null : json["description"],
        favorite: json["favorite"] == null ? null : json["favorite"],
        id: json["id"] == null ? null : json["id"],
        name: json["name"] == null ? null : json["name"],
        startChapter: json["start_chapter"] == null ? null : StartChapter.fromJson(json["start_chapter"]),
    );

    Map<String, dynamic> toJson() => {
        "completed": completed == null ? null : completed,
        "creator_id": creatorId == null ? null : creatorId,
        "creator_nick": creatorNick == null ? null : creatorNick,
        "description": description == null ? null : description,
        "favorite": favorite == null ? null : favorite,
        "id": id == null ? null : id,
        "name": name == null ? null : name,
        "start_chapter": startChapter == null ? null : startChapter.toJson(),
    };
}

class StartChapter {
    StartChapter({
        this.completed,
        this.description,
        this.id,
        this.name,
        this.position,
        this.question,
        this.radius,
        this.ridle,
        this.tips,
    });

    bool completed;
    String description;
    String id;
    String name;
    Position position;
    List<Question> question;
    int radius;
    Ridle ridle;
    List<Question> tips;

    factory StartChapter.fromJson(Map<String, dynamic> json) => StartChapter(
        completed: json["completed"] == null ? null : json["completed"],
        description: json["description"] == null ? null : json["description"],
        id: json["id"] == null ? null : json["id"],
        name: json["name"] == null ? null : json["name"],
        position: json["position"] == null ? null : Position.fromJson(json["position"]),
        question: json["question"] == null ? null : List<Question>.from(json["question"].map((x) => Question.fromJson(x))),
        radius: json["radius"] == null ? null : json["radius"],
        ridle: json["ridle"] == null ? null : Ridle.fromJson(json["ridle"]),
        tips: json["tips"] == null ? null : List<Question>.from(json["tips"].map((x) => Question.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "completed": completed == null ? null : completed,
        "description": description == null ? null : description,
        "id": id == null ? null : id,
        "name": name == null ? null : name,
        "position": position == null ? null : position.toJson(),
        "question": question == null ? null : List<dynamic>.from(question.map((x) => x.toJson())),
        "radius": radius == null ? null : radius,
        "ridle": ridle == null ? null : ridle.toJson(),
        "tips": tips == null ? null : List<dynamic>.from(tips.map((x) => x.toJson())),
    };
}

class Position {
    Position({
        this.lat,
        this.lon,
    });

    double lat;
    double lon;

    factory Position.fromJson(Map<String, dynamic> json) => Position(
        lat: json["lat"] == null ? null : json["lat"].toDouble(),
        lon: json["lon"] == null ? null : json["lon"].toDouble(),
    );

    Map<String, dynamic> toJson() => {
        "lat": lat == null ? null : lat,
        "lon": lon == null ? null : lon,
    };
}

class Question {
    Question({
        this.chapterId,
        this.description,
        this.id,
        this.sort,
        this.type,
    });

    String chapterId;
    String description;
    String id;
    int sort;
    String type;

    factory Question.fromJson(Map<String, dynamic> json) => Question(
        chapterId: json["chapter_id"] == null ? null : json["chapter_id"],
        description: json["description"] == null ? null : json["description"],
        id: json["id"] == null ? null : json["id"],
        sort: json["sort"] == null ? null : json["sort"],
        type: json["type"] == null ? null : json["type"],
    );

    Map<String, dynamic> toJson() => {
        "chapter_id": chapterId == null ? null : chapterId,
        "description": description == null ? null : description,
        "id": id == null ? null : id,
        "sort": sort == null ? null : sort,
        "type": type == null ? null : type,
    };
}

class Ridle {
    Ridle({
        this.answer,
        this.id,
        this.type,
    });

    String answer;
    String id;
    String type;

    factory Ridle.fromJson(Map<String, dynamic> json) => Ridle(
        answer: json["answer"] == null ? null : json["answer"],
        id: json["id"] == null ? null : json["id"],
        type: json["type"] == null ? null : json["type"],
    );

    Map<String, dynamic> toJson() => {
        "answer": answer == null ? null : answer,
        "id": id == null ? null : id,
        "type": type == null ? null : type,
    };
}
  • Related