How to convert Response JSON to Object in Flutter?

57,157

Solution 1

Don't need to use cast, you can parse directly to a Map

final Map parsed = json.decode(res); 

After you have a map you can use that data to convert into your Object.

final signUp = SignUpResponse.fromJson(parsed);

And if you want to parse an array of objects, you could do something like this:

//assuming this json returns an array of signupresponse objects
final List parsedList = json.decode(res); 

List<SignUpResponse> list = parsedList.map((val) =>  SignUpResponse.fromJson(val)).toList();

Solution 2

The JSON :

    [
     {
       "id":1,
       "name":"Afghanistan",
       "iso3":"AFG",
       "iso2":"AF",
       "phone_code":"93",
       "capital":"Kabul",
       "currency":"AFN"
     },
     {
       "id":2,
       "name":"Aland Islands",
       "iso3":"ALA",
       "iso2":"AX",
       "phone_code":"+358-18",
       "capital":"Mariehamn",
       "currency":"EUR"
       },
    ]

The POJO Class :

    class country{
       String id;
       String name;
       String currency;

       country({this.id,this.name,this.currency});

       factory country.fromJson(Map<String, dynamic> parsedJson){
         return country(
         id: parsedJson['id'].toString(),
         name : parsedJson['name'].toString(),
         currency: parsedJson['currency'].toString() 
         );
       }
    }

API CALL :

    await http.post("http://calikidsmap.com/test.php").then((response){

    var ddd=jsonDecode(response.body);

    Country_object_list = (ddd as List)
      .map((data) => new country.fromJson(data))
      .toList();

Solution 3

Add this to pubspec.yaml

dependencies:
  # Your other regular dependencies here
  json_annotation: <latest_version>

dev_dependencies:
  # Your other dev_dependencies here
  build_runner: <latest_version>
  json_serializable: <latest_version>

Object class.

import 'package:json_annotation/json_annotation.dart';


part 'user.g.dart'; //"user" is your dart file name

/// JSON serialization logic to be generated.
@JsonSerializable()

class User {
  User(this.name, this.email);

  String name;
  String email;

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  Map<String, dynamic> toJson() => _$UserToJson(this);
}

And run this in Terminal of Android Studio.

flutter pub run build_runner build

Now convert like this:

Map results =  json.decode(response.body);
User user = User.fromJson(results);

Source: https://flutter.dev/docs/development/data-and-backend/json

Solution 4

Same answer but, what happens when you have nested JsonObjects? Easy:

Given a jsonResponse like this:

{
  "id": 1,
  "type": 15,
  "innerClass": {
    "id": 1,
    "type": "testing"
  }
}

This is an example of how the code looks like:

class MainClass {
  int id = 0;
  int version = 0;
  InnerClass innerClass;

  MainClass (
      this.id,
      this.version,
      this.innerClass
      );
  
//Create the same factory converter, but using another inner factory 'fromJson' converter
//for the inner class object (InnerClass.fromJson(json['inner_class']))

  factory MainClass.fromJson(dynamic json) {
    return MainClass(
        json['id'] as int, // << put your json response keys instead.
        json['version'] as int,
        InnerClass.fromJson(json['innerClass']) // << this one
    );
  }

Then, repeat the same strategy but for the inner class object:

class InnerClass {
  int id = 0;
  String type = 'testing_type';
  InnerClass (
      this.id,
      this.type
      );
  factory InnerClass.fromJson(dynamic json) {
    return InnerClass(
        json['id'] as int,
        json['type'] as String
    );
  }
}

Finally, you could cosume that, in another part of you project like this:

try {
          mainClassDartObject = MainClass.fromJson(response.body);
     } catch (e) {
          print(e);
     }

Solution 5

Here is a basic answer for this if you want to access your information after the request with no extra steps.

 Map<String, dynamic> data = jsonDecode(response.body);
 String token = tokenData["data"]["access_token"];

the structure of the object from the request was like this:

{
  "success":1,
  "error":[],
  "data": {
     "access_token":"13d2ec9d1094903b1e81de8af059233e9f36ec4d",
     "expires_in":2628000,
     "token_type":"Bearer"
  }
}
Share:
57,157
Harsh Bhavsar
Author by

Harsh Bhavsar

Hello, I am Harsh Bhavsar. Having 4+ experience in mobile development and 1+ year of experience in flutter development. • In mobile development, I have worked with Image-Video Editing Apps, Survery Apps, Chat Apps, Location-Map based Apps, Various management Apps, BLE related Apps etc. About my area work in flutter. • I have worked with Flutter's UI/UX , Google Maps, Couchbase, Socket connection, Sync gateways, Localizations, Customised plateform specific plugins, plateform specfic codes/views, Firestores with flutter, Chat with XMPP(native Android) and openfire, FFmpeg for Image-Video processing etc. We have worked with MVC, BLoc and Flux design pattern/ state management based on project requirements.

Updated on January 14, 2022

Comments

  • Harsh Bhavsar
    Harsh Bhavsar over 2 years

    I am trying to convert success JSON string to Object. May be I am not doing in proper manner But I have couple of question related to converting JSON to Object.

    Also I am getting this exeption in Log.

    NoSuchMethodError: Class '**_InternalLinkedHashMap<String, dynamic>' has no instance method 'cast' with matching arguments**.<br>
    Receiver: _LinkedHashMap len:3
    **Tried calling: cast<Map<String, dynamic>>()**
    
    1. Should I need cast that data object in model too?
    2. Which is the best and simple way to convert JSON to Object (SignUpResponse).
    3. Its better to do with serialization ?

    Response JSON :

    {
        "data": {
            "_id": "5bd2a59f4c59de1ac517d7bf",
            "email": "[email protected]",
            "phoneNumber": "2417874147",
            "isAddressApproved": 0,
            "unitNumber": "144",
            "streetAddress": "sdfsddsf",
            "area": "asd",
            "zipCode": "112233",
            "totalOrder": 0,
            "todayOrder": 0,
            "isPauseDelivery": false,
            "vacationStartDt": null,
            "vacationEndDt": null,
            "defaultLiter": 1
        },
        "message": "New User Created",
        "error": false
    }
    

    SignUpResponse which was created by online tool.

    class SignUpResponse {
        Data data;
        String message;
        bool error;
    
        SignUpResponse({this.data, this.message, this.error});
    
        SignUpResponse.fromJson(Map<String, dynamic> json) {
        data = json['data'] != null ? new Data.fromJson(json['data']) : null;
        message = json['message'];
        error = json['error'];
        }
    
        Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        if (this.data != null) {
            data['data'] = this.data.toJson();
        }
        data['message'] = this.message;
        data['error'] = this.error;
        return data;
        }
    }
    
    class Data {
        String sId;
        String email;
        String phoneNumber;
        int isAddressApproved;
        String unitNumber;
        String streetAddress;
        String area;
        String zipCode;
        int totalOrder;
        int todayOrder;
        bool isPauseDelivery;
        Null vacationStartDt;
        Null vacationEndDt;
        int defaultLiter;
    
        Data(
            {this.sId,
            this.email,
            this.phoneNumber,
            this.isAddressApproved,
            this.unitNumber,
            this.streetAddress,
            this.area,
            this.zipCode,
            this.totalOrder,
            this.todayOrder,
            this.isPauseDelivery,
            this.vacationStartDt,
            this.vacationEndDt,
            this.defaultLiter});
    
        Data.fromJson(Map<String, dynamic> json) {
        sId = json['_id'];
        email = json['email'];
        phoneNumber = json['phoneNumber'];
        isAddressApproved = json['isAddressApproved'];
        unitNumber = json['unitNumber'];
        streetAddress = json['streetAddress'];
        area = json['area'];
        zipCode = json['zipCode'];
        totalOrder = json['totalOrder'];
        todayOrder = json['todayOrder'];
        isPauseDelivery = json['isPauseDelivery'];
        vacationStartDt = json['vacationStartDt'];
        vacationEndDt = json['vacationEndDt'];
        defaultLiter = json['defaultLiter'];
        }
    
        Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['_id'] = this.sId;
        data['email'] = this.email;
        data['phoneNumber'] = this.phoneNumber;
        data['isAddressApproved'] = this.isAddressApproved;
        data['unitNumber'] = this.unitNumber;
        data['streetAddress'] = this.streetAddress;
        data['area'] = this.area;
        data['zipCode'] = this.zipCode;
        data['totalOrder'] = this.totalOrder;
        data['todayOrder'] = this.todayOrder;
        data['isPauseDelivery'] = this.isPauseDelivery;
        data['vacationStartDt'] = this.vacationStartDt;
        data['vacationEndDt'] = this.vacationEndDt;
        data['defaultLiter'] = this.defaultLiter;
        return data;
        }
    }
    

    Calling REST POST API

    void postCallSignUp(BuildContext context, var body) {
    // This Function will check Internet is available or not.
    Utils.checkConnection().then((connectionResult) {
        if (connectionResult) {
        http.post(Constants.BASE_URL + Constants.CREATE_USER,
            body: body,
            headers: {
                "Accept": "application/json",
                "content-type": "application/json"
            }).then((http.Response response) {
            final String res = response.body;
            final int statusCode = response.statusCode;
    
            if (statusCode < 200 || statusCode > 400 || json == null) {
            _onFailureResponse(new Exception("Error while fetching data"));
            } else {
            //Parsing json response to particular Object.
            print(json.decode(res));
    
            // Unable to cast json here...
            final parsed = json.decode(res).cast<Map<String, dynamic>>();
            parsed.map<SignUpResponse>((json) => SignUpResponse.fromJson(json));
            SignUpResponse signUpResponse = parsed.map<SignUpResponse>((json) => SignUpResponse.fromJson(json));
            _onSuccessResponse(signUpResponse);
            }
        });
        } else {
        _onNoInternetConnection();
        Utils.showAlert(context, "Alert", "Internet is not connected.", () {
            Navigator.pop(context);
        });
        }
    });
    }
    

    Unable to understand what is happening here ? Why we have to do so much for convert our json to particular object ?