Unhandled Exception: type 'Null' is not a subtype of type 'String'

3,779

Solution 1

Please check your Product class. Its attributes should be able to be Null.

So it's may be String? not String

  Product(
        id: key,
        title: value['title'],
        description: value['description'],
        price: value['price'],
        isFavorite: value['isFavorite'],
        imageUrl: value['imageUrl']));
  }

I checked the response from https://flutter-39ecc-default-rtdb.firebaseio.com/products.json. There are some missing keys that need to use when construct the Product object.

Solution 2

this is happenned because one of the value you're trying to assign is null while the variable is not nullable

        loadedProducts.add(Product(
            id: key,
            title: value['title'],
            description: value['description'],
            price: value['price'],
            isFavorite: value['isFavorite'],
            imageUrl: value['imageUrl']));
      });

look at this code, if you want to make a model class of product, it would be great if you make every variable nullable.

class ProductModel {
  int? id;
  String? title;
  String? description;
  double? price;
  bool? isFavorite;
  String? imageUrl;
}

And it would be great if you really careful with the assignment from the backend. Because some backend aren't consistent.

factory ProductModel ProductModel.fromJson(Map<String, dynamic> json) => ProductModel({
  id: json['id'] != null ? (json['id'] as num?)?.toInt() : null, 
//it would be great if you also check if the json['id'] is instance of String or not, because sometimes you can get id with type String from backend
// why use num? instead of int?, because sometimes we can also get double from backend right? and int and double indicator isn't consistent
// that's why num? then cast to the type you want is the best practice
  title: json['title'] as String?,
  
  
  //etc..
});
Share:
3,779
FZ3R0
Author by

FZ3R0

Updated on January 02, 2023

Comments

  • FZ3R0
    FZ3R0 over 1 year

    i was taking a Flutter course (the course was recorded before flutter 2) when i ran into this error:

    I/flutter ( 3538): type 'Null' is not a subtype of type 'String'
    E/flutter ( 3538): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'Null' is not a subtype of type 'String'
    E/flutter ( 3538): #0      Products.fetchAndSetProducts
    package:shop_app/providers/products_provider.dart:80
    E/flutter ( 3538): <asynchronous suspension>
    

    I tried to check if there was something wrong on the line highlighted and for me it was ok.

    Here is the code:

    Future<void> fetchAndSetProducts() async {
        var url = Uri.parse(
            'https://flutter-39ecc-default-rtdb.firebaseio.com/products.json');
        try {
          final response = await http.get(url);
          final extractedData = json.decode(response.body) as Map<String, dynamic>;
          final List<Product> loadedProducts = [];
          extractedData.forEach((key, value) {
            loadedProducts.add(Product(
                id: key,
                title: value['title'],
                description: value['description'],
                price: value['price'],
                isFavorite: value['isFavorite'],
                imageUrl: value['imageUrl']));
          });
          _items = loadedProducts;
          notifyListeners();
          // print(json.decode(response.body));
        } catch (error) {
          print(error);
          throw error;  // line 80
        }
      }
    

    This is how i´m calling this function

      var _isInit = true;
      var _isLoading = false;
      @override
      void didChangeDependencies() {
        if (_isInit) {
          setState(() {
            _isLoading = true;
          });
          Provider.of<Products>(context).fetchAndSetProducts().then((_) {
            setState(() {
              _isLoading = false;
            });
          });
        }
        _isInit = false;
        super.didChangeDependencies();
      }