2

I know how to convert Map<dynamic, dynamic> to Map<String, dynamic> using Map.from() method. But what if I have unspecified number of nested Maps inside? How to convert all potential children as well from Map<dynamic, dynamic> to Map<String, dynamic>?

1
  • 1
    It will be easy to understand if you will add response map data Commented Dec 21, 2021 at 12:06

4 Answers 4

2

Same answer as fravolt's but I was unable do put code in comments:

Map.forEach do not treats value by reference. You may change to:

// recursively convert the map
Map<String, dynamic> convertMap(Map<dynamic, dynamic> map) {
    for (var key in map.keys) {
      if (map[key] is Map) {
        map[key] = convertMap(map[key]);
      }
    }  // use .from to ensure the keys are Strings
  return Map<String, dynamic>.from(map);
  // more explicit alternative way:
  // return Map.fromEntries(map.entries.map((entry) => MapEntry(entry.key.toString(), entry.value)));
}
Sign up to request clarification or add additional context in comments.

Comments

1

Same answer but with additional condition for List

/// recursively convert the map tp Map<String,dynamic>
Map<String, dynamic> convertMap(Map<dynamic, dynamic> map) {
  for (var key in map.keys) {
    if (map[key] is Map) {
      map[key] = convertMap(map[key]);
    } else if (map[key] is List) {
      map[key] = map[key].map((e) {
        if (e is Map) {
          return convertMap(e);
        }
        return e;
      }).toList();
    }
  }
  return Map<String, dynamic>.from(map);
}

Comments

0

You could use a recursive approach to this problem, where all map values of type Map are recursively converted as well.

// recursively convert the map
Map<String, dynamic> convertMap(Map<dynamic, dynamic> map) {
  map.forEach((key, value) {
    if (value is Map) {
      // it's a map, process it
      value = convertMap(value);
    }
  });
  // use .from to ensure the keys are Strings
  return Map<String, dynamic>.from(map);
  // more explicit alternative way:
  // return Map.fromEntries(map.entries.map((entry) => MapEntry(entry.key.toString(), entry.value)));
}

// example nested map with dynamic values
Map<dynamic, dynamic> nestedMap = {
  'first': 'value',
  'second': {
    'foo': 'bar',
    'yes': 'ok',
    'map': {'some': 'value'},
  }
};

// convert the example map
Map<String, dynamic> result = convertMap(nestedMap);
print(result);

4 Comments

this is a great idea but i still get this error '"type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>' in type cast"'. what am I doing wrong?
The exact code I posted runs fine in dartpad for me. It sounds like it might have to do with how Map.from should be used.
Maybe it works for you if you explicitly parse the keys to Strings? I added the alternative return line where the entry keys are first mapped to Strings to the code above
ok it works fine now, there was a problem with nested parsing with freezed. thank you for your help :)
0
Map<String, dynamic> convertMap(Map<dynamic, dynamic> map) {
  map.forEach((key, value) {
    if (value is Map) {
      // logger.d("key: $key ${value.runtimeType}");
      // it's a map, process it
      map[key] = convertMap(value);
      // logger.d("key: $key ${value.runtimeType}");
    }
  });
  // use .from to ensure the keys are Strings
  return Map<String, dynamic>.from(map);
  // more explicit alternative way:
  // return Map.fromEntries(map.entries.map((entry) => MapEntry(entry.key.toString(), entry.value)));
}

Comments

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.