In the previous part of this post, you have added database and navigation to your project. It is time to finish this application and sum up all you have learnt.
Currently, we are persisting our notes, but you cannot see the results of this operation. That’s why we need to display a list of notes on our main screen.
There is one problem with displaying our notes: they are stored in database, and we should access the database on a new thread. Fortunately, there is a FutureBuilder widget in flutter, which is doing exactly what we need: loading data in background and creating proper widget after obtaining the data. Whenever you need to load some data in the background (for example from webservices) and display it, using this widget will be the most likely solution.
Modify your main.dart file:
Create a new method (we’ll add the body next):
Ok, now it is time to add FutureBuilder, as mentioned earlier. ALT + ENTER click on your scaffold, to wrap it into new widget, and then modify it this way:
Let’s come back to buildNotesList method. It takes AsyncSnapshot object as a parameter. From this object, we can get information about current loading state (for example ‘waiting’ means that we are still waiting till the end of loading data). We would like to show a progress indicator during loading data, and after getting result, display list of notes or an error message (if the loading has failed).
Last thing we need to add is the _createItem method:
Build and run your application. You should see a list of notes. Pressing FAB should trigger the creation of a new note, which will be visible on list.
Ok, now we can see a list of notes, but we are not able to see all note details or to edit the data. Let’s fix it. Modify the note_details_widget.dart file as such:
Now, let’s update the _submit() method so it’s updating a note instead of creating a new one:
Now we only need to add navigating to noteDetails after click on list tile. Update the _createItem method (main.dart):
Build and run the application again. Now, you can edit note details!
To finish our application, we need to add an option to delete existing notes. Flutter has a built in mechanism for it, so we can implement it very easily. Update the _createItem method:
Build your application again. Now, everything should be working fine. Congratulations, you have just created your first application in Flutter! Continue reading if you want to know how to write some tests for it.
In Flutter, there are 3 very important libraries for testing:
Now, we are going to create some tests for application we have just created. We will be using the WidgetTester library.
Let’s start with adding required dependencies. Open pubspec.yaml file and modify it:
Ok, now open file widget_test.dart file which you can find in test/ directory. Remove all the code from the main method. Then, create some mocks for our tests:
We would like to test our NoteDetailsWidget. The first test will make sure the data is being saved in the database. As you can remember, the top level widget build by NoteDetailsWidget was the Scaffold, that’s why we must wrap it into MediaQuery and MaterialApp - without this wrapping, our test are going to fail. Let’s start with wrapping method:
Ok, now create our test:
To finish our test, we need to insert values to our FormTextFields. As you can remember, we can access them using keys. Open note_details_widget.dart again and add keys:
Ok, come back to our test, and add values for our FormTextFields:
Run this test. It should pass.
Create another test for updating notes:
Run both tests, they should both pass. That’s it! If you like, try creating some more tests yourself.
Now you know how to create an application with Flutter. Keep in mind that for larger applications, you should probably use a battle-tested architecture pattern. Due to the inherent architecture of Flutter framework, I think MV* (MVP, MVC...) patterns are not the best suited for large Flutter apps. It does not mean that you cannot use them, but I suggest that there are more suitable solutions.
My recommendation is to use the REDUX architecture (if you are not familiar with it, please read: https://redux.js.org/introduction). There is a perfect plugin created by Brian Egan to support this architecture. Some examples are available here: https://github.com/brianegan/flutter_architecture_samples
If you would like to use MV*, my recommendation is to use MVI. Here you have got samples:
I have not found any good, working examples of MVVM on Flutter (If you know of any, please send it to me).
Using Flutter you can create mobile applications fast and easily. Let’s sum up the pros and cons of Flutter.
However, Flutter has also some cons:
We could spend a lot of time arguing which hybrid framework is the best. I can only recommend Flutter, because it is fast, easy to learn, and it is getting more and more popular. Have a great time writing your applications using Flutter!
All code mentioned above is available at my github: https://github.com/MikolajLenart/notepad
Thank you very much for reading this blogpost.