Create a Simple Timetable App with JSON & Flutter
Tags: flutter, tips, tutorial
Published: 2021-06-09 17:40:30

This article We will build a simple Flutter App to read a list of appointments from a local JSON file and show them in a list, this is useful to understand some concepts that can be used in Flutter Apps like:

- read a file from the local storage
- parse JSON file
- model a JSON file to a list of Dart Classes
- create a list with a FutureBuilder

The final result will look like this

![home_page.png](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bgc9zdd672454s3vztkq.png) 

### Let's code

You can find all the code in this GitHub repo [simple-flutter-timetable](https://github.com/polilluminato/simple-flutter-timetable) and these are the main parts:

- **assets/json/timetable.json**: file json with the timetable that represent our "store", image that as our DB or API result;
- **lib/model/appointment.dart**: this is the model that allows us to convert the JSON object into a Dart class;
- **lib/pages/home_page.dart**: main screen of the app with all the calls to read and parse the JSON;
- **lib/ui/appointment.list.dart**: listview to read the List of Classes from JSON and display it on screen;

In this post I will only explain the most important parts because if you follow the code in the repo it's pretty easy to understand what it does. 

First of all you have to tell Flutter that It can use the *timetable.json* file and to do that you have to put those lines in the pubspec.yaml file

```yaml
  assets:
    - assets/json/timetable.json
``` 
After that we have to provide a Dart class that represents the information, in our case I create the appointment with this data

```json
{
    "day": "2021-05-24",
    "time": "09:00 -> 11:00",
    "type": "relax",
    "title": "Yoga class"
}
```

and the Dart class is this one

```dart
class Appointment {
  final String day;
  final String time;
  final String type;
  final String title;

  Appointment({required this.day, 
      required this.time, 
      required this.type, 
      required this.title});

  //This is the function that lets you to convert the 
  //  JSON representation of the Appointment in its Dart class
  factory Appointment.fromJson(Map<String, dynamic> json) {
    return new Appointment(
      day: json['day'] as String,
      time: json['time'] as String,
      type: json['type'] as String,
      title: json['title'] as String
    );
  }
}
```

We can read the file and parse the content with these two functions in the *home_page.dart*

```dart
Future<String> getJsonStringFromFile() async {
    return await DefaultAssetBundle.of(context)
              .loadString('assets/json/timetable.json');
}

List<Appointment> parseJson(String response) {
  final parsed =
      json.decode(response.toString()).cast<Map<String, dynamic>>();
  return parsed.map<Appointment>((json) => new Appointment.fromJson(json)).toList();
}
``` 

Note in this case that the function **getJsonStringFromFile** has been declared **async** since accessing the memory is an operation that can take some time and therefore the reading of the file is something that will happen in the "near future". To take advantage of the async code and not to "freeze" the UI, a FutureBuilder has also been added, a very useful widget when you need to show a portion of the UI in which data comes from an async, in this way it is possible to provide a placeholder widget while the data arrives, once the data has arrived it is then possible to design the definitive UI

```dart
new FutureBuilder(
  future: getJsonStringFromFile(),
  builder: (context, snapshot) {
    if (!snapshot.hasData) {
      //Placeholder widget because the data hasn't arrived yet
      return new Center(
        child: new CircularProgressIndicator(),
      );
    } else {
      List<Appointment> appointments = parseJson(snapshot.data.toString());
      return new AppointmentList(
        appointments: appointments,
      );
    }
  },
),
```

To customize the UI, the *type* field in the class was used to show a custom icon in a single row and allow the user to easily distinguish the different types of appointments.

### How to improve it

There are lots of improvements that we can do to make our app better, now I can list some of them to give you some inspirations:

- Read JSON file from a custom URL on the internet: in this way you are not limited to the JSON that you have in your local storage, so if you have to update the JSON file you don't have to update the app, but you only have to update the JSON file because the app will read the updated one;
- Add more information on the single appointment like the location, split start and end time, insert a description or some notes on the appointment;
- Create a detail page of the appointment to show all the information;
- Allow the user to filter the contents of the list: for example you can add filters by type of appointment or by date, in case of a very long list of appointments it can be very convenient;
- Customize more the look and feel of the single row, on sites like [Uplabs](https://www.uplabs.com/), [Behance](https://www.behance.net/) or [Pinterest](https://www.pinterest.com) you could find lots of UI Design to improve it.

You can find all the app code in this GitHub repo: [simple-flutter-timetable](https://github.com/polilluminato/simple-flutter-timetable), you can fork, use and modify it as you want, the app uses the latest Flutter 2.2 so it's already with Sound Null Safety, you can build it on Android, iOS and on the Web.

Bye, Alberto