Functioning of "return data" in custom event

Hi everyone,
I encountered a (to me) strange behaviour with the :return data action.

I’m building a ‘submit form’ workflow for an input form that should also contain input validation inside the workflow. The main workflow (simplified with only the relevant actions) is this one:

In Step 1 I trigger a custom validation workflow that checks, if input fields for first and last name are empty (Steps 2 & 3) and if a DT Client object with the same Name already exists in ‘DT User Defaults’ All Clients’ (list of DT Clients) of the current user (Step 4). If one of these conditions is true, I return ‘validation successful = no’. → This would trigger the ‘Terminate Workflow’ action in the main workflow (see screenshot above).
If none of the conditions is true, Step 5 returns ‘validation successful = yes’ and ‘Terminate Workflow’ should not be triggered.

For the case that the main workflow is not terminated, a new DT Client record will be created (Step 3 main workflow) and will be attached to the DT User Defaults’ All Clients (list of DT Clients).
At the end of the workflow the Popup that contains the form should be closed.

Now the behaviour that seems odd to me:
When I submit the form to create a DT Client that doesn’t exist in the database yet, the DT Client record is being created and attached to the DT User Defaults correctly. However the last step ‘Close the popup’ doesn’t trigger and the popup stays open.
When going step-by-step in the debugger Step 4 of the validation workflow returns ‘successful validation = no’ because it finds the DT Client record that should only be created in Step 3 of the main workflow (so after the validation).

Can anyone explain this behaviour to me?
My suspicion is that the ‘return data’ action stays ‘active’ during the whole workflow and monitors if its condition becomes true at any point, then returns ‘successful validation = no’ and thereby triggers the ‘terminate workflow’ before the ‘close popup’ action is triggered.

If the rest of the workflow works correctly, then I can think of 2 possibilities:

  • Could be a bad copy paste
    Have you tried to delete the hide popup action and add a new one?

  • Something else is triggering the popup to be visible
    Do you have any other events that show the popup?

I do have a question though. In your custom event you have 3 Return data actions with conditionals and then 1 last one without any conditionals. I’m asking because that should log as an error because only 1 Return data action should ever trigger in a custom event that returns data.

It could be that the custom event’s Return Data isn’t being returned unconditionally/early, so the main workflow continues and creates the record before validation finishes; make the custom event finish with an unconditional return (or mark the return optional but explicitly return a value in every branch) or run the validation synchronously before creating the thing

Thanks @ihsanzainal84 .

Could be a bad copy paste

I rebuilt the workflow completely from scratch already, because a “bad copy paste” was one of my suspicions as well.

Something else is triggering the popup to be visible
Do you have any other events that show the popup?

This is not the case either.

Thanks @rafaelchavantes !
The custom event already finishes with an unconditional return (Step 5). Making the return value optional or not doesn’t make a difference either.
What do you mean with “run the validation synchronously before creating the thing”? Setting a “is clickable” condition on the Button itself?

I’ve had similar issues before.

Try conditioning the creation of a new user on the YES return value of your custom event.
And condition the closing of the popup on the user creation with something like result of step 3 is not empty.

I’ve noticed many times, and I don’t know why, that whenever there’s a CREATE action involved, the workflow order gets messed up. Bubble creates the thing first and only then runs the workflow, completely out of order…

So it ends up causing this kind of issue. Building the entire flow with conditions was what worked for me.

Thanks @rpetribu . In the actual workflow (I just posted a simplified version here) there are actually several more “create/make changes” actions. Adding the “validation successful = yes” condition to all of them (in addition to existing conditions) seemed messy to me, so I tried the following:
Step 1: Custom Event Input Validation (as before)
Step 2: Terminate this workflow (only when “validation successful = no”) → actually redundant because of Step 3
Step 3: Custom Event containing all the remaining steps of the previous main workflow with condition (Only when “validation successful = yes”).

Since the Bubble documentation states that ‘Custom events run in sequence, not parallel. …’ I thought this should definitely work. Well…no. Same behaviour as before.

This is actually the default behavior in any workflow. Server side actions like Create Action will run as soon as they have all the values they need.

A custom event is considered a clientside event so it respects the workflow.

This is the best way to get server-side actions to respect a workflow.

I’ve also run into a similar problem and I’m pretty sure at this point that an unconditional Return data action inside a Custom event might trigger before all previous steps inside the same CE finish. It’s not really intuitive IMHO, I was expecting it to really be the last step but seems to not always be the case.

Bubble Docs state that: Custom events run in sequence, not parallel. If Workflow 1 triggers a custom event that starts Workflow 2, Workflow 2 will complete before the remaining actions in Workflow 1 run

It actually does not say that everything within the Custom event will run in sequence. It just says that if you start a Custom event and this will trigger workflow 2, workflow 1 won’t continue as long as this “nested workflow” is done.

I solved it by making the return value optional and then returning after each step (as I then want to anyway terminate the workflow) or a Return data action at the end that returns only when all the other steps before where empty (meaning they did not execute).

So optional return value and conditionals. Not setting the return value to optional will throw an error.

Just in case someone has a similar problem and finds this helpful…

What if we had a normal workflow builder with proper branching/parallelization/loops that didn’t require 1990’s workarounds?

To validate an input is not empty, all you need to do is set that input to ‘should not be empty’ and use that inputs value in a workflow action as a data source for create or make changes. If that input is empty, the workflow doesn’t run and input is marked as invalid and focus is set to that input.

Be careful as the order of input values in workflow is what sets focus to first empty input in the flow, it’s not set to first empty input on page layout.

To validate you do not already have a user with same name, consider a better validator like the email address which is unique and bubble already has built in validation like email address already exists. Trying to validate names, you’ll deal with capitalization, spaces, misspelled names and more, resulting in issue when the email address is same and you do not have a system to alert user to the same email address in use issue they may face after passing your same name validation.