How to read data from local JSON files in Flutter

Updated: September 15, 2023 By: A Goodman 14 comments

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.

Subscribe
Notify of
guest
14 Comments
Inline Feedbacks
View all comments
bora
bora
1 year ago

thanks a lot

Ali alamrad
Ali alamrad
1 year ago

many thanks

Umid
Umid
1 year ago

why you don’t add initState?

Abbhi
Abbhi
1 year ago

please provide how write data from textbox in to json file

Ариса
Ариса
1 year ago

Thank you, it helped a lot

gurkan
gurkan
2 years ago

Hello, A Goodman! It has been a crucial tutorial to learn how to decode a nested JSON file. And it possessed so strategic first appearance page that you can manage the page in two different conditions. Therefore it means that you can use a text message while waiting for a… Read more »

HezO
HezO
2 years ago

This was very helpful. Thanks

1111
1111
2 years ago

how it deal without button, i have trouble finding

Muzammil Hassan
Muzammil Hassan
2 years ago
Reply to  1111

If you dont want button just give that function in initState((){}; , data will be fetched as soon as page gets load

Lee Lee
Lee Lee
2 years ago

Another question! … how to update local JSON files?

Faezeh Yas
Faezeh Yas
2 years ago

that was very helpful for me among all the sources and ways to make these kinda UIs. Thanks a lot.

Related Articles