Conditional for Data Source on Reusables

If you have a reusable element that you do not intend for the data sources to be always loaded, even when that reusable element is not visible on the page, you should add the data sources conditionally.

This means, for example of a repeating group, do not put the ‘do a search’ into the default data source. Instead create a condition, that is ‘when this reusable is visible’ and property to change is the data source. It is there you place your ‘do a search’.

This extends to API data. If you have an API call of type data, place the call conditionally as the data source.

This extends to references to other sources that may already not be visible :count operators. Your count operator will run an aggregate search (0.2 WU) even if the source referenced is not visible and the reusable is not visible. So for any text, that is displaying a count of items inside of a reusable, put a condition for ‘when reusable is visible’ and put the dynamic expression for the count as the text property there.

This extends to default values of reusable element properties. From personally example, for purposes of a pagination element, I have a property on the RE that is of type number, where I referenced the data source count. This default property value should be a conditional in the form of dynamic expression ‘when reusable is visible format as text (yes = dynamic expression for count; no = 0) converted to number’.

This is important for dashboards in which it is common to have multiple reusable elements that are the different views of the dashboard. You do not want your clients, or yourself, throwing away WUs. Also for SPAs that may not need to do a first load of all data for trying to improve perceived navigation between views.

Your goal should be that when a page with reusable elements is loaded without any of those reusable elements, to have no WU charges other than page is loaded, and maybe the ‘individual data request’ for current user.

Test for example a dashboard page, normally navigated via URL parameters to switch views, with empty navigation parameters, so a blank page is loaded…if there are data fetches or API data using up WUs those can be optimized away via simple conditions.

2 Likes

Crucial for SPA’s especially.

Keep in mind that Bubble only fetches the data when it’s needed, so if it is being fetched, it’s because some combination of stuff in the app references that property and needs the value to evaluate on page load

1 Like

I have a couple of questions about your idea.

If, a reusable group (in an SPA) is set to do a search for only when the group is visible…

if a user then browsed to a different group, wouldn’t that make the reusable not visible anymore? And if they came back to that reusable, it would do a search all over again?

On my SPA, when get data from page url is products (example), I load a custom state with a list of those products only if it is empty, then set the RG’s source as that custom state. The user can browse the site all day and the custom state stays. This does one loading and there’s no need to repeat it.

So basically, the custom state never loads unless that url is called.

It seems is visible etc. can have a lot of hidden gotchas that can be easily overlooked.

Anyway, do you see a flaw with my method?

Edit: Fixed wording from is not empty to is empty

‘Do a search for’ is really a misnomer for the Bubble expression it represents (one which leads to a lot of confusion).

It’s easy to think that ‘Do a Search for’ is an instruction to query the database - and that each time you use the expression, a database request is being made.

It’s not - and it doesn’t work that way, due to Bubble’s data caching.

The ‘Do a search for’ expression is more like an instruction to reference certain data - and Bubble will decide whether to make a new database request to load that data based, in part, on whether that data (or part of it) has already been loaded, and also based on the specific constraints used in the ‘Do a Search for’ expression.

If that data hasn’t yet been loaded to the page yet at all, then it will be loaded via a database request (or requests). But only the data from the expression that’s actually needed will be requested (not necessarily all of it).

If the data has already been loaded via the same set of search constraints (or, by constraints ‘broader’ than those used in the subsequent expression) then it won’t be loaded again.

If some of it has already been loaded, AND the constraints used in the original expression are ‘broader’ than those being used in the new one, then only the data that’s not already there will be loaded.

If the new constraints are broader the previous ones then ALL the required data will be loaded, even if the data itself has already been loaded to the page previously.

BTW - it’s simple to test this kind of thing for yourself… (just create an empty page with a couple of hidden RGs and some buttons to make them visible, and watch the data in the network tab of the browser dev tools as you play around with different datasources and visibility).

So I always encourage people to do that, if they’re genuinely interested in seeing how it works, as it avoids relying on other people’s information (which may or may not be correct).

So to answer your specific question:

if a user then browsed to a different group, wouldn’t that make the reusable not visible anymore? And if they came back to that reusable, it would do a search all over again?

No.. almost certainly not (unless the search constraints have changed to be different, or broader, than those previously used).

Anyway, do you see a flaw with my method?

Not particularly (although I’d say it’s not necessary).

but just be aware that loading data into a custom state loads ALL of it (unless you’re handling pagination yourself). And it’s also a static list (i.e. it doesn’t update in real-time when items are added or removed) - which is either a good thing or a bad thing, depending on use-case.

Whereas using an RG datasource only loads what’s needed (unless you explicitly set it to ‘show all items immediately), and is fully dynamic in regard to real-time data updates.

2 Likes

Yes…this is to ensure Bubble knows it is only needed when the reusable is visible, hence the use of conditions to give Bubble that instruction. Otherwise, if for example you have a repeating group inside of the reusable element that just simply has the data source set in default data source area, that data will get fetched even if the reusable is not visible on the page. Also, if there is a text element referencing the repeating group, even if that repeating group has a data source set conditionally for only when the reusable is visible, the text element will cause the aggregate search to have the count, so again, needing to give Bubble the instructions via the condition not to do that unless the reusable is visible, because the reusable is on the page, but just not visible due to the fact the navigation url parameter doesn’t have that ‘view’ open.

yes

if it is just a basic do a search without constraints, no, it would use the previously fetched data. If however, it has constraints, it depends on how those constraints may have changed.

So long as you are always using ‘go to page’ action and it is the same page as your SPA would be, then custom states are not lost…however, there is no material benefit to adding the usage of a custom state to hold onto the list of products. You can instead just put them into the repeating group via a search. And if the repeating group is not set to show all items immediately, you may see WU savings this way, since I’d imagine the approach implement with custom state was to fetch ALL products…if search is directly in the RG and not set to show all items immediately, you will not actually fetch all products.

@georgecollier had a tip about understanding where data comes from that gave some decent insights Understanding how searches and filters work in Bubble

What those insights help understand is with bubble lazy loading, if the user doesn’t scroll past first set of results batched in first fetch, you are not fetching all products. In my db, i get around 35 returned on a blank page, with one rg, with products that have 3 fields plus the built in fields.

Yes, that is good, but likely you are loading all search results into the custom state.

Not that I am aware of

Just what I presume to be a fetch of all products to set the custom state list of products

1 Like

Thank you so much for the responses.

I love hearing from people who are experienced in these things.

I do agree a custom state would need to be paginated if I ever got to that point. Right now where I’m at it’s not a concern.

I had originally thought also about a dashboard that can have a lot of data…even though it wasn’t visible, it could still be called? Maybe not, I’ll have to consider that more.

Anyway, thanks again.

I will give this some thought

Yes, unless you put conditions for data source only when reusable is visible

I just did this on a dashboard that has 12 views. When none were visible I had around 15 WUs coming from searches, aggregate searches and API calls, and reusable element properties with default values. Now it’s just page load and current user individual data request.