No doubt really basic: if NOT then

Hi all,

This really feels like I should have been able to find it out myself, but so far no dice, here it goes:
In my app during the week users gain points in three categories, this determines if they get a fixed endscore of 12,15 or 21.
In Excel ( yes, that is my reference point), I used to build alot of If then formula’s on top of eachother, so the above would be: If category A rule is met then “12”, If not -> if category B is met then “15”, if not -> If category C rule is met then “21”.
Any ideas how to do this?
Thanks alot!

Hi @SenorPelota - are you looking for something like this? You’d need to define your criteria and track the points for each user during the week but hopefully this little proto gives you some ideas on how to solve.

Hi Nikolai,
Yes, that is indeeed a good possibility! I must admit I hoped to include the three options into one action instead of three actions, since this one button I use already has about 12 actions tied to it :slight_smile:. It becomes a bit…cluttered. I was trying to make a formula for that.

Hi @SenorPelota - agreed it would be nice to have some “classic” sw constructs but I guess that’s the trade-off with codeless development :wink:

I updated the prototype to use a Custom State to set the value. While there’s still three steps in assigning the Custom State Value, assigning the value in the database is now a single workflow action. This second approach should be better performance-wise since the “evaluation” is happening behind the scenes when the dropdown value changes and it’s a single step workflow once the button is pushed (as opposed to the first version which does three evaluations in the workflow).

Ahhh, the legendary Custom state, I need to read up on that :). In my case the user inputs the result of his last day, then pushes a button, and if it is the last of 7 days, a final verdict is given to him ( 12,15, or 21 in this example). So on the final click I am now putting a couple of rule checks which determins the final result. It is indeed not very quick performance wise, but we’ll get there.

So just to be sure, there is no way to put a ‘otherwise’ in an action other then formatted as ( which gives two static options)?
Thanks for helping me out!

Why not do them all as steps in your workflow? It doesn’t look like there’s a need for an else.

Step 1: (only when Category rule A) Set endscore to 12
Step 2: (only when Category rule B) Set endscore to 15
Step 3: (only when Category rule C) Set endscore to 21

There’s no need for the If, Else construct if you order them properly.

Indeed, this would be the right approach with one caveat: You might want to Terminate the Workflow after the successful completion of each event, as it’s more performant than executing all three “Only When’s”. This is only an issue in very long workflow chains like this or if you are iterating or regularly executing that workflow.

I have noticed (because I have some pages that perform iteration over potentially large lists of things using workflows – making use of the trigger events from JS to Bubble elements*) a rather large increase in performance in bailing out of the workflow if you know that future steps should not be completed, rather than letting them evaluate.

So your version becomes:

Step 1: (only when Category rule A) Set endscore to 12
Step 2: Terminate the workflow (only when Category rule A)
Step 3: (only when Category rule B) Set endscore to 15
Step 4: Terminate the workflow (only when Category rule B)
Step 5: (only when Category rule C) Set endscore to 21

Again, this would only be noticeable if it’s something you’re doing a lot (like you’re looping over it) or if the conditions in Steps 1, 3, and 5 are complex (like the results of a “do a search for:filtered:sorted:etc.”), but it’s worth noting.

(*I keep threatening to post a video of my general approach to iterating over workflows using JS to Bubble, but haven’t got around to it yet.)

@keith Hmmm. Although I agree you should terminate workflows and avoid unnecessary changes, I don’t think it applies here. Or at least you would have to re-think the order. I assumed that anything that meets Category C also meets Categories A and B. And anything that meets Cat B meets Cat A. If that’s the case you could use your code, but reverse the order. Start with Cat C. Another reason you wouldn’t terminate is if you have more to do in the workflow - in this case you probably want to write some change to the database.

Goodmorning,

Yes and yes ( to @keith and @kirk).
The basic issue is like Keith describes it, the workflow is becoming very long. In the example above I am talking of 3 rules, but in reality it can get up to 15. It ends with an action where another page is being loaded, so just terminating the workflow will not do.
Also, the checking of the rules only needs to be done at the end of the week, for the other days it would be handy if it skips those steps right to the part where the next page is being loaded.
@kirk, currently the sequence is such that Rule A delivers the best score ( 12) and when met that score is changed in the database-> the workflow proceeds to rule B and if that is met the score in the database is changed to 15…etc.

OK, so presumably you understand the answer to your original question now. (Which was essentially, “How do I do conditional logic in Bubble?” The answer is, “By executing a workflow step ‘Only when…’ a condition is true.”) [BTW, @kirk, you’re correct in your reply above and if what you’re saying is not yet clear to the OP, I think it will be shortly!]

So, @SenorPelota, in the case you describe here, if I understand you correctly, you want to do the following:

You have a button that, when clicked, does this:

[Compute (or get) weekly score] → [Map that score to one of 3 ‘endscores’ (which are like ‘grades’)] → [Save that value somewhere in the database]

Correct? Those are the tasks you need to complete, in order.

Each of these three things you want to do may be composed of several subtasks. These subtasks will composed of individual steps in the button’s “WHEN button is clicked…” workflow.

Don’t get too hung up how “long” the workflow gets visually. This is just kind of a byproduct of drag-and-drop authoring systems like Bubble. So, just looking at these three “tasks” in order:

  1. [Compute (or get) weekly score]: presumably this is some sort of running total you’re keeping. I can’t guess how it’s computed, but it could be pretty complex. It could also be very easy – maybe it’s just “Current User’s Weekly Score” retrieved from the database, right? At any rate, however we get it, we need that value locally so we can map it to a grade.

If it already lives in the database, we already have access to it. Sounds like that is the case. However, if that was not the case, the first steps in our workflow would do whatever magic we need to do to compute the value. And the end of this “task” (set of workflow steps 1 through whatever) would be to either save that value to the database (if we care about it in future) or TEMPORARILY SAVE IT LOCALLY (which we can do with Custom States which are really just Bubble’s version of local variables).

Moving on:

  1. [Map the score to a grade]: This is what was conceptually hanging you up. In Bubble, this part of the workflow will – of necessity – be composed of AT LEAST 2 steps. No, there is no single workflow step that is like a branch, if - else structure or case statement structure. That would be handy in some cases and might make some folks feel more comfortable. However, it’s not necessary for the most part.

As @kirk and @nikolai and I (just now) pointed out, there are several inefficient things you are doing:

  • first, you’re writing the grade value to the database 3 times the way currently do it. This WILL BE slow and it’s unnecessary.

  • second, you’re thinking about your grading algorithm a bit backward. At least the way you’ve described it, you can safely assume that all grades will be “12” unless the criteria for grades “15” or “21” are met. (So, you never actually have to map a weekly score to “12” – it’s the “default”, right?)

But how does one do these two things in Bubble?

Here’s how:

  1. We’re gonna need some local storage to hold our “grade” locally until we (as the second-to-last task) write it to the database. In Bubble we do this with Custom States. Custom States are just local variables that are associated with an element on the page.

In your case, you might as well just put this “grade” variable on the button itself. While you can do this in the workflow builder, here’s how you’d do it in design mode (which makes it more obvious what we’re doing… and also lets us set a default value, which will be very handy and performant):

When we click “Add a new custom state” we are presented with a dialog (just like adding a field to a thing in the database) that lets us give it a name and assign a data type to it. Yours would be like this:

That’s gonna result in the following:

See how we can give this Custom State a default? I did that, set to 12, our lowest grade.

  1. Now your workflow components for mapping the other two grades are going to look like this. This step is created by selecting Element Actions > Set state:

Obviously, your workflow may have some preceding steps, but you get the idea. Set the variable Grade (which is stored on this Button) to 21 if (when) the criteria for this grade is true (“yes” in Bubble terms).

The second evaluation step is the one for grade “15” – set Grade to that value if the criteria for that Grade is met. NOW, it is not clear to me if the criteria for Grades “21” and “15” are mutually exclusive. Only you might know this.

If they are NOT mutually exclusive, we need a dual condition here. I’ve assumed that a weekly score that qualifies for grade “21” would ALSO qualify for a grade of “15”. (I think this is why you ordered your workflow steps the way you did, right?)

So, we will set the grade to “15” only when “It is NOT already 21” AND your other conditions for getting a score of “15”. Like this:

Now you will note that you DO NOT even need to bother with figuring out if the weekly score was enough for a grade of 12… This Button’s Grade will already be 12 (by default that we set in the Custom State) if it has not been changed by these two preceding workflow steps.

Neat, right?

What we’ve constructed here is the Bubble version of IF… ELSE IF… for all intents and purposes. More literally, in JS-like psuedocode, it’s like we did this:

var grade = 12;
if (cond1 is true) {set grade to 21};
if (cond 1 did not pass AND cond 2) {set grade to 15};

Get what I’m saying?

Moving on:

  1. [Save the Grade somewhere in the database]: This part is easy, right? We’re just going to “Make changes to a thing…”. I have no idea what the weekly score is attached to in your database, but that step is going to look like:

Hope that helps!

-K-

2 Likes

It is like someone yelled ‘take it away!’. And off you went. That was great.

you’re writing the grade value to the database 3 times the way currently do it.

Correct, I currently do everything with database, because I did not learn about custom state yet. Your explanation makes it very easy to understand how it should work when there are multiple steps in a workflow which work to one finale conclusion.

second, you’re thinking about your grading algorithm a bit backward.

Yes. It is not necessary to calculate 12 ( which I did). Also, It is not that when 21 is met 15 also is met, 15 simply becomes irrelevant when you violated a rule giving you a 21 score. Your solution fits this.

Thanks for the elaborate explanation. The workflow was sort of working with the help of @nikolai, and now I can really tune the performance by cutting out clutter by implementing custom states.
@nikolai @keith @kirk. Thanks for the help!

2 Likes