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

Oh sorry, I misread your first post. Note that while you might think there’s some performance penalty here, there really isn’t and an efficient way to do this is:

Step 1: open - close
Step 2: high - close
Step 3: Result Step 1 < 0
Step 4: Result Step 2 (push to Processed List, only if Result Step 3)

1 Like

OK, that’s starting to make sense. Last question, I’ve defined the OPEN list in the LS Type List Constant so I can select it as Operand Y. How/where do I define the HIGH list so I can use it as Operand Y in Step 2?

EDIT: Would the Anything Constant serve that purpose?

Yes, other inputs you can use are the PL Type List Constant (that’s a list that’s the same type as the Processed List type which for you is a number just like the LS Type List). And then you could additionally- or alternatively use Anything List Constant.

1 Like

Hi @keith,

The main reason I really want to use LS Process is because it seems FAST. I’m going to be crunching a year’s worth of financial price data and it seems like it should be able to do it in a fraction of a second if I can get it work correctly.

However, when setting up a PROCESS to work on multiple lists, I can only get NULL results when looking at the console. I’m working off some lists derived from a master list and when I process any one of those lists alone with basic math I get a processed list successfully.

But when I fill out a LS Type List Constant or Anything List Constant with one of the other lists, all of the results are just NULL. I’ve tried every variation of formatting I can think of and I cannot get it to produce a single result other than NULL.

I MUST be missing something or doing it incorrectly. I’m wondering if need to book some time with you to share what I’m working on in the hopes that you can spot where I’m messing up.

I would suggest duplicating those example pages I shared into a project of your own. Then you can really inspect them.

Note that when you import List Type constants into process list, there are several different operands you can select that relate to them. Example: You can get the entire array all at once with LS List Type Constant, but again that’s the entire array.

The individual items in that list are available to you as LS List Type Constant ITEM. (For the nth iteration, LS List Type Constant ITEM is LS List Type Constant[n] .) That’s what the example is using where we are taking a list “a” and multiplying each item by the corresponding item in list “b”:

In case you’re wondering why it might be useful (not necessarily to you, but in general) to be able to access the entire array:

If the first operand is an array, most of the operators can be used “array-wise” and the operation is considered to be “for each item in the array, do this operation". So let’s say we have some list of numbers that we’ve imported and we want to multiply each of them by 10, we could do something like:

Internally, what happens in that case is we do a .map() on the array in question (where for each value, we do the specified operation and that new array becomes the Result of that step).

If we set the second operand to be an array, many times this may cause unpredictable (or hard to understand) results. If the second operand is an array (but not the first) we still do a .map() operation, but now we’re mapping over the second array, and the value of the entire array is sent as the second operand.

Unless the operation accepts an array as a valid argument, this is essentially non-sensical and we can expect to get null-ish values back. (In the case of multiply, for example, this will cause the evaluation - in JavaScript - of x * [the array y] which returns undefined. Obviously, that’s not a number and NaN values get converted by Process List steps to null. So we just get an array of nulls back in this case.)

Thanks @keith,

I wasn’t using the LS Type List Constant ITEM Operand. Using that, I am now getting numbers being crunched, and results being derived.

Another question: I am getting only boolean TRUE/FALSE results in my processed list when I want a number. Here’s my desired workflow, along with images of steps number 1-5 and what the console shows for each step…

Step 1) Operand X - Y
Step 2) Operand X - Y ( Y is a different List)
Step 3) Is RS1 > 0 (a positive number)?
Step 4) is RS2 < 0 (a negative number)?
Step 5) are RS3 AND RS4 both true? If so, THEN push RS1 (a number) to the final list

Here’s how I’ve set it up:

I’m only getting “TRUE” or “FALSE” being pushed into the list. Here are the console panels:

My goal is to have a final processed list of RS1, instead I’m getting just boolean values.
Can you spot what I’m doing incorrectly?

Thanks so much.

RS3 and RS4 are both Booleans. The expression RS3 && RS4 will always yield a boolean (true for RS3 and RS4 being true, false for either being false).

You still have step 6. Which is where you say what you want to do if RS5 is true (or false).

I hear what you’re saying. When I clear out Step 5 except for the two Operands to test, and then go to Step 6 and choose Result Step 5 in Operand X (to test if it is TRUE), and then in Push/Sum/Set I choose RS2 (which should be a numeric value), my list is still empty when Processing is finished. I can see the values in the console for RS1 and RS2.

EDIT: I may have finally figured it out. In Step 6, I needed to have the value I ultimately want passed to the list to be Operand X (Result Step 2), then Push RS6 to Proc List set to YES, then finally the Push/Sum/Set Only set to the value that I’m testing for TRUE (Result Step 5).

Whew.

Right. You got it!

1 Like

I have a RG (using List Shifter as its source) which has various filters on it. I want the user to be able to click the Reset All button and it clears the filters and resets the RG to its original non-filtered state. I can reset the filters without any issues using the Reset Data function but I can’t seem to find a way to reset the RG itself (when I reset the filters, the RG stays filtered).

I thought using a ‘Reset a List Shifter KW’ would do it but clearly not.

Hi,

I like the idea of the plugin but even with videos, i must do something wrong because i can’t iterate. I tried the video about the area of circles but the process only iterate once and i get a error message :
The plugin List Shifter Karma-Ware / element List Shifter KW threw the following error: _@https://dhtiece9044ep.cloudfront.net/package/run_debug_js/1b22e2b9ef1a062689cc00f34b5e6fd0078fe112de4b7fcf64dc5d5a1ea3942d/xfalse/x15/run_debug.js:6:2501322
d@https://dhtiece9044ep.cloudfront.net/package/run_debug_js/1b22e2b9ef1a062689cc00f34b5e6fd0078fe112de4b7fcf64dc5d5a1ea3942d/xfalse/x15/run_debug.js:6:2502333
[171]
Like on the video, i used an action ‘begin iterate’ with the push of a button. Then from the event ‘Iterate From’, i set a state with the result of a calculate a value from the current iteration, i add that value on a list.
It works but only once, for the first value.

Hey @faismoibg, welcome! Also, if you point me to the editor for your sample project, I can tell you where you’re going wrong.

Ok, thanks for the answer. I suppose you can access the editor with that link ? Faismoibg | Bubble Editor

Ah, I see, @faismoibg. So, this isn’t really documented (partly because I’ve not really tested List Shifter with date ranges), but basically, List Shifter doesn’t properly support the date range data type.

This is why you’re getting that error about ListShifter KW A in the console and also in the debugger. (What’s happening is that ListShifter KW A is basically crashing and so never initializes and will not do anything useful.)

The solution in your case (I’m talking about the page you pointed me to: Faismoibg) is to feed that List Shifter not with RepeatingGroup Rendez-vous's List of Rendez-vouses:each item's Ceneau, but make the List Shifter’s Data Type of List Rendez-vous and feed it with RepeatingGroup Rendez-vous's List of Rendez-vouses.

Then, when you’re iterating over List Shifter A, the Current Iteration Item will be a Rendez-vous, but you can get the item’s date range by Current Iteration Item's Ceneau.

Further:

I see where you are also trying to simply test the Iterate feature using List Shifter B. You’ve currently got List Shifter B set up correctly, but over in your workflow attached to the “GO” button (which you have disabled right now), you are attempting to fire the BEGIN ITERATE action at List Shifter A (which is broken and will not respond).

To test your “B” workflow you need to fire BEGIN Iterate at ListShifter B. Like so (select List Shifter B not List Shifter A):

As far as why List Shifter does not support the Date Range data type properly:

This comes down to an inconsistency in Bubble’s plugin API. We publish exposed states (such as List Shifter’s Original List) with a function called publishState(). If an exposed state is a List and that output is supposed to be an empty list (the list has no items), we can in almost all cases tell publishState() to push an empty array ([] in JavaScript), which is what List Shifter does.

However, in the case of Date Ranges (and probably Numeric Ranges), publishState() it seems not to interpret as just make the output empty. Instead, it throws an error (“expected a date range but got an object instead”).

This inconsistency is basically a bug in Bubble’s plug-in API. While I could work around it (and I might fix that in a future update), it’s rather a pain to do so and I can’t commit to fixing it in any specific time-frame. But I have run into this before and should probably report it to Bubble as a bug in the plugin API.

In your case, what I suggest above will work just fine though!

Thanks for the great explanation. I can’t get the Preview to work right now so i will have to fully test it later.

Actually, for the test of the Iterate function i intended to use the Button C to launch it., with a simple operation on the numbers from List Shifter B. I could have used the wrong button during testing.
Thanks again !

Hey @wrightj2, whatever the issue is here, it’s not from List Shifter. List Shifter always just outputs whatever its “List to Shift” is. You don’t show how you’re actually implementing the filtering (there are multiple ways we might do that), but when you’re applying filtering, that does not change what is present at List Shifter’s outputs.

If you really want to force your RG to update back to showing all of the items at a List Shifter output, you could do the action “Display List” and force the data source back to being whatever output of List Shifter it’s supposed to be looking at.

In terms of what’s probably causing you consternation:

If you’re doing your filtering in the RG based on Conditions, you probably need to add a Condition that sets the RG’s data source back to the unfiltered list, when whatever criteria occurs that represents the “we are not filtering” state. Note that composing a “When” expression for this may be impossible, which is why you’d just force a Display Data action, as I suggest above (you would do this in the “When Reset All is clicked” workflow, and add it as step 2 after Reset Group Filters.)

Edit: I meant to also add the following… The RESET action in List Shifter does the following (this is documented in the plugin itself, but Bubble doesn’t expose this documentation in any meaningful way – you have to actually look at it in the plugin editor – yet another really stupid Bubble thing). Anyway, here is what RESET does:

“Execute this action to reset List Shifter’s Shifted List to its initialized state. Transformations such as SWAP Items are cleared and most other values revert to their initial state. Note: This action DOES NOT clear List Shifter’s Processed List, Custom Value, and Custom List as these values are only published in response to your own workflow actions.”

@keith thank you for your amazing plugin. I have already used it successfully a few times.
I have a use case that I think list shifter and/or list popper is going to be a better solution to than the one I have right now, but I just can’t figure out how to do it. Maybe you are willing to show me a step in the right direction. I had a look at probably all of your videos and explanations but I think my use case is a little different or maybe I just can’t see the solution because I have no experience with code or JS at all. Or it also might be a wrong setup of my database structure.

I have basically these datatypes right now:

Meal Plan |
Meal | Recipe | Portions | Meal Plan
Recipe | Ingredient | Quantity | Unit
Shopping list | Ingredient | QuantitySum | Unit | Meal Plan

When a user wants to look at a shopping list for a Meal Plan, I want to calculate that. So what has to happen is that for each Ingredient in a meal it has to calculate portions*quantity and then to sum that quantity up grouped by the unit and the ingredient.
At the moment what happens is that in the backend I have a recursive workflow, that is pretty slow.
This is how it works right now:

  1. Clear shopping list
  2. send list of meals to backend workflow
  3. Take the first ingredient from the first meals recipe
  4. Multiply the meal’s portion size with the ingredient quantity
  5. If the ingredient with this unit already exists → add portion*quantity to the quantitySum, if it doesn’t exist create a new shopping list item
  6. repeat with the next ingredient from the first meal
    When it finishes with the last ingredient from the first meal, it goes to the second meal and so on.

I have thought about creating a parallel list of quantitySum with “process” action but wasn’t successful. I also tried to two “iterate” workflows, to mimic what I do right now in the backend, but didn’t get that to work either.
I am out of ideas so I thought maybe you have one.

Best regards
Michael

@keith
How do I suspend iteration of list B until an iteration of list A inside B is complete?
So basically its an iteration inside an iteration?
Please help
image

Learn to use Process List for this.