Home > Mobile >  Flutter Error in parsing JSON after getting response from API using dio
Flutter Error in parsing JSON after getting response from API using dio

Time:06-05

I was using dio to get the API response from http://fakestoreapi.com/docs . While i was getting the response , which is a List of Maps (sample json output at https://pastebin.com/ubkJLp7d ), it is when I am trying to convert this list into a List of Product (my PODO) that I am running into an error. i made a function :

final ApiService _api = locator<ApiService>();

  Future<List<Product>> getProducts() async {
    final response = await _api.get(endpoint: 'products?limit=5');
    try {
      List<Product> products =
          List<Product>.from(response.map((e) => Product.fromJson(e)));
      return products;
    } on Exception catch (e) {
      print(e.toString());
    }
    return [];
  }

When I am using this function in a FutureBuilder, I am snapshot.hasData=false. Just to check the response , I made a test function :

Future<void> test() async {
    final response = await _api.get(endpoint: 'products?limit=5');
    print(response.length);
    print(response[0]);
    print(Product.fromJson(response[0]).title);
  }

And it gave all the right outputs. So I making some mistake while making the List of Products. What am I doing wrong and how to fix it?

Relavant code : product.dart:

class Product {
  int id, rateCount;
  double price, rating;
  String title, description, category, imageUrl;

  Product({
    required this.id,
    required this.rateCount,
    required this.price,
    required this.rating,
    required this.title,
    required this.description,
    required this.category,
    required this.imageUrl,
  });

  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'],
      rateCount: json['rating']['count'],
      price: json['price'],
      rating: json['rating']['rate'],
      title: json['title'],
      description: json['description'],
      category: json['category'],
      imageUrl: json['image'],
    );
  }

  Map<String, dynamic> toJson() => {
        'id': id,
        'title': title,
        'price': price,
        'description': description,
        'category': category,
        'image': imageUrl,
        'rating': {
          'rate': rating,
          'count': rateCount,
        }
      };
}

api_service.dart:

class ApiService {
  static const String BASE_URL = 'https://fakestoreapi.com/';
  final Dio _dio = Dio();

  Future<dynamic> get({required String endpoint}) async {
    String url = BASE_URL   endpoint;
    try {
      final response = await _dio.get(url);
      if (response.statusCode! < 205) {
        return response.data!;
      }
    } on Exception catch (e) {
      print(e.toString());
    }
    return [];
  }
}

CodePudding user response:

You shouldn't assume your API responses to never return null fields, this is likely where your error is occurring. If it's not, maybe it's not the type you expect (for instance, the json contains an '0' where you expect a 0).

One way to handle nullability is to make your attributes nullable.

class Product {
  int? id, rateCount;
  double? price, rating;
  String? title, description, category, imageUrl;

  Product({
    required this.id,
    this.rateCount,
    this.price,
    this.rating,
    this.title,
    this.description,
    this.category,
    this.imageUrl,
  });


  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'],
      rateCount: json['rating']['count'],
      price: json['price'],
      rating: json['rating']['rate'],
      title: json['title'],
      description: json['description'],
      category: json['category'],
      imageUrl: json['image'],
    );
  }

The other way is to provide default values when json['key'] is null.

  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'] ?? 0,
      rateCount: json['rating']['count'] ?? 0,
      price: json['price'] ?? 0.0,
      rating: json['rating']['rate'] ?? 0.0,
      title: json['title'] ?? '',
      description: json['description'] ?? '',
      category: json['category'] ?? '',
      imageUrl: json['image'] ?? '',
    );
  }

CodePudding user response:

You have missed to decode the response

try {
  final response = await _dio.get(url);
  if (response.statusCode! < 205) {
    return json.decode(response.data);
  }
  • Related