105

I wanted to convert a string to map.

String value = "{first_name : fname,last_name : lname,gender : male, location : { state : state, country : country, place : place} }"

into

Map = {
first_name : fname,
last_name : lname,
gender : male,
location = {
  state : state, 
  country : country, 
  place : place
 }
}

How do I convert the string into a map<String, dynamic> where the value consists of string, int, object, and boolean?

I wanted to save the string to a file and obtain the data from the file.

10 Answers 10

181

That's not possible.

If you can change the string to valid JSON, you can use

import 'dart:convert';
...
Map valueMap = json.decode(value);
// or
Map valueMap = jsonDecode(value);

The string would need to look like

{"first_name" : "fname","last_name" : "lname","gender" : "male", "location" : { "state" : "state", "country" : "country", "place" : "place"} }
Sign up to request clarification or add additional context in comments.

3 Comments

If you are saving an existing map, you can likely convert that map to a valid JSON string using json.encode, then it will parse back correctly using json.decode.
how can i covert this type of string to map [{type: Input, title: Hi Group, placeholder: Hi Group flutter, response: fgggh}, {type: Password, title: Password, response: vvvvv}, {type: Email, title: Email test, placeholder: hola a todos, response: cccvc}, {type: TareaText, title: TareaText test, placeholder: hola a todos, response: vvvvv}]
What you posted is not JSON. In JSON all keys and string values would need quotes. If it were valid JSON you could use var decoded = json.decode(yourString); var map = Map.fromIterable(decoded, key: (e) => e.keys.first, value: (e) => e.values.first); (not tested). See also api.dartlang.org/stable/2.1.0/dart-core/Map/…
45

You would have to change the way you create the string.

I'm guessing you are creating the string using the yourMap.toString() method. You should rather use json.encode(yourMap), which converts your map to valid JSON, which you can the parse with json.decode(yourString).

2 Comments

Map insides of Map insides of Map insides of Object(Map). Thanks for reminding me of this
this is usefull
7

create two objects

class User {
  final String firstName;
  final String lastName;
  final String gender;
  final location;

  User({
    this.firstName,
    this.lastName,
    this.gender,
    this.location,
  });

  User.fromJson(Map json)
      : firstName = json['firstName'],
        lastName = json['lastName'],
        gender = json['gender'],
        location = Location.fromJson(json['location']);
}

class Location {
  final String state;
  final String country;
  final String place;

  Location({
    this.state,
    this.country,
    this.place,
  });

  Location.fromJson(Map json)
      : state = json['state'],
        country = json['country'],
        place = json['place'];
}

then use it like this

var user = User.fromJson(value);
print(user.firstName);

or convert it to list like this

var user = User.fromJson(value).toList();

1 Comment

Thank you so much for your solution, I was getting error because I was using .toString instead of jsonEncode
6

you can do like this ->

import 'dart:convert'; ...

if your data like this ** {'bus1':'100Tk','bus2':'150TK','bus3':'200TK'}

**;

then you can do like this ->

Map valueMap = json.decode(value);

// or

Map valueMap = jsonDecode(value);

or if like this ->var data = {'1':'100TK','2':'200TK','3':'300TK'};

var dataSp = data.split(',');
Map<String,String> mapData = Map();
dataSp.forEach((element) => mapData[element.split(':')[0]] = element.split(':')[1]);

Note: Map first value was Int that's why I did that.

Comments

4

Make a wrapper class for the location where you define the methods fromMap, toMap

Comments

2

Yeah, that's not possible.

But i have workaround to fix that.

  • Remove space in ur invalid json
  • Fix ur invalid string json to valid string json
  • Convert valid string json to map

Here's the full code for above process:

import 'dart:convert';

void main() {
  String value = "{first_name : fname,last_name : lname,gender : male, location : { state : state, country : country, place : place} }";
  
  String jsonString = _convertToJsonStringQuotes(raw: value);
  print("Test 1: $jsonString");
  
  final Map<dynamic, dynamic> result = json.decode(jsonString);
  print('Test 2: $result');
}


String _convertToJsonStringQuotes({required String raw}) {
    /// remove space
    String jsonString = raw.replaceAll(" ", "");

    /// add quotes to json string
    jsonString = jsonString.replaceAll('{', '{"');
    jsonString = jsonString.replaceAll(':', '": "');
    jsonString = jsonString.replaceAll(',', '", "');
    jsonString = jsonString.replaceAll('}', '"}');

    /// remove quotes on object json string
    jsonString = jsonString.replaceAll('"{"', '{"');
    jsonString = jsonString.replaceAll('"}"', '"}');

    /// remove quotes on array json string
    jsonString = jsonString.replaceAll('"[{', '[{');
    jsonString = jsonString.replaceAll('}]"', '}]');

    return jsonString;
  }

Comments

1
Map<String, dynamic> item = json.decode(jsonDecode(jsonString));

just use this to change String to Map type after this, you can get data example:

searchedHistoryNameList["{\"symbol\":\"600001\",\"name\":\"邯郸钢铁\",\"is_self\":0,\"type\":1}",
 "{\"symbol\":\"000001\",\"name\":\"平安银行\",\"is_self\":0,\"type\":1}"]

to {symbol: 600001, name: 邯郸钢铁, is_self: 0, type: 1}

and get the item with item["name"]

Comments

0
To convert a string into a map<String, dynamic>, you can use the

following code:

String value = "{first_name : fname,last_name : lname,gender : male, location : { state : state, country : country, place : place} }";
         String result = value
           .replaceAll("{","{\"")
           .replaceAll("}","\"}")
           .replaceAll(":","\":\"")
           .replaceAll(",","\",\"");
        print(result);

Here, we first replace the opening and closing curly braces with double quotes, and then replace the colons and commas with quotes to create a valid JSON string. Then, we use the jsonDecode method to convert the JSON string into a map.

Comments

0

I found a way to cast that string

Ok, lets use a complex model to cast:

final testMap = {
  'userName': 'Igor',
  'age': 22,
  'totalCash': 138.57,
  'isMale:': true,
  'userStatus': {
    'isUserActive': true,
    'isAPremiumUser': false,
  },
  'userTags': ['Flutter Developer', 'Proactive', 'Clean code'],
  'userCourses': [
    {
      'title': 'How to use TDD in flutter',
      'finished': false,
      'coursePercentage': 47.4,
      'buyDate': '1969-07-20T20:18:04.000Z',
      'courseTag': ['New', 'Popular'],
      'courseDetails': null,
    },
    {
      'title': 'Clean arquiteture in flutter',
      'finished': false,
      'coursePercentage': 20.8,
      'buyDate': '1969-07-20T20:18:04.000Z',
      'courseTag': ['New'],
      'courseDetails': {
        'teacherName': 'Tayler Mostoult',
        'totalSubscribers': 5402,
      },
    },
    {
      'title': 'Micro-frontends in flutter',
      'finished': true,
      'coursePercentage': 100.0,
      'buyDate': '1969-07-20T20:18:04.000Z',
      'courseTag': [],
      'courseDetails': {},
    },
  ]
};

Know, cast it to string:

final testMapInStringFormat = testMap.toString();

To convert this String to map, we can use:

// Decoded, back to map format
final Map response = _getJsonFromString(testMap.toString()); 

The function that will effectively do the casting:


  Map<String, dynamic> _getJsonFromString(String rawText) {
    // Will find, for exemple, the text: "{isUserActive:"
    final regexMapKeyWithOpenBracket = RegExp('(?<={)(.*?):+');
    // Will find, for exemple, the text: ", userCourses:"
    final regexMapKeyWithCommaAndSpace = RegExp(r'(?<=, )([^\]]*?):');

    final regexOnlyKeyInLine = RegExp(r'^.+:$');

    final splitedSentences = rawText
        .replaceAllMapped(regexMapKeyWithCommaAndSpace,
            (Match match) => '\n${match.text.trim()}\n')
        .replaceAllMapped(regexMapKeyWithOpenBracket,
            (Match match) => '\n${match.text.trim()}\n')
        .replaceAll(RegExp(r'}(?=,|]|}|$|\s+)'), '\n}\n')
        .replaceAll(RegExp(r'(?<=(,|:|^|\[)\s?){'), '\n{\n')
        .replaceAll(RegExp('\\[\\s?\\]'), '\n[\n]\n')
        .replaceAll(RegExp('\\{\\s?\\}'), '\n{\n}\n')
        .replaceAll('[', '\n[\n')
        .replaceAll(']', '\n]\n')
        .replaceAll(',', '\n,\n')
        .split('\n')
      ..removeWhere((element) => element.replaceAll(' ', '').isEmpty);

    final List<String> correctLines = [];
    for (String line in splitedSentences) {
      final isMapKey = regexOnlyKeyInLine.hasMatch(line);

      if (isMapKey) {
        final lineWithoutFinalTwoDots = line.substring(0, line.length - 1);
        final lineWithQuaot = _putQuotationMarks(lineWithoutFinalTwoDots);

        correctLines.add('$lineWithQuaot:');
      } else {
        String l = line.trim();

        final hasCommaInFinal = l.endsWith(',') && l.length > 1;
        if (hasCommaInFinal) l = l.substring(0, l.length - 1);

        // If it falls in this else, it is a value of a key or a map structure
        final isNumber = double.tryParse(l) != null || int.tryParse(l) != null;
        final isBolean = l == 'false' || l == 'true';
        final isStructureCaracter =
            ['{', '}', '[', ']', ','].any((e) => e == l);
        final isNull = l == 'null';
        if (isStructureCaracter || isNumber || isBolean || isNull) {
          if (hasCommaInFinal) {
            correctLines.add('$l,');
          } else {
            correctLines.add(l);
          }
          continue;
        }

        // If you got to this point, i'm sure it's a value string, so lets add a double quote
        final lineWithQuaot = _putQuotationMarks(l);
        if (hasCommaInFinal) {
          correctLines.add('$lineWithQuaot,');
        } else {
          correctLines.add(lineWithQuaot);
        }
      }
    }

    final Map<String, dynamic> decoded = {};
    (jsonDecode(correctLines.join('')) as Map)
        .cast<String, dynamic>()
        .forEach((key, value) {
      decoded[key] = value;
    });

    return decoded;
  }

extension MatchExtension on Match {
  String get text => input.substring(start, end);
}

String _putQuotationMarks(String findedText) {
  if (!findedText.startsWith('\'') && !findedText.startsWith('"')) {
    findedText = findedText[0] + findedText.substring(1);
  }
  if (!findedText.endsWith('\'')) {
    final lastIndex = findedText.length - 1;
    findedText = findedText.substring(0, lastIndex) + findedText[lastIndex];
  }
  return '"$findedText"';
}

Comments

-2

Use below method
just pass String json data it will give Map data

jsonStringToMap(String data){
      List<String> str = data.replaceAll("{","").replaceAll("}","").replaceAll("\"","").replaceAll("'","").split(",");
      Map<String,dynamic> result = {};
      for(int i=0;i<str.length;i++){
        List<String> s = str[i].split(":");
        result.putIfAbsent(s[0].trim(), () => s[1].trim());
      }
      return result;
    }

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.