An efficient expression to check if a list field of a record has been updated in the backend

After some brain matter reducing thinking with ChatGPT, I’ve finally found the most efficient expression to check if a list field of a record has been updated in a backend workflow.

Basically, we compare the count of old and new lists when merged versus the count of the same lists when intersected.

A simple expression to use in the backend. I use it to compare when a list field of a Record has changed in a DB trigger. This is the most accurate and simplest method so far. No need for Bubble to do additional processing of list or filters.

Works in any conditional if you need to compare 2 lists that don’t match. Originally, I built a plugin to compare lists on the frontend - Definitely overkill for something simple.

You can test out the expression here: coffeehat-sandbox | Bubble Editor

Don’t ask how it works. My brain needs to recover. I’ve tested in my sandbox, will test it in prod soon. Do give me feedback if you’ve found edge cases.

4 Likes

Another way is List A:format as text is not List B:format as text where inside format as text you have the unique ID (if thing) or the content (if option set/something else).

If in backend trigger, you can use List A:each item's unique id join with , is not List B:each item's unique id join with , which is basically the same

5 Likes

Urgh, I totally forgot about converting the lists to text. I knew I was overthinking things. Really need to get sleep.

1 Like

In a train to an errand so I got some brain back. My lists are pretty small so either works. You got me thinking about comparing large lists, more than 50 records.

A hash of all the UIDs stored as a field will be much more efficient in the long run.

1 Like

Vibe Coding Syndrome?

Are you checking if a change was made or just if a record was added or removed?

Other than a fix for a plugin yesterday, been a while since I last coded something new.

I’m just stretched thin with a job, a diploma course, my hustle and the kids.

1 Like

Changes to the list. Adds and removals.

1 Like

All good I just think it’s a funny name.

1 Like

Talking about “Vibe Coding” gives me brain pain. I wish it was never coined in the first place.

2 Likes

Hey @ihsanzainal84, it’s great that you reasoned it out. You’re spot on. The only suggestion I would make is to use is not instead of >. That way, either merged or intersection can come first in the expression and one needn’t concern themselves with the direction of the angle bracket. The fact that there’s a count difference is all that matters. It simply indicates the lists are different.

  • Lists merged:count is not List intersection:count

What’s more, there’s simple logic to determine exactly which items were added and/or removed:

Get the list of items removed

  • List before:minus list (List intersection)

Get the list of items added

  • List now:minus list (List Intersection)

I do exactly this in one of my apps. Users can have multiple roles, and I use a DB trigger to execute some logic whenever there’s a change to a user’s roles. I also send an admin notification with the user’s current roles as well as exactly which roles were added/removed.

For anyone interested in learning more, this all has to do with the mathematics of “finite sets”. In Bubble, “merged” is what’s known as a set “union”. An LLM can take it from there.
 
 

Just be mindful of sort order, as this approach is nondeterministic with respect to list content alone. That is, it will produce a different output even if the items comprising the list don’t change but their order does.

For example, if the app has logic which overwrites the original list with a reordered copy, such as…

  • ListItems set list = This Thing's ListItems:sorted by Field

or

  • ListItems set list = RG's List of ListItems (where RG is sorted)

…then that would result in a modification where the content of the list doesn’t change but the order does.

Of course, it’s easy to account for that by simply sorting each list before formatting as text…

  • List A:sorted by uid each item's uid join with , is not List B:sorted by uid each item's uid join with ,

This delimited string comparison approach has the advantage of being able to detect a change in order only.

  • Either content or order has changed (unsorted list before !== unsorted list after)
  • Only content has changed (sorted list before !== sorted list after)
  • Only the order has changed (sorted list before === sorted list after AND unsorted list before !== unsorted list after)

 
If you’re not concerned with the order of items, working directly with lists allows you to determine not just that the lists are different but how they are different.

2 Likes

What a vibe coder would say :eyes:

I vibe code with Bubble.

Use AI to create some code…or write some…pop it into Bubble and see how it looks.

Haven’t used any credits yet in testing :upside_down_face:

Can’t see how you can beat it

1 Like

I did think about it but because I’m not really sure how Bubble processes is not. Integers are faster comparators versus strings. So I couldn’t come to a conclusion to what would require less processing on the backend.

In the end I decided to go with a MD5 Hash as a single field. Waay simpler expression and most of the processing (looking at this specific feature of “looking for updates to the list”) done clientside.

Since the comparison is between two integers, I’d be really surprised if Bubble did a type conversion to a string. I suspect it’s using a strict inequality operator under the hood - e.g. int1 !== int2.

Anyway, glad you got it working to your satisfaction.

:slightly_smiling_face:

1 Like