This tutorial will show you how to work with a list and TinyDB.
You will learn:
How to create a list and save items to it
How to save the list to a TinyDB
How to set the list when opening the app
How to set a listpicker elements to a list
How to delete an item from the list
How to avoid duplicates in a list
This tutorial also shows:
How to use a procedure in your workflow
How to build a "list display" in a label
How to use the notifier for information and confirmation
The generation and manipulation of lists, and their retrieval is often a main part of most developers work in AI2, and where many new developers get "stuck". It is therefore useful to understand how to create and save lists, and ensure that the users data is available for future use. Developers tend to get a bit carried away with the opportunity to store data in a database, and often develop complex tag:value setups. This is very often not necessary. Work with lists in the app, then save those lists to the tinydb as they change, and return the lists from tinydb at startup. This way you only have to work with the lists, and not worry so much about the tinydb. This also keeps things simple.
It is worth remembering that when an app is first installed, the tinydb will be empty. you cannot store data in a tinydb during development for it to be available in the final app/apk. Different methods are required for this.
Here is a short video of the example app in action.
The app is built with a textbox, one button, a listpicker, a notifier and a label. The textbox and the buttons are organised in a horizontal arrangement, and another label is used for spacing at the top. Device Default theme is used and display components are sized and centred.
A tinyDB component (in the storage drawer) is dragged out to the designer
As you will have seen from the video, the app creates a list of animals. Therefore a variable is required for the animals list, this is set with a create empty list block.
The first important job is to load this list with whatever is in the tinydb on start up. Using the Screen1.Initialise block we call the tag:animals value from the tinydb and load it to the animals list. if the value is empty, we load an empty list. This last part is important, when loading a list from tinydb, your "valueIfTagNotThere" should always be "create empty list".
Now our procedure is needed to set up the app for use. A "procedure that does not return a value" block is used for this.
What is going on here?
- We set the listpicker elements (the listpicker will be used for deleting items from the list) to the animals list variable.
- Then we set up the label to display the contents of the animals list. First we give the label a title, and include a "
\n" to separate it from the list items. We then test to see if the list is empty or not, if it is empty then we do not display the title. If the list has items then we iterate over the list adding each item to the label value with a "
\n" to create a new line.
- Finally we ensure the textbox is empty, and set its focus ready to receive text input.
We can then add the run procedure block to the Screen1.Initialise event
Let us add an animal to our list! Here are the blocks used:
There is a lot going on here just to add an item to a list! Why ? We have to think about users and how they will behave, clicking on anything, regardless of what might be required by the program. We therefore have to introduce some error controls.
- The first check is for an empty textbox. The user will be notified if they press the Save button and the textbox is empty.
- The second check is if the entry made by the user is already in the list. If it is in the list, then the user gets notified. (for this example we do not want duplicates....)
- If it is not in the list, then the value in the textbox is added to the animals list using the add items to list block. The LIST is then stored in the tinydb. This keeps the stored data up to date. Then the procedure is run again, to update the label display, the listpicker and reset the textbox ready for another entry.
We can now quite happily keep adding animals to our list, knowing that they are saved to the tinydb, so if we leave the app, then return later, the animals we have entered will be there. But what if we want to delete one of the animals? Here are the blocks for that:
When the user presses the Delete button (actually a listpicker) the listpicker is opened with all the items from the animals list displayed. When the user selects an animal, the listpicker closes, and they are present with a "notifier choose dialog".
Do you really want to delete? Always good practice to put an extra check in there. If the user presses "No" then nothing happens. If the press "Yes" then the delete process is run, removing the item from the list, and storing the LIST to the tinyDB, and running the procedure again to update everything.
You may note that the "index in list thing" block has been used instead of the listpicker1.Selection index.
This is done in case, as a developer, the filter bar is used in the listpicker. When the filter bar is used, the listpicker creates a new index, so by using the Listpicker1.Selection (with our unique items list) we will always pick the correct item from the full list.
There we have it. Now we can add and delete items from a list, adding only unique items, and the list is always saved/stored to the tinydb for future use.
Here are all the blocks together:
and here is an aia project of the example for reference:
saveListToTDB.aia (4.6 KB)
A couple of things to try, to develop on from here:
- Handle an empty list with the Delete button, so that an empty listpicker is not shown
- Use Listpicker1.SelectionIndex in the Delete routine and see how this works