List Shifter: Reverse, Rotate, Swap and ITERATE (Loop) Over Bubble Lists | Now Part of Floppy

I can’t replicate that in general, @giosegar. Are you sure you don’t have another workflow being triggered on the same event?

(Note that, I do see in some cases - perhaps all - that, if List Shifter is being fed from a custom state, you may see it initialize/update twice in quick succession as the page is loading. Probably because the state doesn’t exist and then does exist and this triggers the update routine.)

Edit: but of course if there’s a constraint for its Original or Shifted List count being > 0 such a workflow won’t trigger.

@keith Is there a way to set the original list for list shifter from a workflow so it’s not constantly listening to the custom state value?

Nope, it’s not designed to work that way. There’s a feature of Floppy that is, though — Floppy’s RAM List.

You could also use List Shifter’s Custom List in this way. (Floppy’s RAM List is more versatile though.)

I figured out the issue. I was setting the custom state which the original list is based on when the page loads. Changing to a “Do when page loaded and list shifter is initialized” before setting the state worked for me.

There seemed to be a race condition problem happening where the state was set before the plugin had initialized, and it didn’t recognize that the list had values in it already.

1 Like

Hey @keith I just started with your great listshifter to render paginated shifted list. There is one issue I have not managed to overcome yet :
Sort the orginal list - That works fine on the first page.
However going to the next listshifter page displays removes gets me to the second page of the unsorted listshifter shifted list.

I am pretty sure the solution must be dead simple, but I cant figure it out. Any hint?

Hey @stevan.lecorre - this has been asked several times before, but the answer is a bit hard to find above in this massive thread. When List Shifter is in pagination mode, it only knows about the values on the current pagination page and any List Shifter actions apply only to those paged items.

So if you have a list that you want to sort (or filter or whatnot) and then paginate, use two List Shifters for this. Use the first one basically like a custom state (holds the full list which you can transform or sort using List Shifter’s actions) and then feed that List Shifter’s Shifted List as the source for the second List Shifter that you put in Pagination mode.

Hi Keith.

Thanks a lot for the swift reply. Definitely makes sense! Will try it tomorrow.

Cheers from Paris.

1 Like

Hey @keith , quick question as I’m a bit confused… perhaps this is a basic question. I have a backend workflow to schedule an API workflow on an API action call. To keep data from an API off client-side, it would need to be a backend workflow right?

How would I go about obtaining the data returned from the API workflow and passing it to a ListShifter element on the page?

Hey @austinm911: I think you might be a little confused by Bubble’s (odd/poor) nomenclature around backend workflows (which are also referred to as “API workflows”) versus calls made to some (typically) external API via the “API Connector”.

Backend workflows” as they are now known in the editor (found at the bottom of the page search menu) are workflows that run on the Bubble server. They are also referred to as “API workflows” because such workflows can also be exposed as API endpoints (so that other web applications - or even your own application itself - can communicate with your app via HTTP protocols such as GET, POST, etc). But of course backend workflows do not have to be exposed as public endpoints, they can also just be workflows that run on the server side that are available only to your own app.

It doesn’t help that, in the backend workflows view, such workflows are labeled as “API Workflow - name_of_endpoint”.

We trigger a backend workflow from the client side using the “Schedule an API workflow…” actions. “Schedule an API workflow” simply means “trigger the backend workflow in question at some particular time (which can in fact be now)”. The “Schedule an API workflow…” actions do not return data from the backend workflow. What that action returns is an ID for the scheduled workflow. (The utility of that is that we could use that ID to cancel the scheduled workflow. That’s really the only purpose of that value.)

So, that’s what backend workflows are.

Now, these are not to be confused with the mechanism Bubble provides us for making HTTP GET, POST, etc. calls to (usually) external web resources. This is called the “API Connector”.

Calls to such web resources via the API Connector can be made in one of two ways: Either via an action in a workflow (where they show up with the names you’ve given to a particular action call under Plugins) or “as data” by referencing them in an expression built in the Expression Builder, using the “Get data from an external API…” dynamic expression.

Whether a given API Connector call (“API call”) is available as an action or as data is configured when you set up your specific API call in the API Connector. (See image below.)

Note that there’s nothing keeping you from having a call available by both methods (just duplicate the call and set one to “Use as Data” and the other to “Use as Action”).

Here’s where I think you might be getting confused: An API call configured as an action can be used in either a client-side (in page) workflow or backend (“API workflow”) workflow. And the same is true for an API call configured as “data” – anywhere you can write an expression, you could potentially use that API call via the “Get data from an external API…” expression.

That is: API calls made via the API Connector do not have to made in the backend. They can also be made client side. (On the client side, note that some API calls might be made directly in the page while others may need to be brokered by Bubble’s servers, however, the API Connector abstracts this detail away.)

So, anyway, if you want to set List Shifter’s Custom List to be some result from some API call, you can either:

  1. Make the API call (the actual API call, not “schedule backend workflow”) in the action step before Set Custom List and then set Custom List to the “result of that step”.

Or

  1. Configure that call as “data”, and then you can simply use the “Get data from an external API” in the “Custom List” field in Set Custom List. (Though note that in either case, you must configure the type of that field in List Shifter’s main interface, under Process List Type or else you’ll not be able to select any value.)

If for some reason, you desire to make the API call in a backend workflow, you won’t be able to return any values to the page via “Schedule API workflow”. What you would have to do is either (1) store the response in your database and retrieve that in whatever page you need it (this doesn’t really make any sense) or (2) configure the backend workflow in question as a publicly available endpoint.

When you configure a backend workflow as an available endpoint the “Return data from API” action becomes available to you. And what that action does is configures the response from your endpoint. And now you could go into the API Connector and configure an API call that calls your own app’s endpoint that you just built.

But I can’t see any reason to do that in this instance. However, if you’re interested in that topic, I touch on it in the video linked here: FLOPPY: Plugin for localStorage, sessionStorage, IndexedDB storage, List Creation/Manipulation, Iteration, and More! Now with even more video docs! - #128 by keith

1 Like

@keith Thank you so much for your detailed response, it helped clear a few things up to me.

The biggest thing I’m confused on… Is there any way to make external API calls that do not show the response client side while at the same time not needing to save the response in my bubble database? I can’t find this answer anywhere.

I don’t want to have to save the data as a Thing from this API because it’s going to result in an huge amount of database entries. And I want to make sure users can only see what data i choose to show.

I thought that this might be the solution (or close to it) to trigger the API server side without exposing any response date back to the client side… but can’t get it to work (thought this might be the proper way to pass the parameters around)

hey @keith ,

I just recognized an error when having the search element from fuzzy search plugin from zeroqode on the same page referencing the same values which I wanted to change with list shifter.

The result is that only the first two values are iterated and then it stops.

When deleting the search element from zeroqode everything works as it should.

Hey @daviddr17, I can’t tell you what might be going wrong in that scenario, but it’s unlikely to have anything to do with List Shifter. If you were to create a simple page that demonstrates the issue, I’d be happy to take a look.

here you go, just type in any number and you can see that it just changes the first entry.

When deleting the fuzzy search element, everything is working as expected.

@daviddr17 - I need to be able to see the editor for that page. I should also say: You’re going to have to explain to me how that page illustrates the issue / what to do as from just looking at the runtime I have no idea what this is supposed to do.

@daviddr17 thanks for the example you provided. I’m not really sure what to tell you here except that “don’t do that”.

The issue is that you are making changes to things that are referenced in the main interface to both List Shifter and Search & Autocorrect (btw, the code of that plugin is rather poor, but the quality of its code isn’t the problem). When the values of the fields in a plugin change, this causes the plugin’s update function to run. And, in the case of lists, the plugin will typically fetch the lists (as both List Shifter and Search & Autocorrect do).

Bubble has a slightly strange way of loading data whereby instead of making plugins have to load data asynchronously, the calls appear synchronous but the plugin execution may be repeatedly started, terminated, and started again until all the required data is loaded. (This is true for both lists and even individual Things. Basically, anything that might come from the database can cause this to happen.) It does this with a library that does some really funky things with JavaScript promises. (Promises are a way of handling asynchronous JavaScript execution.)

I actually spent quite a bit of time replicating your issue in a test app and I see the same thing as you. What appears to be happening is that, since you’re changing the data that’s being loaded into Search & Autocorrect, this is causing S&A to run its update routine every time the Iterate workflow runs.

And I think what happens is that, when that update process loads the list, it gets started and stopped like I described before. I think as part of this Bubble is killing all of the promises pending in the app. List Shifter’s Iterate function uses promises to know when to fire the next “Iterate from List Shifter” event. (What I see in my testing is that the first and the last promises from List Shifter resolve, but the rest never do, but neither do they error out in my own code, so they are getting resolved/killed somewhere else.)

I tried a lot of workarounds such as hiding S&A before beginning iteration and reshowing on Iteration Complete, but I wasn’t able to keep its update routine from stomping on what List Shifter is doing. Also tried using a custom state that only gets changed when List Shifter isn’t doing iteration (but this doesn’t work because the individual Things in the list are changing and this causes S&A to update as well).

(There are of course many other things you could try that I did not, like seeing if you might be able to empty out or change the source for S&A using a conditional to “disable” it or if you might be able to disable/re-enable it some other way. But that’s probably more thrashing than its worth for a goofy plugin.)

Most obvious workaround: One way to do what you want would be to use a different approach to iteration that doesn’t rely on promises, such as the “Step Mode” feature in Floppy, which should work in this instance. (You tell it explicitly when to run the next step. It doesn’t automatically detect when some specific workflow is complete.)

(You may at this point be wondering how it is that List Shifter’s update function doesn’t stomp on itself in the same way that S&A’s is. When List Shifter is iterating or doing process list, I essentially suspend the update function so that it doesn’t attempt to load data until we are done.)

Postscript: BTW, if the Search & Autocorrect plugin were forkable, I’d have probably just forked it and added an Action whereby you could suspend its updates. But it’s not, so I won’t.

I could be entirely wrong about the cause of this issue, but I don’t see a way around it in my own code. (Though as I said, it could be fixed via changes to S&A.) One might also see this as a Bubble bug and could report it, I suppose, but I doubt this would be a high-priority. Though possibly they would take a look. Personally, I wouldn’t consider this a “bug” per se, but it’s certainly not optimal.

1 Like

Hi @keith ,

I’ve been using your ListShifter plugin quite well to process a chunk of financial data. The data gets crunched when a user clicks on a certain trigger and then it takes about 1-2 seconds to crunch the answers. The data that populates the master ListShifter element comes from a financial API call. That’s all fine and good and works well.

Simple question, I’m curious about creating a backend workflow that triggers during the night (using Cron-Job.org) that can process the same financial data with ListShifter so I can write it to the database without having any user manually trigger it.

I’m not an expert with backend workflows, but is there a way that I can reference a front-end workflow that runs the ListShifter math from the backend? Or somehow recreate my ListShifters in a way that can be referenced with a backend workflow?

Thank you kindly,
Dan

Hey @underhill.dan , I assume you’re using PROCESS List in the front end?

There isn’t at this time a server-side version of that action as the interface is a total pain to build.

If you could share a little more detail about your calculations (what they are and how you’re doing them, a screenshot, etc.) I could provide more guidance. Feel free to private message me that!

1 Like

thanks for your detailed answer. I thought that the issue would go in this direction and understand your listed points.

Right now I’m just not using both plugins in one page, but maybe @ZeroqodeSupport will notice your new posting and we hear something from them.

1 Like

You might wanna directly ping them in the support thread for that plugin. If it were forkable it would be easy enough to just add an action that lets one disable/enable it. (Though note that I may not be doing much Bubble stuff over the next week as I have a conference/offsite thing to attend and it seems my dance card is pretty full.)

1 Like

Hey gents,

I tried to search for it but couldn’t find an answer in the thread, about the list-shifting option.

Basically, I have a list shifter, that shows all subcategories, on index page (search page).
When one subcategory is selected, it changes visual properties (text color, bottom margin color, etc). Like this:

So initially around 10 subcategories are loaded, the rest are 'hidden-on-the-right" and when I am moving the list to left/right, the list shifts, and then I can shift through all subcategories.

The question is - how to focus selected subcategory if it’s not in the initial 10 shown categories?
To explain - when I do a search for a subcategory in search-bar, it brings me to the index page (search page), and automatically selects the subcategory that is searched for. This is ok. BUT the issue is - if that subcategory was not in the first 10-12 loaded subcategories - the searched subcategory will be activated, but it will not be visible. Only after I shift the list left and right, I can find that subcategory.

So, is there a way to focus on one specific item from the list and show it if it was further away in the list?

Thank you very much for the help!