Try it yourself with our free Json Formatter tool — runs entirely in your browser, no signup needed.

How to Parse JSON in Dart

How to Parse JSON in Dart

Parsing JSON in Dart is a fundamental skill for any developer working with web APIs, data storage, or file formats. JSON (JavaScript Object Notation) is a lightweight, human-readable data interchange format that is widely used for exchanging data between systems. In this article, we will explore how to parse JSON in Dart, covering the basics, edge cases, common mistakes, and performance tips.

Quick Example

Here is a minimal example that parses a JSON string into a Dart object:

import 'dart:convert';

void main() {
  const jsonString = '{"name": "John", "age": 30}';
  final jsonData = jsonDecode(jsonString);
  print(jsonData['name']); // Output: John
}

This example uses the json library, which is included in the Dart SDK, to parse the JSON string into a Map<String, dynamic>.

Step-by-Step Breakdown

Let's walk through the code line by line:

  1. import 'dart:convert';: We import the dart:convert library, which provides the jsonDecode function.
  2. const jsonString = '{"name": "John", "age": 30}';: We define a JSON string as a constant.
  3. final jsonData = jsonDecode(jsonString);: We use jsonDecode to parse the JSON string into a Dart object. The jsonDecode function returns a dynamic type, which means it can be any type of object.
  4. print(jsonData['name']);: We access the name property of the parsed JSON object using the [] operator.

Handling Edge Cases

Empty/Null Input

If the input JSON string is empty or null, jsonDecode will throw a FormatException. To handle this, we can add a simple null check:

void main() {
  const jsonString = '';
  if (jsonString.isEmpty) {
    print('Invalid input');
  } else {
    final jsonData = jsonDecode(jsonString);
    print(jsonData['name']);
  }
}

Invalid Input

If the input JSON string is invalid (e.g., malformed or contains invalid characters), jsonDecode will throw a FormatException. To handle this, we can wrap the jsonDecode call in a try-catch block:

void main() {
  const jsonString = '{"name": "John" "age": 30}';
  try {
    final jsonData = jsonDecode(jsonString);
    print(jsonData['name']);
  } catch (e) {
    print('Invalid input: $e');
  }
}

Large Input

If the input JSON string is very large, parsing it can be slow. To improve performance, we can use the JsonDecoder class, which allows us to parse the JSON string in chunks:

void main() {
  const jsonString = '{"name": "John", "age": 30, ...}'; // large JSON string
  final decoder = JsonDecoder();
  final jsonData = decoder.convert(jsonString);
  print(jsonData['name']);
}

Unicode/Special Characters

If the input JSON string contains Unicode or special characters, we need to ensure that the Dart string is properly encoded. We can use the utf8 codec to encode the string:

void main() {
  const jsonString = '{"name": "Jöhn", "age": 30}';
  final encodedJsonString = utf8.encode(jsonString);
  final jsonData = jsonDecode(encodedJsonString);
  print(jsonData['name']);
}

Common Mistakes

Mistake 1: Not Handling Null Input

void main() {
  const jsonString = null;
  final jsonData = jsonDecode(jsonString); // Error: FormatException
}

Corrected code:

void main() {
  const jsonString = null;
  if (jsonString != null) {
    final jsonData = jsonDecode(jsonString);
    print(jsonData['name']);
  } else {
    print('Invalid input');
  }
}

Mistake 2: Not Handling Invalid Input

void main() {
  const jsonString = '{"name": "John" "age": 30}';
  final jsonData = jsonDecode(jsonString); // Error: FormatException
}

Corrected code:

void main() {
  const jsonString = '{"name": "John" "age": 30}';
  try {
    final jsonData = jsonDecode(jsonString);
    print(jsonData['name']);
  } catch (e) {
    print('Invalid input: $e');
  }
}

Mistake 3: Not Handling Large Input

void main() {
  const jsonString = '{"name": "John", "age": 30, ...}'; // large JSON string
  final jsonData = jsonDecode(jsonString); // slow performance
}

Corrected code:

void main() {
  const jsonString = '{"name": "John", "age": 30, ...}'; // large JSON string
  final decoder = JsonDecoder();
  final jsonData = decoder.convert(jsonString);
  print(jsonData['name']);
}

Performance Tips

  1. Use the JsonDecoder class for large input: As mentioned earlier, the JsonDecoder class allows us to parse the JSON string in chunks, improving performance for large input.
  2. Use the utf8 codec for Unicode/special characters: Ensuring that the Dart string is properly encoded using the utf8 codec can improve performance and prevent errors.
  3. Avoid unnecessary parsing: If the JSON string is not going to be used immediately, consider storing it as a string and parsing it only when needed.

FAQ

Q: What is the difference between jsonDecode and JsonDecoder?

A: jsonDecode is a convenience function that parses a JSON string into a Dart object, while JsonDecoder is a class that allows us to parse the JSON string in chunks.

Q: How do I handle invalid input?

A: Wrap the jsonDecode call in a try-catch block to catch FormatException exceptions.

Q: How do I handle large input?

A: Use the JsonDecoder class to parse the JSON string in chunks.

Q: How do I handle Unicode/special characters?

A: Use the utf8 codec to encode the Dart string.

Q: What is the best way to store JSON data in Dart?

A: Store JSON data as a string and parse it only when needed to avoid unnecessary parsing.

AI agent tools available. The CodeTidy MCP Server gives Claude, Cursor, and other AI agents access to 60+ developer tools. One command: npx @codetidy/mcp