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.
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.
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
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”,
“title”: “Rear Tires”,
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.
READ THE JSON AND GENERATE THE FORM WITH IT
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).
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.