==========
What’s That?
==========
This post is a tutorial on how to save data using JSON format. The method allows to compress multiple database records into a single one, thus, speeding up workflows that involve manipulating lists of records.
========
But Why?
========
Few weeks ago, while developing an app for a client, I hit a wall. The dynamic form I was trying to make required the database to copy/delete a list of 48 records. With a paid, professional plan, this process took 2-3 minutes! I still can’t conceive how a such small task can take that long. There are web apps today that deal with thousands of records in less time.
Here’s a link that points out to an app I made to test off the speed of Bubble’s DB:
Speed test app
Speed test app Editor
After a few days of research I ended up with a workaround that solved the problem: shrinking the 48 records into a single one using JSON. Now my workflows are executing in less than a second.
I got the advice to make use of API workflows; they run in the background so the UX doesn’t suffer from it. But what happens when the user fills out a form and after hitting “Save” they can’t see or retrieve the results before 2-3 minutes? This leads to confusion and frustration.
==========
Dummy App
==========
Here’s a link to an app I made to show off a concrete example. I commented the elements and the workflows to explain what serves to what. Anyway the app is pretty simple.
If it was for real, the app would be meant for automobile mechanics to use when they inspect cars. The app offers a list of components to evaluate and save as an “Inspection”. For every inspection, there are basic informations (Inspector’s name, car brand…) and there are 20 questions (or components) to evaluate. For each of them, the user can specify the level of degradation, the urgency to fix it and leave a comment.
So what’s the best way to save an Inspection? Creating a “thing” in Bubble with a field for every piece of information? That would not be sustainable as there are 3 informations for every questions. So 3x20 means 60 fields. What if in the future we want to add 20 questions and add the possibility to specify a part number? This would mean 4x40 fields: 160. Bubble’s database is currently limited to 140 fields so we’d be doomed.
The other way, the good one, would be to create a record for each question. This way we could add as many components as we’d like + a possibility of over 100 more fields for each of them. Unfortunately, this is where Bubble’s performances come short. To create 20 records at a time would take easily 1-2 minutes. The user experience is destroyed.
The workaround (it really is just that) is to have our 20 questions saved in a JSON string that is saved in a single field of a single record. This is how this dummy app works.
Test the app
See the editor
===================
The Process in Summary
===================
-Write by hand the JSON template (I used a text editor that offers indentation + colouring)
-Design the app: putting the elements on the canvas and styling it, create the “things” in the data tab
-Build the parsing process: the part where Bubble reads the JSON and generate the list of questions from it
-Build the update process: the part where Bubble reads the inputs as the user change their content and put their data back in the JSON
-Build the saving process: the part where Bubble takes the up-to-date JSON and saves it in a record along with the other data
==========
The Process
==========
ESTABLISH THE STRUCTURE OF THE JSON
This includes planning what are the types of information I’ll want to save. Because the questions are dynamically generated in a repeating group, the JSON must be a list.
This is the first 2 questions of the app:
[
{
“title”: “Front Tires”,
“state”: 0,
“urgency”: “”,
“comment”:“”,
},
{
“title”: “Rear Tires”,
“state”: 0,
“urgency”: “”,
“comment”:“”,
}
]
The JSON is saved in Bubble as the default value of the JSON custom state. So whenever the user wants to fill a new inspection form, the template is taken as default.
It is important to note that once you’ve written your JSON template, you NEED to remove all the new lines. The javascript won’t accept a multiline JSON. One tool I discovered is JSON Validator from Curious Concept. It allows to format a JSON as desired + it serves as a validator.
READ THE JSON AND GENERATE THE FORM WITH IT
This part requires the ever useful “Toolbox” plugin (big thanks to @mishav ). The custom workflow “JSON Parser” has a “Run Javascript” action which expect a JSON string to parse. It creates an array for each information of the questions (title/state/urgency/comment). These lists are then passed to “Javascript to Bubble” functions (bubble_fn_whatever). The number of questions (in this case 20) is passed to the function bubble_fn_listLength.
On the Bubble side now. A “List of Numbers” element generates a list of numbers that starts from 1 to the value of the bubble_fn_listLength (Javascript to Bubble element). This list of numbers is used as the source of the repeating group so it has the right amount of cells.
Every element of the cell take its data from the appropriate bubble_fn_whatever function and by selecting the item # corresponding to its “Current cell’s index”
UPDATE THE JSON FROM THE INPUTS
The only built-in way that I found to extract data from a repeating group without interacting with the database is with “An input’s value has changed” workflow trigger. So in the dummy app, there are 3 workflows: one for the slider (state value), 1 for the dropdown (urgency) and one for the text input (comment).
So when an input’s value gets updated, it triggers a custom workflow (JSON Updater) that passes the value of the input, the field it belongs to (state/urgency/comment) and the “Current cell’s index”. The custom workflow has a “Run Javascript” action that replaces the original value in the JSON with the new information. This means that the custom state that originally holds the template is updated in real time as the user changes the inputs values.
SAVING THE JSON
The saving workflow is pretty straight forward as it takes the JSON from the custom state that originally held the template and puts it in the “JSON” field of the record that goes in the database.
EDITING A SAVED INSPECTION
The process is exactly the same then creating a new one except for one thing. Instead of using the default value (template) of the JSON custom state, it takes the content of the JSON field of the record that needs to be edited and puts it in the custom state.
Since the repeating group is populated from the parsing of the JSON, the inputs will reflect the values that were saved.