Null aware assignment of map entry

384 Views Asked by At

Is there an elegant way to write the following statement for a map?

  String? img = json['image'];
  if (img != null) {
    json['image'] = 'https://example.com/ingredients_100x100/' + img;
  }

Basically I want to append the image IFF it exists and ignore if it does not. This has the opposite effect of ??= where the assignment occurs only if the image is found to be null. Which is similar to putIfAbsent.

The best I can come up with is this:

String? img = json['image'];
json['image'] = img != null ? 'https://example.com/ingredients_100x100/' + img : null;

I just feel like this is the wrong way of writing for null safety as the word null appears twice in a line.

1

There are 1 best solutions below

1
On BEST ANSWER

You could also use the update method of Map. It will throw an error if the key 'image' does not exist. With the update method, you can also easily provide a default if the key image does not exist.

const baseImgUrl = 'https://example.com/ingredients_100x100/';
const defaultImgFilename = 'default.png';

Map<String, dynamic> updateImage(Map<String, dynamic> json) {
  try {
    return json
      ..update(
        'image',
        (filename) => '$baseImgUrl$filename',
      );
  } catch (_) { // key not in map
    return json;
  }
}

Map<String, dynamic> updateImageWithDefault(Map<String, dynamic> json) {
    return json
      ..update(
        'image',
        (filename) => '$baseImgUrl$filename',
        ifAbsent: () => '$baseImgUrl$defaultImgFilename',
      );
}

void main() {
  Map<String, dynamic> jsonWithoutImage = {'data': 123};

  updateImage(jsonWithoutImage);
  print('JSON without image: $jsonWithoutImage');
  // JSON without image: {data: 123}
  
  updateImageWithDefault(jsonWithoutImage);
  print('JSON with default image: $jsonWithoutImage');
  // JSON with default image: {data: 123, image: https://example.com/ingredients_100x100/default.png}

  Map<String, dynamic> jsonWithImage = {'data': 123, 'image': 'apple.png'};
  
  updateImage(jsonWithImage);
  print('JSON with image: $jsonWithImage');
  // JSON with image: {data: 123, image: https://example.com/ingredients_100x100/apple.png}
}