Kinda Code
Home/Flutter/How to read data from local JSON files in Flutter

How to read data from local JSON files in Flutter

Last updated: September 15, 2023

This short, straight-to-the-point article shows you how to read local JSON files in Flutter.

Overview

We’ll make a tiny Flutter app that loads and displays some data from a JSON file called sample.json.

Screenshot:

Here’s sample.json:

{
  "items": [
    {
      "id": "p1",
      "name": "Item 1",
      "description": "Description 1"
    },
    {
      "id": "p2",
      "name": "Item 2",
      "description": "Description 2"
    },
    {
      "id": "p3",
      "name": "Item 3",
      "description": "Description 3"
    }
  ]
}

The code which is used to fetch data from the JSON file (see the full code below):

Future<void> readJson() async {
    final String response = 
          await rootBundle.loadString('assets/sample.json');
    final data = await json.decode(response);
    // ... 
}

To use json.decode(), we need to import dart:convert.

Getting Started

1. Create a new Flutter project:

flutter create local_json_example

2. Create a folder called assets (the name doesn’t matter) in the root directory of your project, then copy the sample.json file into it:

3. Declare the json file in the assets section in your pubspec.yaml file:

flutter:
  assets:
    - assets/sample.json

Note that the indentation is mandatory.

4. Remove all the default code in main.dart and add this:

import 'package:flutter/material.dart';
import 'dart:convert';

import 'package:flutter/services.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Hide the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      theme: ThemeData(
        useMaterial3: true,
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List _items = [];

  // Fetch content from the json file
  Future<void> readJson() async {
    final String response = await rootBundle.loadString('assets/sample.json');
    final data = await json.decode(response);
    setState(() {
      _items = data["items"];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: const Text(
          'Kindacode.com',
        ),
      ),
      body: Padding(
        padding: const EdgeInsets.all(25),
        child: Column(
          children: [
            ElevatedButton(
              onPressed: readJson,
              child: const Text('Load Data'),
            ),

            // Display the data loaded from sample.json
            _items.isNotEmpty
                ? Expanded(
                    child: ListView.builder(
                      itemCount: _items.length,
                      itemBuilder: (context, index) {
                        return Card(
                          key: ValueKey(_items[index]["id"]),
                          margin: const EdgeInsets.all(10),
                          color: Colors.amber.shade100,
                          child: ListTile(
                            leading: Text(_items[index]["id"]),
                            title: Text(_items[index]["name"]),
                            subtitle: Text(_items[index]["description"]),
                          ),
                        );
                      },
                    ),
                  )
                : Container()
          ],
        ),
      ),
    );
  }
}

5. Launch a simulator and run the following command:

flutter run

Output:

Loading Data on App Starts

In case you want to fetch and display data from your JSON file automatically when the app starts instead of on button click, you can call the readJson() function in the initState() method like this:

import 'package:flutter/material.dart';
import 'dart:convert';

import 'package:flutter/services.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Hide the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      theme: ThemeData(
        useMaterial3: true,
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List _items = [];

  // Fetch content from the json file
  Future<void> readJson() async {
    final String response = await rootBundle.loadString('assets/sample.json');
    final data = await json.decode(response);
    setState(() {
      _items = data["items"];
    });
  }

  @override
  void initState() {
    super.initState();
    // Call the readJson method when the app starts
    readJson();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: const Text(
          'Kindacode.com',
        ),
      ),
      body: Padding(
        padding: const EdgeInsets.all(25),
        child: Column(
          children: [
            // Display the data loaded from sample.json
            _items.isNotEmpty
                ? Expanded(
                    child: ListView.builder(
                      itemCount: _items.length,
                      itemBuilder: (context, index) {
                        return Card(
                          key: ValueKey(_items[index]["id"]),
                          margin: const EdgeInsets.all(10),
                          color: Colors.amber.shade100,
                          child: ListTile(
                            leading: Text(_items[index]["id"]),
                            title: Text(_items[index]["name"]),
                            subtitle: Text(_items[index]["description"]),
                          ),
                        );
                      },
                    ),
                  )
                : Container()
          ],
        ),
      ),
    );
  }
}

Another solution is to use FutureBuilder. See the detailed guide about this widget here.

Conclusion

We’ve built a simple app that loads data from a local JSON file. Continue exploring more about JSON stuff and other fascinating things in Flutter by reading also:

You can also check out our Flutter topic page or Dart topic page for the latest tutorials and examples.