Can't check if a thing exists

Hi. I want to run a workflow once I click my submit button that says “If a thing exists, then change it, otherwise make a new thing”. Now, there are a couple of posts addressing this already but they make as much sense as a pack of condoms in a monastery. Apparently there is a checkbox that says “Create a thing if it doesn’t exist” (How do I use my edit a thing page as a create a thing page?) but I don’t have it? I click on “Make changes to a thing” but all I see is the option to select the current user or do a search, which also only gives me the things that already exists. But no option to create a new one if it already exists.

I’m new to Bubble so if there is a tutorial about this, please point me towards it. Is it something that I can’t do on a hobby account? Otherwise please explain it to me in noob-speak?

1 Like

The checkbox for “create if thing doesn’t exist” has been deprecated, so it’s probably not available in your app. I would have 2 actions on the workflow, each with a condition. One action would be to create the thing ONLY WHEN search for thing count = 0. The other would be to update the thing if search for thing count = 1

2 Likes

Great! This is very useful, I see what you are talking about.

Hello @andrewgassen

I noticed this solution makes my app really slow as the whole database needs to be checked every time. That is if I have to check every time with the condition create the thing ONLY WHEN search for thing count = 0, I think searching the database like this is slow. It makes my app take about 7 seconds to complete.
Is there any other way to make the condition faster?

2 Likes

I’ve seen people use :firstitem is empty and claim it to be faster. I personally haven’t had any issues with it, but maybe give it a shot?

Thanks. Please see below my search condition.
Where do I include the “is empty” condition?

What @andrewgassen is hinting at is a better way to evaluate whether a list contains any items or if it is a list of nothing. But he doesn’t tell you exactly how to do it because he doesn’t use the technique he’s hinting at. Here I describe this technique:

list-morpheus

(I was going to say, “a better way to evaluate whether a list is empty”, but this is incorrect terminology. A list itself is never empty and has no “is empty” state. There’s a mildly complicated computer science explanation for this, but for now just know that this is true. Thanks, Morpheus!)

So, when we “Do a Search for… something” this expression always returns a list of the requested data type. So your search:

Search for Replenishments

Always returns a valid list of Replenishments. This list may contain any number of Replenishments, including 0 (zero) Replenishments.

What we are interested in is detecting when that search returns zero Replenishments versus when the number of Replenishments is NOT zero.

You have figured out the first and most obvious way to do this. Knowing that the number of items in a list is represented by its :count operator, you know that you can differentiate between a zero-length list (a list whose :count is 0) and a list that is NOT zero-length (a list whose :count is greater than zero).

And so you wrote the expression:

Search for Replenishments:count < 1

And you know that this expression will evaluate to YES if the :count is 0. And you know that this expression will evaluate to NO if the :count is greater than 0.

Your expression is completely correct and completely valid… but… as you’ve observed, if your search potentially returns a LOT of items (or those items are themselves very large), this can get slow.

(At this point, you might also want to think about what constraints are in your Search. It could be you’re doing something completely unnecessary, or returning a longer list than necessary, etc. But let’s assume for a minute that you really need to do the search you are doing in the exact way that you are currently doing it.)

Let’s think about this expression for a minute. At a basic level, how does this work? What are we asking Bubble to do? We seem to be asking Bubble to do the following:

  1. Hey Bubble, please go search for all Replenishments that match these criteria. (Search for… Replenishments)
  2. Thanks for that. Now, tell me how many of them there are. (Get the :count of this list)
  3. Thanks again… Now tell me if that number is less than 1.

On the face of it, it seems like we actually have to go and fetch the entire list of Replenishments before we can assess how many items are in the list.

What if the search might turn up 10,000 Replenishments? That sucks, right?

Now, you and I can see that this is sort of silly. Ultimately, we are just going to return NO if the :count is anything over 0. We don’t need to wait until the :count becomes 10,000. As soon as the :count is even 1, shouldn’t Bubble just stop and say, “Hey dude, the answer is NO.” ???

Well, it could. But – as far as I can tell – when we ask Bubble to return the :count of a list, what Bubble does is just execute a function that returns the number of items in the list. (Lists always have this property of length.)

But you see, we are not telling Bubble, “Hey, go search for Replenishments and put them in this list. And – oh — every now and then, please check for how many Replenishments we’ve found. If that number ever gets greater than zero, just stop, mmm-kay?”

We have no way to do that. Not with :count. (Aside: If Bubble had VERY VERY VERY sophisticated optimization system, it might do this, but it doesn’t do that so just get over it.,.)

morpheus%20another%20way

There is another way.

Can we construct an expression that does essentially tell Bubble, “Hey, give up on this as soon as you find even 1 Replenishment!”?

It seems that we can. Think about this expression for a minute:

Do a Search for Replenishments:first item

First: turn off any sorting in your search. We don’t care to sort the items, right? We just care if there’s a single one. IF we have a sort inside our constraint, Bubble may in fact still need to search for all of the Replenishments that meet our constraints, sort them, and THEN pick the first item in that sorted list and return it to us.

But what if there is no sorting? In that case, the :first item becomes populated AS SOON AS ONE REPLENISHMENT IS FOUND. And, having accomplished its mission, Bubble can return that to us.

So then, Bubble returns that to us. A-ha! We have a Replenishment! (hold that thought for a minute)

Now, what if Bubble is NOT able to find any Replenishments that meet our criteria? It will still return to us a Replenishment, but that Replenishment will be empty.

SO, what we need to check for is this:

Do a Search for Replenishments:first item is not empty

This expression evaluates to YES if we find even 1 Replenishment, as SOON as we have found 1 Replenishment. (Theoretically… but testing seems to bear this out.) This expression evaluates to NO if Bubble comes up empty-handed.

Now you are saying, “WAIT! I need this expression to be NO if we find a Replenishment!!! And I need it to be YES if no Replenishments are found!!!”

morphus%20boolean

Hold on there, Morpheus!

First, what I’m going to suggest is that you start thinking about lists and whether they have any items or not, not as checking if the list items are empty, but checking if any of them are not empty. And so, you would structure things a bit differently in your app.

But, to Morph’s point: Even if you don’t want to do that, we can just flip the Yes to No or the No to Yes, and we do it this way:

Do a Search for Replenishments:first item is not empty is "no"

Adding is "no" here inverts the value of the yes/no. (Think about it: If we find a Replenishment, the first part is YES. Now we ask, “Is Yes No?” and the answer is “No”. And if we find zero Replenishments, the first part is NO. Now we ask, "Is No No?’ and the answer is “Yes”.)

The expression above is, theoretically, the fastest way to get your answer. Keep in mind: For maximum performance, review the criteria you are using in your search. And secondly, SELECT THE EMPTY ENTRY FOR “SORT” – do not sort as we do not need it.

So build that expression in your “Only when” field and see how it performs over your current :count-based condition.

Let us know what you find.

14 Likes

Waoh, this is the best explanation ever. :clap::clap::clap::clap::clap:

3 Likes

Great explaination. I will try it out shortly the completely understand it. :-).

Question. How do you combine this with object selection based on a property. For example:

‘Do a search for customers:first item is not empty is “no”’ … Where name = input A’s value’

so…. to my astonishment
i just had a condition fail
because the first item was empty
but the second item was not.
so now i’m using count is empty
which appears to be working…