dstaley
dstaley

Reputation: 1042

Convert JSON to map with string keys and List<String> values

I'm attempting to convert JSON that has strings for keys and string arrays for values.

From my understanding, this should work:

import 'dart:convert';

void main() {
  var jsonString = '{"key": ["1", "2", "3"]}';
  var data = json.decode(jsonString) as Map;
  var result = data.cast<String, List<String>>();
  print(result);
}

However I get the error that type 'List<dynamic>' is not a subtype of type 'List<String>' in type cast.

What's interesting, however, is that the following does correctly work:

import 'dart:convert';

void main() {
  var jsonString = '{"key": "value"}';
  var data = json.decode(jsonString) as Map;
  var result = data.cast<String, String>();
  print(result);
}

So, I assume that the .cast<> method introduced with Dart 2 doesn't know how to convert nested types that aren't simple types like String, int, or bool.

How would I convert this object to a Map<String, List<String>> without resorting to external libraries?

Upvotes: 2

Views: 3909

Answers (1)

munificent
munificent

Reputation: 12364

So, I assume that the .cast<> method introduced with Dart 2 doesn't know how to convert nested types that aren't simple types like String, int, or bool.

That's correct. It just does a one-level-deep shallow conversion. You can do the nested conversion yourself like:

void main() {
  var jsonString = '{"key": ["1", "2", "3"]}';
  var data = json.decode(jsonString) as Map;

  var result = data.map((key, value) =>
      MapEntry<String, List<String>>(key, List<String>.from(value)));
  print(result.runtimeType);
}

This is calling Map.map(). Sometimes Map.fromIterable() or Map.fromIterables() is a better fit. The collection types have a handful of methods like this to convert between different types.

Upvotes: 3

Related Questions