parseDartMapString function

Map<String, dynamic> parseDartMapString(
  1. String input
)

Safely parses a string that looks like a Map into an actual Map<String, dynamic> Handles strings like "{number: 98653253625, formId: 2, responseEventType: }" which aren't valid JSON but are common in Flutter toString() outputs

Implementation

Map<String, dynamic> parseDartMapString(String input) {
  // Check if input is empty
  if (input.isEmpty) {
    return {};
  }

  try {
    // First try standard JSON parsing (in case it's actually valid JSON)
    return json.decode(input);
  } catch (_) {
    // Not valid JSON, try manual parsing
    Map<String, dynamic> result = {};

    // Remove the outer braces if they exist
    String cleanInput = input.trim();
    if (cleanInput.startsWith('{') && cleanInput.endsWith('}')) {
      cleanInput = cleanInput.substring(1, cleanInput.length - 1).trim();
    }

    // Split by commas, but not those inside quotes
    List<String> parts = [];
    bool inQuotes = false;
    int startPos = 0;

    for (int i = 0; i < cleanInput.length; i++) {
      if (cleanInput[i] == '"' || cleanInput[i] == "'") {
        inQuotes = !inQuotes;
      } else if (cleanInput[i] == ',' && !inQuotes) {
        parts.add(cleanInput.substring(startPos, i).trim());
        startPos = i + 1;
      }
    }

    // Add the last part
    if (startPos < cleanInput.length) {
      parts.add(cleanInput.substring(startPos).trim());
    }

    // Process each key-value pair
    for (String part in parts) {
      if (part.isEmpty) continue;

      // Find the separator between key and value
      int colonIndex = part.indexOf(':');
      if (colonIndex == -1) continue;

      String key = part.substring(0, colonIndex).trim();
      String valueStr = part.substring(colonIndex + 1).trim();

      // Remove quotes from key if present
      if ((key.startsWith('"') && key.endsWith('"')) ||
          (key.startsWith("'") && key.endsWith("'"))) {
        key = key.substring(1, key.length - 1);
      }

      // Parse the value
      dynamic value;

      // Empty value
      if (valueStr.isEmpty) {
        value = null;
      }
      // Try to parse as number
      else if (RegExp(r'^-?\d+(\.\d+)?$').hasMatch(valueStr)) {
        value = num.tryParse(valueStr) ?? valueStr;
      }
      // Boolean values
      else if (valueStr == 'true') {
        value = true;
      }
      else if (valueStr == 'false') {
        value = false;
      }
      // Null value
      else if (valueStr == 'null') {
        value = null;
      }
      // String value (with quotes)
      else if ((valueStr.startsWith('"') && valueStr.endsWith('"')) ||
               (valueStr.startsWith("'") && valueStr.endsWith("'"))) {
        value = valueStr.substring(1, valueStr.length - 1);
      }
      // Default to string
      else {
        value = valueStr;
      }

      result[key] = value;
    }

    return result;
  }
}