Jul 3, 2024

What I learned from building an auto-save feature in Bubble

Auto-save failure

These past few months, I've been consistently surprised by how simple the solutions I've devised are compared to how long I've spent thinking about the problem.

Ever since we deployed the exercises section on the Course Hub (BlueDot’s learning management system), I received numerous bug reports about the saving feature. Users report that their responses disappeared upon refresh even though they had clicked ‘Save’ or that parts of their answers disappeared on saving.

I tried using Bubble’s auto-binding feature (a significantly faster workflow for updating an object’s value) and manual workflows (explicitly calling the action to update the object's value). Yet, each time I tested the fixes, another user would still raise a new bug report — one I struggled to replicate.

Diagnosing the issue

If someone triggers the saving workflow multiple times, an earlier instance of the workflow could override the value in the text editor. This means everything typed after the first save is initiated would be lost.

It could happen in two types of workflows:

  1. When creating a new exercise response record
  2. When updating an existing exercise response record

I hypothesised that if these two workflows somehow get triggered simultaneously, they would interfere with the value they were meant to save as the response.

Bubble's workflows run in parallel, so this didn't make sense to me, but I couldn't think of any other reason why this would happen.

I tried:

  • Enabling vs disabling auto-save
  • Adding buffer time between workflows
  • Preventing users from typing before the workflow was completed
  • Preventing users from spamming save
  • Creating an explicit check between the value of the text editor and the value of the exercise response record

Then, I tested each scenario in the development and live environments while simulating potential user behaviours, like:

  • Spamming the ‘save’ button
  • Hitting save after every few words
  • Trying to save >1,000 words at once
  • Refreshing the page multiple times

Yet, each time I made a confident post declaring that I had finally solved the issue, a few days later, I'd see another bug report telling me, “No, you have not”.

All out of ideas

No one else on the team had a good grasp of how Bubble worked, and I couldn't find any discussions on this issue (at the time) on Bubble's forums. I didn't know anyone who was an expert on Bubble, and frankly, I couldn't see a way out.

In my head, I filed this bug as unsolvable. I hoped that someone more technical or creative than I would come along (though I knew this wouldn't come any time soon).

Once in a while, I'd have a stroke of inspiration and try out a fix, but I'd find myself put back in my place. Eventually, I stopped declaring my efforts and just silently crossed my fingers in the hopes that no one would raise another report.

Why didn't you get a Bubble consultant?

I did (on Dewi's advice), but it wasn't very helpful, given that the consultant couldn't replicate the issue. I could have shopped around for other consultants, but I didn't have many clues for them to go on.

Mental block

This would have been prime time for some out-of-the-box thinking. But with a long list of feature requests and bug reports, I deprioritised the exercise saving issue and never returned to it.

My mind’s record player dug deep grooves, spinning the same refrain: “I can't solve this. I've already tried everything. I'm just not technical enough to fix it.”

It's funny being the main team member in charge of software/product and not feeling qualified to do the job. It flew right in the face of all I had built on the Course Hub. Yet I did really think that if I had more “professional” / “formal” software engineering experience, I could have solved it or at least spent significantly less time trying to diagnose the issue.

But Bubble is a no-code app. What would software engineering experience do for you?

Imposter syndrome is not rational. What can I say? I somehow think SWEs have some secret sauce when it comes to debugging, which I'm not privy to, even though all the memes say it's mainly consulting Stack Overflow.

More (unrelated) problems with the exercise responses

At the same time, there was a text formatting issue. Bubble’s default rich text editor would save the text in BBCode, which was incompatible with Airtable's Markdown formatting.

The rich text would also have more formatting options than Airtable supported. This means that even with the help of ChatGPT, I could not write a function within Airtable's local scripts to convert BBCode cleanly into Airtable's Markdown. Random bits of formatting would be left behind or interfere with other formatting.

Along the way, these two problems became entangled in my mind, even though they were distinct. Each time I tried to solve the auto-save failures, I simultaneously tried to make the text formatting readable in Airtable.

Both did not pan out, and it felt like I was shoving cubes into round holes. However, there weren't any other objects around, so I kept brute-forcing the problem. The whole thing felt like a hot mess, so I decided to leave the exercise section alone.

An unexpected rainbow

After solving a separate but equally painful issue related to data syncing, I decided to pick up my courage and solve the bugs in the exercise section once and for all!

I sifted through the discussion forum again, hoping to find a fellow in the trenches with me, and picked up a nugget of inspiration to fully separate the workflows for creating and updating the exercise response so I can let auto-binding do its thing uninhibited.

It seems simple but involves creating a fake object that looks like a text box but acts as a button to create an exercise response. The actual text editor will only become visible once an exercise response is linked.

No more conditionals dictating separate workflows. No more contradictory workflows running at once. I'm barely into day one after rolling out this feature, but this is the first time in months that I've felt optimistic (and, dare I say, motivated) about this issue.

The discussion was posted ~ one year ago, so I could have plausibly found it back then, but I don't think I was asking the right question. I was caught up in my own diagnosis of the issue, asking, “Why is my setup not working?” I didn't allow myself to zoom out to the question, “How do I create a reliable saving function?” and try to switch gears. By that point, I had lost steam and given up.

Recreating the rainbow

This is the second persistent software issue I've solved over the last month. Upon reflection, I'm amazed by how obvious the solution was and am slightly embarrassed by how long I let the issue fester before I got here.

A few things led me to this particular rainbow:

Recognising that this was not a simple problem (stop beating yourself up!)

Over dinner with other folks at the office, I shared how a seemingly simple feature like auto-saving could be such a pain. In explaining why I thought this was a simple problem, I realised that maybe it isn't actually simple.

Maybe I'm actually solving a complex issue that only sounds simple.

Test explicit hypotheses

This is my favourite way to debug. I write down a list of potential reasons why an issue has occurred and a quick way I could test whether it is true. Then, I slowly work through this list, starting from the simplest hypothesis to disprove.

With a written list, I could narrow down which parts were working correctly and which parts I wasn't sure about. It was also easier to get back to debugging when I get (inevitably) pulled away to other tasks throughout the day.

You are almost certainly not the only one with this problem

There are millions of people using Bubble. I was definitely not the first person to try getting auto-save to work.

I was looking in the wrong places for help. I didn't need a general Bubble consultant or a software engineer—I needed to find someone who had solved this problem.

Don't get distracted

I kept getting sidetracked by the text formatting issues while trying to solve the saving errors. The two became tangled together, and it was hard to stay focused.

Writing down the problem I was solving and listing anti-goals helped ground me.

I've spent the past few weeks fixing everything I thought was unfixable. It has felt like chipping away at a huge boulder, but instead of thinking of it as a gargantuan task, I've begun to view it as a calming (almost meditative) practice.

I methodically work through a list of hypotheses. If I try to rush at it, I'll only end up hurting myself. So I pick up my tools, find the cracks and chip and chip and chip until it falls away. Eventually there will be a way through, I've just got to keep going.

© 2024 Ang Li-Lian. All rights reserved.