Need to wait for prior API call to finish before allowing the next

My application has four different API calls defined from three different API data sources.

The user fetches specific data using the various API calls, which they initiate by clicking buttons.

I need a mechanism to ensure that the next API call won’t start until the current API call completes.

I log every API call, partly so the user can view of a history of their API call usage, partly so I know what level of service I need to subscribe to for the various API services (as the app gets busier I’ll need higher subscription levels), and mostly I allocate the cost of the API usage based on the usage by the user.

I do this with a variable I call QueryCreditBalance, which is just an integer of their individual QueryCreditBalance.

When they use a service that costs 1 QueryCredit, I decrement the balance by 1. When they use a service that costs 160, I decrement the balance by 160.

I’m keeping track of that value in the record type I create every time a user obtains data from one of the outside services.

The screenshot below shows how a user gets data by clicking a button.

And this screenshot shows a sequence of the log records having been created.

As you can see, in the Log record there is a field named ApiCallFinished. When a workflow with an API call in it starts, the very first action in the workflow sets that value to “no”. Then the last action sets that value to “yes”.

In theory this should prevent a user from running a new one before the current one completes.

However, there is a problem.

When the user clicks buttons in quick succession, the workflows queue up, for lack of a better description, and the API calls do in fact run one after the other, but the counter of QueryCreditBalance gets messed up because each workflow starts with the same counter.

They start with the same counter, because they start with the same precise LogApiCall record.

So while the workflows do in fact execute in sequence, the QueryCreditBalance counter is not being properly decremented, as three different workflows, containing three different API calls to three different data sources, all start with the same value of QueryCreditBalance from which they then decrement their respective amounts.

I hope this makes sense.

My goal is to have the value of QueryCreditBalance properly decrement from one API call to the next.

Has anyone encountered this before, and can you suggest how I solve this?

When a user clicks a button, how about if you immediately set the other buttons to clickable=no?Then make them clickable again after the API finishes.

I tried that using a conditional expression on the element, and it had zero effect. I think making the element not clickable took too long. If there was an element action that would allow me to make an element not clickable, I would gladly use it, but I don’t think there is.

That doesn’t sound right. How did you set the conditional?

Sadly I’ve undone it now, so I can’t show you. A Bubble support engineer suggested that rather than use a DB field for my semaphore, I use a Custom State on an element, which I’m embarrassed to admit did not occur to me unprompted.

I’ve made that change, and the buttons are now not clickable when I want them to be not clickable.

There is however one lingering issue that is sometimes, but not always, the counter QueryCreditBalance decrements from a value that was not fetched from the most recent DB record. In my testing so far, this has failed 1 time out of every 4 attempts.

The Bubble support engineer (Jeff) has been alerted.