Search code examples
flutterretrofit

Flutter Retrofit issue with two different json response in one API


I have been using Retrofit for API calling. In one of the API sending two different response and trying to get them in Map<String, dynamic> But in generated file it is showing error.

enter image description here

When i take response type as Map<String, String> for one of the response is fine but in other response have different types of keys. Exception is being caught when type is Map<String, String> and Json keys has int value.

One response

   {
  "count": 1,
  "login_type": "PASSWORD",
  "success": true,
  "type": "object",
  "data": {
    "token_type": "Bearer",
    "expires_in": 1200,
    "access_token": "1o+BYL3LWRs+JpHMK3E5",
    "refresh_token": "OAPwbwFORpQ0R6sg",
    "userId": 358
  }
}

Other response

{"count":1,"type":"success","data":{"success":true,"otpEnabled":true,"message":"OTP has been sent to your mobile no 62*****32","timestamp":"","otp":572800}}

Error

type 'int' is not a subtype of type 'String' in type cast


Solution

  • UI:

        Row(
          children: <Widget>[
            ElevatedButton(
              onPressed: firstAPI,
              child: const Text("Call First"),
            ),
            ElevatedButton(
              onPressed: secondAPI,
              child: const Text("Call Second API"),
            ),
          ],
        ),
      ),
    

    First API Call (One response):

      Future<void> firstAPI() async {
        const String path = "https://www.jsonkeeper.com/b/99ID"; // hosted One res
        final Response<dynamic> res = await Dio().get(path);
        final FirstModel firstModel = FirstModel.fromJson(res.data);
        log("firstAPI(): ${firstModel.toJson()}");
        return Future<void>.value();
      }
    

    Second API Call (Other response):

      Future<void> secondAPI() async {
        const String path = "https://www.jsonkeeper.com/b/49KW"; // hosted Other res
        final Response<dynamic> res = await Dio().get(path);
        final SecondModel secondModel = SecondModel.fromJson(res.data);
        log("secondAPI(): ${secondModel.toJson()}");
        return Future<void>.value();
      }
    

    first_model.dart:

    class FirstModel {
      FirstModel({this.count, this.loginType, this.success, this.type, this.data});
    
      FirstModel.fromJson(Map<String, dynamic> json) {
        count = json["count"];
        loginType = json["login_type"];
        success = json["success"];
        type = json["type"];
        data = json["data"] != null ? Data.fromJson(json["data"]) : null;
      }
      int? count;
      String? loginType;
      bool? success;
      String? type;
      Data? data;
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        data["count"] = count;
        data["login_type"] = loginType;
        data["success"] = success;
        data["type"] = type;
        if (this.data != null) {
          data["data"] = this.data!.toJson();
        }
        return data;
      }
    }
    
    class Data {
      Data({
        this.tokenType,
        this.expiresIn,
        this.accessToken,
        this.refreshToken,
        this.userId,
      });
    
      Data.fromJson(Map<String, dynamic> json) {
        tokenType = json["token_type"];
        expiresIn = json["expires_in"];
        accessToken = json["access_token"];
        refreshToken = json["refresh_token"];
        userId = json["userId"];
      }
      String? tokenType;
      int? expiresIn;
      String? accessToken;
      String? refreshToken;
      int? userId;
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        data["token_type"] = tokenType;
        data["expires_in"] = expiresIn;
        data["access_token"] = accessToken;
        data["refresh_token"] = refreshToken;
        data["userId"] = userId;
        return data;
      }
    }
    

    second_model.dart:

    class SecondModel {
      SecondModel({this.count, this.type, this.data});
    
      SecondModel.fromJson(Map<String, dynamic> json) {
        count = json["count"];
        type = json["type"];
        data = json["data"] != null ? Data.fromJson(json["data"]) : null;
      }
      int? count;
      String? type;
      Data? data;
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        data["count"] = count;
        data["type"] = type;
        if (this.data != null) {
          data["data"] = this.data!.toJson();
        }
        return data;
      }
    }
    
    class Data {
      Data({this.success, this.otpEnabled, this.message, this.timestamp, this.otp});
    
      Data.fromJson(Map<String, dynamic> json) {
        success = json["success"];
        otpEnabled = json["otpEnabled"];
        message = json["message"];
        timestamp = json["timestamp"];
        otp = json["otp"];
      }
      bool? success;
      bool? otpEnabled;
      String? message;
      String? timestamp;
      int? otp;
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = <String, dynamic>{};
        data["success"] = success;
        data["otpEnabled"] = otpEnabled;
        data["message"] = message;
        data["timestamp"] = timestamp;
        data["otp"] = otp;
        return data;
      }
    }
    

    Output:

    output