BACK TO THE HOMEPAGE

Nov 01, 2023 4 min read

Local JSON with Dart

Using Dart to process JSON can seem a complicated choice at first. There are a couple of things to be aware of when processing JSON. To build our understanding I will be taking a manual approach to hand crank through a JSON file. Obviously you shouldnt do this in the real world, but this is meant to be an educational post :-) In the following blog post I assume you already have the Flutter environment setup. If you dont have an environment handy you can use dartpad.dev or similar to practice.

Local JSON

This example demonstrates loading a JSON array from a local file and displaying the data in a list.

Remember to handle potential errors, especially when dealing with file operations and network requests in more complex scenarios. Also consider creating data models using json_serializable for more robust type safety in larger projects.

  1. Project Setup:

    • Create a new Flutter project (if you don’t already have one): flutter create my_app
    • Navigate to the project directory: cd my_app
  2. Create the JSON file:

    • In the root of your project (or in an assets folder), create a JSON file (e.g., data.json).
    • Add some JSON data to it. For example:
NODE_TYPE // json
[
  {
    "id": 1,
    "name": "Item 1",
    "description": "This is the first item."
  },
  {
    "id": 2,
    "name": "Item 2",
    "description": "This is the second item."
  }
]
  1. Update pubspec.yaml:
    • Declare the assets folder in your pubspec.yaml file so Flutter knows to include it in your application bundle. Add the following to your pubspec.yaml under the flutter: section:
NODE_TYPE // yaml
flutter:
  assets:
    - data.json
    # or if you have an assets folder
    # - assets/data.json
*   Run `flutter pub get` to fetch the updated dependencies.
  1. Load the JSON data:
    • In your Flutter code (e.g., in lib/main.dart), create a function to load the JSON data from the asset file. You’ll use the rootBundle class from package:flutter/services.dart.
NODE_TYPE // dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;

Future<String> loadJsonData() async {
  var jsonText = await rootBundle.loadString('data.json'); // or 'assets/data.json' if in assets folder
  return jsonText;
}
  1. Parse the JSON data:
NODE_TYPE // dart
Future<List<dynamic>> parseJsonData() async {
  String jsonString = await loadJsonData();
  final jsonResult = jsonDecode(jsonString);
  return jsonResult;
}
  1. Display the data in a Widget:
    • Use a FutureBuilder to handle the asynchronous loading and parsing of the JSON data. Then display the content.
NODE_TYPE // dart
class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Local JSON Example'),
      ),
      body: FutureBuilder<List<dynamic>>(
        future: parseJsonData(),
        builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {
          if (snapshot.hasData) {
            return ListView.builder(
              itemCount: snapshot.data!.length,
              itemBuilder: (BuildContext context, int index) {
                return ListTile(
                  title: Text(snapshot.data![index]['name']),
                  subtitle: Text(snapshot.data![index]['description']),
                );
              },
            );
          } else if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}'));
          } else {
            return const Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }
}
  1. Complete main.dart:
    • Wrap it all up in the standard main.dart file:
NODE_TYPE // dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;

Future<String> loadJsonData() async {
  var jsonText = await rootBundle.loadString('data.json');
  return jsonText;
}

Future<List<dynamic>> parseJsonData() async {
  String jsonString = await loadJsonData();
  final jsonResult = jsonDecode(jsonString);
  return jsonResult;
}

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Local JSON Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Local JSON Example'),
      ),
      body: FutureBuilder<List<dynamic>>(
        future: parseJsonData(),
        builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {
          if (snapshot.hasData) {
            return ListView.builder(
              itemCount: snapshot.data!.length,
              itemBuilder: (BuildContext context, int index) {
                return ListTile(
                  title: Text(snapshot.data![index]['name']),
                  subtitle: Text(snapshot.data![index]['description']),
                );
              },
            );
          } else if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}'));
          } else {
            return const Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }
}
  1. Run the application: flutter run

Conclusion

Handling JSON in Flutter/Dart is a common and crucial task when building applications that interact with APIs or local data. By mastering techniques like serialization/deserialization with dart:convert, code generation using json_serializable and build_runner, and understanding different strategies for handling complex JSON structures, you can efficiently manage data and build robust, maintainable Flutter applications. Remember to choose the method that best suits the complexity of your JSON data and the performance requirements of your application. Consider error handling and data validation to ensure the reliability and integrity of your data. With practice, you’ll become comfortable handling various JSON scenarios in your Flutter development.