FLOPPY: Plugin for localStorage, sessionStorage, IndexedDB storage, List Creation/Manipulation, Iteration, and More! Now with even more video docs!

Hey, @johnnyweb - the version of Rehydrate that I published last night is a client-side element, but I could pretty easily churn out an SSA version. Have you tried it in your page yet? (If I did turn it into an SSA, it should be able to easily handle a list of 4000-ish UIDs.)

Also, it’s a little more work, but would it be helpful to have a version of SS Parallel Date that accepted a list of date strings to parse? (It’s unclear to me if it would be helpful to you in this particular case. What it would do is spit out a list of parsed dates rather than a single one. However, if you would still need to recurse over that list of dates anyway, this might not be much of an efficiency gain. LMK.)


No I’ll have a play with rehydrate and if it looks the goods (as Im sure it is!) I’ll need to go back and change a LOT of API’s and get the UID data into the backend. But this process takes over an hour at the moment (theres a bunch of UID’s to match) so we could be on a winner. Its 4000 records but there’s 4 UID’s that get matched per record :smiley:

My experience is batching works well with large lists (say 50 records at a time with a small delay) but in this case Im also rolling start end end times to nearest 15 minutes so not sure if it would work in this case heres my BE workflow for date conversion

I’ll DM you on what Im doing with the UID’s - Thanks for the awesome support!

1 Like

Oh, I see. Steps 2 and 3 are both SS Parallel Date actions, right? In each recursion, are is the parallel date conversion always to the same timezone? Or do they vary per step?

If they don’t vary, it actually would be a bit of a resource saver to bulk convert all the start and end dates in the kickoff step (that would basically take the same time as a single conversion, really) and then you wouldn’t have two SSA steps in each recursion. Just something to think about.

As for “rehydrate” it’s just super-simple as this is just a core part of the plugin API. When we use the instance.publishState() method to publish values for a Thing, we can send it either the original Bubble object(s) for the Thing, or just the unique ID that represents that Thing and the plugin builder API magically converts them back.

So all it does is read the list of UIDs that get sent as text and then publish them to a properly typed output (you tell the plugin what type the UIDs represent in the main interface) and once there they are magically Things again.

Oh hai: I put a YouTube playlist together with 6 of my videos about Floppy (which may or may not be all of them?), but anyway if you like youtube and you haven’t had a chance to see or find all of them here, it’s a convenient way to do so:


Am I right in thinking I could potentially make my users experience ‘faster’ if I save lists to floppy in a storage like ram?

I have a job listings site. Would there be a way to basically save that list to users once that day (when the load the site) and then update it the list if the list has changed (we added more jobs)?

Oh hai - here’s a new freestyle video where I talk about synchronous vs asynchronous actions (in general) and then demonstrate the new Sync Trigger feature in Floppy.

I kind of departed from my intended script here, so I’ll probably do a followup, but this should be helpful to someone…

Oh, and here’s the very helpful post I mentioned in the video, wherein Tip: Order of Operation - #2 by aschofer @ashofer from Bubble gave some helpful insights into synchronicity/asynchronicity of Bubble workflow actions.


Lol does this mean anything to what I just posted above? If so, that would be crazy.

No, it’s just “synchronous posting”! :stuck_out_tongue_winking_eye:

Hey @bkerryk - well, not really. Sounds like you might be a bit confused by the “RAM” nomenclature. I just use that cheeky naming convention to distinguish the in-memory (volatile) storage from the persistent (browser) storage in Floppy.

Now, you can use Floppy to save data into the user’s browser storage (session, local, or IndexedDB without interacting with the Bubble database, but this is really only true for simple data types. Once we’re talking about Things, there’s always interaction with the database, but it can still be more performant than doing a Search.

As an example, suppose you construct a “Wish List” of Products (a thing, a custom datatype) that a user wants to buy. You can store such a list in localStorage or IndexedDB without having to create a field on the User object in your database to hold it. (Although the Products themselves will just be stored as their unique IDs in browser storage and so, when you load the items in the Wish List they will still be fetched from the database, but you don’t have to do any sort of query to know what they are! And you don’t have to write anything to the database to change that list.)

@keith In your video example with the Custom Event, the only way to succeed is to have several Custom Events next to each other. Then the whole thing will be synchronous. It’s a bit absurd but it works.

1 Like

Hey @JohnMark, when you posted this I was like, “Oh yeah, that might work.” But it actually turns out that it doesn’t in this particular case. Pretty wild. So using the “Sync Trigger” feature seems to be necessary in this specific context (that is, when making sure that a “Create New Thing” or “Make Changes…” action waits for Floppy’s RAM List / RAM Scalar values to be updated). :man_shrugging:

1 Like

@keith I forgot a small detail… when using customs in series, it is necessary to force the detection of a change of condition otherwise the old values of the Bubble “buffer” are taken into account and give erroneous results. This discovery surprised me a lot. Inside a Custom I voluntarily create an addition in a status (simple text variable) into my database. For example I add a symbol :small_red_triangle: and then I validate the rest of the sequence by replacing the symbol :small_red_triangle: by another symbol :white_check_mark:. Technically, it forces the execution of the operation and it validates the conditions correctly. I sometimes call 5 sequences one after the other thanks to this technique with the right values from one to the other. Without this, it doesn’t work. I’m sorry for my somewhat lame explanation… but I hope this is clearer.

Hey @JohnMark - I don’t quite understand your expanded explanation here. Are you saying you do some database interaction? (That’s not particularly desirable as there’s no reason for us to do that - also such an approach can fool us - are we merely slowing things down enough such that by the time we reach the Action we desire to be synchronous, our previous action that wasn’t awaited is now finished?.)

Note that in my example, surely the Create action is triggered only a ms or 2 before the RAM List value is updated. In fact they may happen within a ms of each other and so may even appear to happen at the same JS time value, the resolution of which is limited to one millisecond (which certainly isn’t granular enough on my system, which can initialize several complex plugins in the same millisecond).

Are you a Floppy user (Bubble doesn’t tell us who our purchaser/subscribers are)?

If so, I’d appreciate an example of what I demonstrate in that video (modify Floppy’s RAM List and trigger Create a New Thing where some field on the Thing successfully gets the values from the RAM List, without resorting to an arbitrary pause, an intervening unrelated database interaction, or Floppy’s own sync trigger/RAM List Updated events).

Because I can’t make that happen! (If such a solution actually works it should work with any other combination of actions of any sort and would be a very valuable tip!)

Yes. It’s far from being perfect. I don’t quite understand your plugin yet, but it will come. Yes I bought it to replace another plugin that was giving me a lot of trouble.


I’m working on it. But as you mentioned, it’s not the Nexus ultra in speed.


Hey Keith,

Any thought on making floppy accessible throughout the app like the bdk env variable?

That would be awesome!

Hey @troy.roberge, I’m not quite sure what you mean (I’ve not inspected BDK env variable plugin but I assume it just writes values on the window or something, though it’s not obvious to me what it does per page. Perhaps I should go look.)


The Floppy element itself is an element plugin which is designed to be very simple to use in its core use case (writing and reading some specific type of value to a certain key in storage).

As such, each instance requires configuration, so it’s not really clear how that would help.

If one wanted to add the same Floppy functionality to all pages (e.g., let’s say you’re using Floppy to store a wish list or the contents of a cart-like object or something and you probably want access to that on every page) you’d just put it in a commonly used reusable, like a header or footer. (And the Floppy Reader element would often be a better choice for this as it supports reading from multiple keys from a single element.)

There’s a video further up the thread about properly using Floppy in a reusable, BTW!

1 Like

Well I think you are short changing yourself. Sure, it started off reading and writing keys. But now it’s a list processor with built in events and triggers.

It’s very versatile, but could become more by being read from anywhere in an app without having to deal with outer reusable group states and such. I watched your video, but it wasn’t until I started using it a lot yesterday that it made me think about it.

For my use case, I’m processing a small list using steps, into the scaler value, then sending that off to an SQL query. But I’ll be using another floppy on another page for other things.

So just saying, you are already heading down the road of one of the “can’t live without it” plugins, just giving you another idea.

One can’t actually do the things you’re asking for @troy.roberge. I know the Bubble plugin API very well. Also, I provide plugins that are generally useful to Bubble users, not custom whackadoodle solutions that need inordinate amounts of setup.

Lol what part doesn’t work? It all works, just needs various plugins. Was just trying to give you another idea to boost up your plugin.

No worries.

You have no idea what you’re talking about.

1 Like