Forum Academy Marketplace Showcase Pricing Features

API Connector using stale data

TL;DR: API Connector is sending the wrong data to an API, using an old version of the parameter (or null on page load), probably due to a race condition - and it’s not clear how to fix that given the tools available…?

I’ve got a moderately complex app page where the user makes some suggestions, and as changes are made I then need to take their selections and convert them to JSON, which I then send to a third party API (from Prolific) to get back some feedback which I then update on the page.

The JSON is complex enough to build that I use a plugin custom element that takes a list of Things (which have been updated by the UI) and publishes out the JSON in a custom state. Logging shows me that the JSON generation is working fine given.

The API call is triggered by various things (on page load, on value change, on click) which all fire a Custom Event that then does a few setup steps (eg. kick off a waiting animation via a Custom State change that hides status / shows animation), then uses API Connector to call the API, takes the response and updates the UI.

When I redirect the API call to a server I control I can see that the API call seems to pretty consistently send the wrong data, using an old value - when I trigger this on page load then it sends null, if I trigger it when a UI element’s value changes it sends the version of JSON generated before the UI change happened, despite being initiated from a workflow several steps after the underlying DB Things have been updated. Adding 1-2 second pauses to the workflow before the API Connector step makes no difference, but using the debugger to pause on the preceding step will cause the right data to be sent.

Clearly Bubble is reading/writing Things asynchronously, with the workflow steps continuing before the Thing changes have returned and triggered the JSON update, and I’ve got a race condition. It’s not clear to me how I can solve that, given the tools Bubble makes available…?

Since the API call is in your own plugin (which I’m assuming is an element plugin since you say that it publishes the JSON to an exposed state), you can know when it’s finished.

Create an event in your plugin, “API Call Complete”.

In your code, after you do instance.plublishState(), do

instance.triggerEvent(‘api_call_complete’)

Now you’ll get that event once the plugin has finished publishing and can build a workflow off of that instead of trying to guess.

That worked, thanks!
Which incidentally then highlights the number of times the element is triggered by “changes” to the input which are not actually changes - it seems to get pinged 3 times for every 1 UI change…

Well you can defeat that of course if you don’t want it autoupdating. Make your actual ping API function an Action (which is what it should be anyway). Your update function should just initialize whatever your global settings are and probably throw an initialized event and set an initialized state (so you don’t throw any Actions at it before it’s initialized).

When you say “which is what it should be anyway” you mean it’s best practice to put in extra work to introduce an Action that otherwise wouldn’t need to be there, to join the change in a value to the input of an element? ie. it sounds like you’re saying it’s bad practice to trust Bubble’s binding to UI elements - is there a reason for that (other than the risk they fire more times than you might like)?

I’m just saying if you’re surprised by when your update function runs and that’s where all your shtuff happens that you should move your shtuff to an action in the element.