problem converting json response to object in Flutter

first all sorry about my "engrish"... I'm trying to consume an own API method with http package in Flutter. I'm able to get a response from API but I'm having trouble trying to map the response (json) to my custom object called APILoginResponse.

I'm calling the API method like this:

APILoginResponse apiLogin = await api.apiLogin();

but I'm getting a runtime error "dynamic is not subtype of AccessToken".

Here is my API login method:

Future<APILoginResponse> apiLogin() async {
  final http.Response response = await http.post(
    api_end_point + '/api/Auth/login',
    headers: <String, String>{
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode(
        <String, String>{'userName': api_user, 'password': api_password}),
  );
  if (response.statusCode == 200) {
    return APILoginResponse.fromJson(json.decode(response.body));
  } else {
    throw Exception('Error en login de la API');
  }
}

...and here is my APILoginResponse object:

class APILoginResponse {
  final AccessToken accessToken;
  final String refreshToken;

  APILoginResponse({this.accessToken, this.refreshToken});

  factory APILoginResponse.fromJson(Map<String, dynamic> json) {
    return APILoginResponse(
      accessToken: json['accessToken'],
      refreshToken: json['refreshToken'],
    );
  }
}

class AccessToken {
  String token;
  int expiresIn;
}

error is in the line:

accessToken: json['accessToken']

inside APILoginResponse class.

Here is my json response:

{
  "accessToken": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiIiLCJzdWIiOiJib3N0b25jcmVkX2NsaWVudGVzIiwianRpIjoiZjBkMzY0ZDMtMmRkNS00NzkzLWE5ZTktMzY1YzJmODNiYmI3IiwiaWF0IjoxNTk0MTMxODAwLCJyb2wiOiJhcGlfYWNjZXNzIiwiaWQiOiIyMzg3YTMzZi1hYzE5LTRhMzYtODcyZC04MTE3MzExZDFjY2IiLCJuYmYiOjE1OTQxMzE3OTksImV4cCI6MTU5NDEzMjM5OSwiaXNzIjoid2ViQXBpIiwiYXVkIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzMTcvLyJ9.PqCPkVct4e4duWFEr63fALZ0h_0x25vsV_GBx336Apw",
    "expiresIn": 600
  },
  "refreshToken": "W6wyiw9xYuC2UaJmyCOYujKIZTs0jAscnfcWTrEyVIk="
}

Any help with this will be appreciated. Thanks!

Upvotes: 0

Views: 65

Answers (2)

well I think @P4yam answer was right but I was getting the same error over and over, so I changed my APILoginResponse class as follow:

class APILoginResponse {
  AccessToken accessToken;
  String refreshToken;

  APILoginResponse({this.accessToken, this.refreshToken});

  APILoginResponse.fromJson(Map<String, dynamic> json) {
    accessToken = json['accessToken'] != null
        ? new AccessToken.fromJson(json['accessToken'])
        : null;
    refreshToken = json['refreshToken'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.accessToken != null) {
      data['accessToken'] = this.accessToken.toJson();
    }
    data['refreshToken'] = this.refreshToken;
    return data;
  }
}

class AccessToken {
  String token;
  int expiresIn;

  AccessToken({this.token, this.expiresIn});

  AccessToken.fromJson(Map<String, dynamic> json) {
    token = json['token'];
    expiresIn = json['expiresIn'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['token'] = this.token;
    data['expiresIn'] = this.expiresIn;
    return data;
  }
}

and everything works fine now! thanks!

Upvotes: 0

Payam Asefi
Payam Asefi

Reputation: 2757

If you are sure that the returning value is an AccessToken you can try this:

  factory APILoginResponse.fromJson(Map<String, dynamic> json) {
   return APILoginResponse(
   accessToken: (json['accessToken'] as Map<String,dynamic>) as AccessToken ?? null,
   refreshToken: json['refreshToken'],
   );
 }

Change your AccessToken class to this:

class AccessToken {
   final Map<String,dynamic> tokenData;
   AccessToken(tokenData)
}

Upvotes: 1

Related Questions