Building a To-do app in Flutter with Parse šŸ˜

Usman Khan
Flutter Community
Published in
6 min readApr 15, 2020
Todo App weā€™ll be building

Parse was a popular backend service managed by Facebook until the tech giant stopped its services in 2017. However, one can still make use of their SDKs and libraries provided for range of platforms like Android, IOS to name a few, provided they setup their own server or use Back4App.

In this example, we will be using Back4App which makes use of Parse framework to provide backend services. There is one problem though that there is no official SDK for Flutter unlike other platforms but Back4app provides RESTful APIs for communicating with our backend.

Getting Started with Back4App

  1. Go ahead and create an account on Back4App.
  2. After youā€™ve created an account, you can then see an option to ā€œBuild a new appā€. Click on that and give a name to your app (say Todo App).
Parse console for your project.

3. You should then see a console like the one shown above.

4. On the left side you can see a section named Database Browser which lists all the classes currently present in your database. By default there are two classes present namely Role and User. Create a new class named Todo which will store the data for each Todo item.

5. You can then proceed to add a column named task to the class which will store the actual task.

Letā€™s code

Go ahead and create a new Flutter project.

Clear your main.dart and paste the code below so that we are on the same page.

import 'package:flutter/material.dart';
import 'package:todo_app/ui/todo_screen.dart';

void main() {
runApp(TodoApp());
}


class TodoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: TodoScreen(),
);
}
}

Create a package named ui inside the lib folder. Inside the ui package, create a dart file named todo_screen.dart and paste the below starter code into it.

Create a constants.dart file inside lib folder where weā€™ll be declaring some credentials like ApplicationId and RestApiKey which weā€™ll be using to communicate with our backend while working with our REST APIs.

const kParseApplicationId = "Your Parse Application Id goes here";
const kParseRestApiKey = "Your Parse Rest API key goes here";

Model

Go ahead and create a package named model inside lib folder.

Inside this package create a model class named todo.dart which weā€™ll be using to store our ā€œtodoā€. Paste the below code into it.

Todo model class

The above class was generated using quicktype.io where you paste the json schema and it generates you a model class for your preferred language.

Network Utilties

Weā€™ve setup our model and ui package. Now before we setup our network_utils package, we need to add a dependency named http which is used for making http requests in Flutter. I assume you know how to add dependency to your pubspec.yaml so Iā€™ll skip this part for brevity.

Now create a package named network_utils inside your lib folder. Insisde this folder, create a class named todo_utils.dart which will handle all the network calls.

In this app, weā€™ll be doing four basic database operations namely CRUD (Create, Read, Update, Delete). So the basic skeleton of our todo_utils.dart keeping the operations to be performed will be like following:

Letā€™s finish up all the functions one by one before we move onto the UI part and then eventually call these functions there.

  1. Adding Todo

For adding Todo lets update our addTodo() to the following

class TodoUtils {

static final String _baseUrl = "https://parseapi.back4app.com/classes/";


static Future<Response> addTodo(Todo todo) async{

String apiUrl = _baseUrl + "Todo";

Response response = await post(apiUrl,
headers: {
'X-Parse-Application-Id' : kParseApplicationId,
'X-Parse-REST-API-Key' : kParseRestApiKey,
'Content-Type' : 'application/json'
},
body: json.encode(todo.toJson()),
);

return response;
}
}

Let me explain this function in brief as the same format would be seen for the rest of the functions which weā€™ll cover

  • The variable _baseUrl holds the url part common to all the APIs where as apiUrl is the actual API url for adding a Todo item to database.
  • As we are adding a record to the database, we are making use of post() function from the http package and we are passing certain headers to this function which we had declared in our constants.dart which are used used for authentication.
  • The data passed from client to server should be json encoded so we are encoding our map returned by todo.toJson() using json.encode() from dart:convert library.

Note : The documentation for each request is also present under the API Reference section in your project console at Back4App.

Similarly, lets update the rest of the functions namely

  • getTodoList()
  • updateTodo()
  • deleteTodo()

Finishing up UI

Now weā€™ll proceed with the final part which is creating a UI and calling those functions which we just created.

Letā€™s add the code for getting the list of all the todo items from the db and displaying it on the screen. So go to your todo_screen.dart and update the code as below.

So a function named getTodoList() is added which is resonsible for getting the list of todos from the server and parsing the data back from json to our model class Todo.

And a FutureBuilder is used to build the UI as the items will be returned in future after the request is completed. Till then we should show a progress bar on the screen.

Go ahead and give it a run to see our list of todo items.

Todo Screen

OOPs! We canā€™t see any todo items on the screen

Well that is because we havenā€™t added any yet and to add weā€™ll need to build functionality of add Todo first.

Add Todo Functionality

Go ahead and add a FloatingActionButton to your Scaffold on the tap of which weā€™ll be showing an AlertDialog to enter the Todo.

Updated Scaffold

Inside the onPressed() we are going to call a function which will show user an AlertDialog to enter a new Todo item.

Before that, letā€™s create a global TextEditingController instance for accepting todos written by the user in AlertDialog

TextEditingController _taskController = TextEditingController();

So there are two new functions written inside todo_screen.dart namely showAddTodoDialog() and addTodo() for showing an AlertDialog to accept Todo and adding a Todo item to database respectively.

Call the showAddTodoDialog() inside the onPressed() of our FloatingActionButton.

floatingActionButton: FloatingActionButton(onPressed: () {
showAddTodoDialog();
},
child: Icon(Icons.add),
),
Adding Todo

Update Todo Functionality

Once a Todo has been added, usershould also be able to update it. For that weā€™ll again show an AlertDialog with a TextField showing the existing value of the Todo. And the user can then update the Todo to whatever they want and then tap on Update button.

Weā€™ll again be writing two functions named showUpdateDialog(Todo todo) and updateTodo() for showing AlertDialog for updating existing Todo and updating Todo in database respectively.

Call the showUpdateTodoDialog(Todo todo) inside the onPressed() of edit icon button.

return ListTile(
title: Text(todoList[position].task),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(icon: Icon(Icons.edit), onPressed: () {
showUpdateDialog(todoList[position]);
}),
IconButton(icon: Icon(Icons.check_circle, color: Colors.green,), onPressed: () {
//Call function to delete todo
})
],
),
);
Update Todo

We are almost done with our Todo app. We are just left with delete functionality. So letā€™s go do it.

Delete Todo Functionality

For deleting a todo, weā€™ll simply call a function to delete our Todo to keep this article short and to the point. (You can obviosly go ahead and show a confirmation dialog if you want)

Call the deleteTodo(String objectId) function inside the onPressed() of the delete button.

return ListTile(
title: Text(todoList[position].task),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(icon: Icon(Icons.edit), onPressed: () {
showUpdateDialog(todoList[position]);
}),
IconButton(icon: Icon(Icons.check_circle, color: Colors.green,), onPressed: () {
deleteTodo(todoList[position].objectId);
})
],
),
);
Deleting Todos

So that is it. Weā€™ve successfully built a Todo app using Parse. The source code is available on my Github:

I hope you enjoyed this article, if so feel free to clap as many times you wish.

Letā€™s become friends:

Https://www.twitter.com/FlutterComm

--

--

Usman Khan
Flutter Community

Flutter & Android Developer | Writer(Android/Flutter) | UI & UX enthusiast