0

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 [];
  }
}
2
  • What's the error? Commented Jun 4, 2022 at 20:19
  • when i am passing the getProducts() as a future for a FutureBuilder, in the builder , its giving snapshot.hasData=false. I am getting the response from API, its when I am trying to convert it into a list, I am hitting a snag. Commented Jun 5, 2022 at 2:29

2 Answers 2

1

You have missed to decode the response

try {
  final response = await _dio.get(url);
  if (response.statusCode! < 205) {
    return json.decode(response.data);
  }
Sign up to request clarification or add additional context in comments.

Comments

0

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'] ?? '',
    );
  }

1 Comment

I have provided the JSON response this API call would give and none of the fields are null in that. Though a useful suggestion, my problem is not with nullability here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.