skip to Main Content

I’m working on a Flutter/Dart application where I need to pass a Map object from one screen to another. However, I want to ensure that the original Map object remains unchanged and that any modifications made to the passed Map object on the second screen do not affect the original Map object on the first screen. Original Map object contains JSON init so it will be not clear structure of it.

Map originalMap = {
  'question': 'What is your name',
};
Map modifiedMap = {
  'question': 'What is your name',
  'answer': 'XYZ',
};

I’ve considered using methods like copyWith or creating a new Map object from the original Map.

Map modifiedMap = new Map.from(originalMap);
Map modifiedMap = JSON.decode(JSON.encode(originalMap));

Any guidance or examples would be greatly appreciated.
Thank you!

2

Answers


  1. instead of map, i would prefer class. in class you can make the class immutable by adding const modifier on it’s constructor and then create copyWith function. then if you want to manage the data flow easily, i suggest you to have state management so you can share data across screen and modify them easily.
    imagine Model View Controller. you have Model class which is the QuestionAnswerModel, you have QuizController to control the UI, you have QuizQuestionView and QuizDetailView which accessing one controller (QuizController)

    it would be whole lot easier if you don’t use map.
    anyway you might be interested in Code Generation (https://pub.dev/packages/freezed this is my favorite Code Generation to generate model class) this will allow you to generate boilerplate such as copyWith automatically

    Login or Signup to reply.
  2. What you are looking for is performing a deep copy of your JSON object.

    Deep copy

    JSON objects, when represented as Dart objects are of type Map<String, dynamic>, where according to JSON specification the datatype for the dynamic are:

    • string
    • number
    • boolean
    • null
    • object (JSON object => Map<String, dynamic>)
    • array

    Your deep copy function shall consider all the types in order to also copy the nested objects, which is not performed when using Map.from or List.from constructors.

    Map<String, dynamic> jsonCopy(Map<String, dynamic> original) {
      Map<String, dynamic> copy = {};
    
      original.forEach((key, value) {
        if (value is Map<String, dynamic>) {
          copy[key] = jsonCopy(value); // Recursively deep copy nested maps
        } else if (value is List) {
          copy[key] = _listCopy(value); // Call listCopy for lists
        } else if (value is String ||
                   value is num ||
                   value is bool ||
                   value == null) {
          copy[key] = value; // Only accept JSON data types: string, number, boolean, null
        } else {
          throw ArgumentError('Unsupported data type found in JSON object: $value');
        }
      });
    
      return copy;
    }
    
    List<dynamic> _listCopy(List<dynamic> original) {
      List<dynamic> copy = [];
    
      for (var item in original) {
        if (item is Map<String, dynamic>) {
          copy.add(jsonCopy(item)); // Recursively deep copy nested maps
        } else if (item is List) {
          copy.add(_listCopy(item)); // Recursively deep copy nested lists
        } else if (item is String ||
                   item is num ||
                   item is bool ||
                   item == null) {
          copy.add(item); // Only accept JSON data types: string, number, boolean, null
        } else {
          throw ArgumentError('Unsupported data type found in JSON array: $item');
        }
      }
    
      return copy;
    }
    

    To Json => from Json

    An alternative could be just convert you JSON object to a string and then back to an object:

    try {
      final Map<String, dynamic> copy = json.decode(json.encode(original));
    } catch (e) {
      throw ArgumentError('Couldn't parse object data to JSON');
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search