Why is the value in this map NULL?

Viewed 103

Error: "NoSuchMethodError: 'length' method not found. Receiver: null" when updating map values

List<ImageDetails> _images = [
  ImageDetails(
    imagePath: 'assets/images/meal1.jpg',
    date: '2021-11-30',
    details:
        '',
  ),
  ImageDetails(
    imagePath: 'assets/images/meal2.jpg',
    date: '2021-11-30',
    details:
        '',
  ),
];

    var dateToImages = new Map();
    _images.sort((a,b) => a.date.compareTo(b.date));
    //group images by date
    for (int i = 0; i < _images.length; i++) {
      var d = _images[i].date; //convert string to Datetime
      print("printing datetime in for loop");
      print(d);
      if (dateToImages.containsKey(d)) {
        print("second element");
        var list = dateToImages[d].add(_images[i]);
        dateToImages[d] = list;
      } else {
        print("first element");
        dateToImages[d] = [_images[i]];
      }
    }
    var sortedKeys = dateToImages.keys.toList()..sort((a, b) => a.compareTo(b));
    List<Widget> children = [];
    print("=====printing datetoImages");
    print(dateToImages);
    print("======== printing sortedKeys");
    print(sortedKeys);
    int len = dateToImages['2021-11-30'].length;

Below is result of running above code

printing datetime in for loop
2021-11-30
first element
printing datetime in for loop
2021-11-30
second element
=====printing datetoImages
{2021-11-30: null}
======== printing sortedKeys
[2021-11-30]

After printing some variables, it seems like the issue is with the value for key "2021-11-30" in dateToImages being null... I don't understand why I keep getting null since it seems like the map building process in the for loop seems to be going well? Can anyone shed some light on this bug?

Thanks!

2 Answers

try this :

List<ImageDetails> _images = [
 ImageDetails(
  imagePath: 'assets/images/meal1.jpg',
  date: '2021-12-30',
  details:
      '',
 ),
 ImageDetails(
  imagePath: 'assets/images/meal2.jpg',
  date: '2021-11-30',
  details:
     '',
 ),
]; 

var dateToImages = new Map();

_images.forEach((img){

 if(dateToImages.containsKey(img.date)){
  dateToImages[img.date].add(img);
 }else{
  dateToImages[img.date] = [img];
 }
});

var sortedKeys = dateToImages.keys.toList()..sort((a, b) => 
a.compareTo(b));
print("=====printing datetoImages");
print(dateToImages);
print("======== printing sortedKeys");
print(sortedKeys);

int len = dateToImages['2021-11-30'].length;

Output:

=====printing datetoImages
{2021-12-30: [Instance of 'ImageDetails'], 2021-11-30: [Instance of 
'ImageDetails']}
======== printing sortedKeys
[2021-11-30, 2021-12-30]

The error message suggests you are accessing length method which is not available. since null doesn't have length method but list have it.

So, you may have a logical error, where you think you are returning list but the code is returning null

In your case:

Your Code is fine except for this part:

if (dateToImages.containsKey(d)) {
        print("second element");
        var list = dateToImages[d].add(_images[i]);
        dateToImages[d] = list;
}

add() method returns void which will return null to var list and null will be sent to the map

Update it directly, replace above code with this:

if (dateToImages.containsKey(d)) {
        print("second element");
        dateToImages[d].add(_images[i]);  
}
Related