Forum Academy Marketplace Showcase Pricing Features

List Popper and Friends: New SSA Plugin for Your Backend Workflow (API Workflow) Needs

Hey @eli, there’s no reason to think it would be any faster. It’s just that List Popper gets around the issue of skimming items off a list of non-unique items.

(The speed of API workflows is entirely linked to an app’s capacity as far as I can tell. And, IMHO, Bubble seems really stingy with compute.)

1 Like

nice icon!

Thanks for making this available @keith . This is going to save me a lot of time and pain in dealing with lists and duplicate values (like quantities).


@keith, have you made any videos with examples showing how you would use list popper with api results (the ‘blob’ we get from api returns)?

HI @tom9, I have not, but it would be really, really similar to the video I posted previously. Although… I was thinking about maybe doing a video this afternoon and this might be a cool topic.

@keith honestly i’d watch any video from you on APIs.

1 Like

Just a note that List Popper & Friends version 1.0.2 is now available. This version adds a new feature to the FLOW State List SSA (ability to publish a list of the list items’ indices) and also a brand new server-side action, “IndexOf SSA”, which returns either the first or last index of where a given Item is found in a given List.

The IndexOf SSA is useful for scenarios such as the one discussed in this thread.

Hey Keith, hope all is well with you in San Francisco!

Question: I’ve been using List Popper to successfully convert Javascript Objects into bubble objects. So fun! Thank you!

It seems more elegant than using Bubble’s native Schedule Workflow on a List because with List Popper, I can always save the not yet processed parts to the database with two upsides:

  1. Traceability: If the associated “processor” workflow fails for some reason, I can always restart it on the remaining list without having any confusion as to what was processed vs what wasn’t.
  2. Progress indication: This is basically also “traceability” but specifically that, because I have the known size of the unprocessed list stored somewhere, I can make UI feedback like:

As far as I know, this isn’t easily done with Bubble’s native Schedule Workflow on a List, or am I wrong?

Anyhow, for all of these reasons, I want to stick with using List Popper for list iteration but I have one BIGish problem:

List Popper doesn’t seem to work on the User data type :confused:

Basically, any “Popped” User items return nothing, zilch. Other datatypes with the exact same permissions and workflow do return expected data.

After fiddling for a while I finally just deleted all of my User permissions (which is itself problematic) to make the User type totally public. I thought, “That should make it work!” Alas, it didn’t. List Popper doesn’t seem to transmit User data into any step of a workflow irrespective of permissions.

Have you been able to process a list of Users using List Popper? Perhaps I’ve just made a simple mistake?

I guess I can just go the " minus item: first item…” approach to this. Doing so still offers the “Traceability” and “Progress Indication” I thought only List Popper could afford… so long as my list of Users doesn’t include duplicates. But Bubble things pulled from the database always have unique IDs so that shouldn’t be an issue.

In the meantime, if anyone can confirm or deny that List Popper doesn’t work on the User field, I think that would be a good community contribution :slight_smile:

I haven’t tried that @zelus_pudding, but I’ll look into it. There’s nothing fancy going on in List Popper — but you might want to upgrade to the latest version. Older versions only work with non-thing (primitive) data types, but I fixed that in more recent versions. That’s probably the issue as Users are of course Things.

1 Like

Hmmm, strange. I was pretty sure I tested it against the upgrade :thinking:

Hi @keith,

Would it be possible to support null values within a list?

Currently experiencing this error message:

Workflow error - Plugin action List Popper SSA error: TypeError: Cannot read property ‘object’ of null at LambdaListApi.get (/var/task/index.js:187:36) at eval (eval at build_function (/var/task/index.js:55:21), :1:53) at /var/task/index.js:296:23 at run_fn (/var/task/u.js:594:18)

@zelus_pudding Did you ever manage to figure out why List Popper was not returning anything when it comes to Users? I’m having the same issue!

Well, I just took a look at the code again and it seems that what was published did not work properly for lists that are Things (Users of course are Things).

I just published version 1.0.4. Upgrade and test that one out an let me know if it works properly. (I’ve not thoroughly tested it myself, but this should solve your problem. Please let me know either way.)


I did get it to work but can’t remember what the issue was. My best guess right now was perhaps I had forgot to set the right data permissions (though I’m not sure that was it).

See above (List Popper and Friends: New SSA Plugin for Your Backend Workflow (API Workflow) Needs).

You probably made it work by passing the Users as their unique IDs. But 1.04 should properly support Things now. (In all of the Actions in this plugin. I think the source of my confusion before was that I had added Thing support to one of the other Actions, but not to List Popper itself.)

1 Like

That was it!

This works now!! Thank you !! :slight_smile:

Hi @keith , first of all THANK YOU for sharing this. The video was especially helpful to help me understand how to get data out of a custom API call inside a server-side action (aka the API Ghetto you talk about).

But I’m having problems with this plugin because it doesn’t work with null or undefined values.

My API call returns a list of LinkedIn Pages. From that API call I extract the id, name, and logo for each page. I then use those values to build a list of ids, a list of names, and a list of logos which I return from the server-side action.

My aim is to take those lists and “pop” a list item of each one to turn it into a LinkedIn Page Bubble thing (aka turn it back into structured data inside Bubble). So far this is the same process as described in your video.

But (and this is the important part) some pages do not have a logo value. So to keep each list of equal length, which is crucial for making this process work, I have return a null or undefined value when there is no logo value.

And that is where things go wrong with List Popper…

When using undefined or null values the resulting LinkedIn Page data is all mixed up. The ids, names, and logos do not match each other.

I have tested this by using a text value of NOT FOUND instead of undefined or null and that does make the resulting LinkedIn Page have the correct ids, names, and logos. They are no longer mixed up.

But that workaround has it’s own drawbacks because Bubble no longer recognises the image as “empty” which causes various display problems on the front end.

Is there anyway we can make List Popper work with undefined/null or similar values? Is there another way of doing this using lists of unequal length?

So far the solution you describe here is the best I’ve found for the API Ghetto problem, but alas I’m stumbling at this last hurdle.

Also, I needed a way of Merging two lists without losing duplicates.

I took a look at your code for “List Pusher SSA” and used it to created a new “List Merger SSA”.

It works the same as “List Pusher SSA” but instead of adding one item it adds an entire list.

If you want to add it to the plugin for everyone to use then feel free :slight_smile:

Plugin Action Settings:

Plugin Action Code:

function(properties, context) {
    var currentList, mergedList, updatedList

    function getList(List) {
        var returnList = []
        if (!List.hasOwnProperty('get')) return returnList
        if (!List || List.length() < 1) return returnList
        returnList = List.get(0, List.length())
        return (returnList[0] && returnList[0].hasOwnProperty('listProperties')) ? => item.get('_id')) : returnList
    } // end getList

    currentList = getList(properties.data_source)
    mergedList = getList(properties.list_to_merge)
    updatedList = currentList.concat(mergedList)
    return { updated_list: updatedList }
    // end merge

Congrats. You know what concatenation is. :+1: