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

Hello Bubblers, it’s your old pal @keith back with a new plugin called Floppy… so of course, there’s a long, talky video that gives a basic overview. (Hooray, I guess?)

Floppy is now available in the plugin store! Floppy plugin page here.

Floppy is a multi-purpose plugin for reading and writing values to the browser’s storage, using the localStorage, sessionStorage, or IndexedDB interfaces (IndexedDB support leverages the localForage library). Unlike other storage plugins, Floppy supports nearly any Bubble data type including all of the built-in Bubble datatypes, Things, Lists, and lists of Things.

Here’s the intro video where I talk about what Floppy can do, give an overview of what browser storage is and how it works, and show some simple examples of how Floppy can read and write to storage (see a properly embedded version in this reply!):

There’s a lot more that floppy can do that I’ll demonstrate in future videos.

It should be available in the plugin store soon and I’ll update this when it’s available! Happy Bubbling…

More Features at a Glance

A quick list of other things that Floppy can do, which are not demonstrated in the video above, but will be demonstrated soon…

Floppy has built-in scalar (single value) and list (array) states that are similar to custom states, but with a more robust set of manipulation features. These can be used to construct, modify, and manipulate lists. Additionally, there is basic support for drag and drop manipulation of certain types of Repeating Groups.

Floppy includes a wide variety of List manipulation features, including Actions to help you easily build, modify, and process Lists. Extra utility Actions include a proper “count” function for lists with list fields and “List Math” for doing simple mathematical operations on numeric lists. All of the List Shifter “SHIFT” functions you know and love (like Move, Reverse, Rotate and Swap) are implemented with enhanced error checking for goof-proof operation by newb- and pro-Bubblers alike.

New features include the ability to easily change individual List items, add items (and even lists of items) at arbitrary locations in a List. Lists can be processed List Shifter style (allowing duplicates) or Bubble style (prohibiting duplicates).

BUT WAIT… THERE’S MORE!

Iteration! Floppy also introduces two additional, all-new approaches to iterating over Lists: Step Mode (which lets you iterate over a List with more flexibility and control than in List Shifter) and the “Code: Array Method”, which lets you write simple (or even very complex) JavaScript to process lists using operations like .map() and .filter(), faster and more easily than with other solutions.

In addition to the main Floppy element, there’s a simplified Floppy Reader element for reading (and writing) multiple values of different scalar and List types from local/session/IndexedDB storage, using a single element.

The occasional utility element or action will also be added to Floppy. Recent additions include Floppy Expression Watcher (to watch some expression for changes) and Floppy Inspector (for exposing “native” Bubble values to the console).

MORE FLOPPY VIDEO DOCS: Join me as I explain Floppy’s built-in custom states, Floppy’s RAM List and Floppy’s RAM Scalar! I do a lot of live Bubbling, fix a bug, and also introduce the new IndexedDB (localForage) option, which debuted after Floppy was first published:

EVEN MORE FLOPPY VIDEO DOCS: Let’s explore more app futzing with Floppy, including the Write Any Key action, sort a RAM List by setting it to a sorted version, SHIFT Actions explained (Move, Reverse, Swap, Rotate), and how to make a Repeating Group drag-sortable using the “SORTABLE RG OPTIONS”:

ANOTHER new FLOPPY video! :tada:: Where we talk about Repeating Groups (and the “computation trap” of Repeating Groups), talk about how to randomly-access values in Floppy’s RAM List and change them, via the “Change RAM List Value(s) Action”, and introduce Floppy’s “List Math” action (which lets you do math operations on all the values in a numeric list:

Here’s another video about Floppy where I talk about using Floppy with Bubble API call responses. It’s rather long and a bit on the advanced side, but will be interesting to certain users:

34 Likes

:point_up: I don’t know why sometimes the forum doesn’t properly embed videos. Here it is embedded.

For folks that don’t want to watch everything, here are different segments:

Intro :point_down:

What is Browser Storage? :point_down:

Floppy Basics :point_down:

Simple Practical Example - Saving/Restoring a Draft Post (with plenty of flub-ups and talky talk) :point_down:

6 Likes

Okay just reading the description im already sold! :100:

2 Likes

Hi @Keith ,

This looks like a good plugin (I don’t see it yet in Bubble store). It would be nice to include ‘encryption’ enabled/disabled per field or for all.

And for people info:
“The cache storage size depends on the device. Chrome-based browsers typically permit 100MB per domain, but Safari limits it to 50Mb and expires data after 14 days”

4 Likes

Hey @JohnMark, I’m not quite sure what you mean by the second comment (“backend” feature) can you elaborate on what you’re thinking?

As for “encryption” (really, obfuscation in this context) - unlike certain other plugins that use a certain library, I’m not using that. The library in question has that obfuscation feature, and I’m not sure how I feel about that, TBH. Private or secret info should never be stored in browser storage and I don’t think Bubblers should get the impression that you can.

(In my own non-Bubble work, and in enterprise software in general, we DO NOT see values being obfuscated in browser storage. Drift, 6sense, all sorts of things store data in storage - as large objects sometimes - but all clearly readable.)

The TTL (time-to-live) feature that library offers is interesting and potentially useful, but I prefer to provide native functionality without libraries in most cases. Something I’ll think about.

5 Likes

Thanks, @lantzgould! It is true that my plugin names are best names.

2 Likes

“automagically” :rofl:

1 Like

Legend! Always a treat learning from @keith while watching plugin tutorials.

1 Like

Holy mother of god! I’m sooooooo excited for this!!! I may have a TONNE of questions coming your way while I play with this :rofl: :rofl:

Are you still waiting for Bubble to approve it? I can’t seem to find it in the store (you may have already addressed this but I haven’t read through everything yet)

2 Likes

Wow, nice one @keith a lot of power and potential with this and as always well documented will binge the series :grinning_face_with_smiling_eyes:

Cheers

1 Like

There are plugins like ‘variables’ or ‘server side variable’ that allow you to write temporary variables to play with on the server side. It is not the browser storage but I keep the idea to have the same things you created available on server side (list, multiple variables, date, …). It’s probably a different kind of plugin.

As far as encryption is concerned, it is not necessary for the user to know why we create certain variables. If his machine is hacked or if the user uses a public computer, the values are not readable. Maybe is feasible to use the internal SHA256 converter from Bubble?

Third, the way you create your plugin will give you the ability to create some sort of OFFLINE design, and easily read and update the information when you come back online. This is why encryption or at least text shuffling is “necessary”.

1 Like

Hey @equibodyapp, yeah it just got resubmitted yesterday, so it’s not in the store just yet, but should be shortly.

Hi @JohnMark, ah, I see, yeah you’re talking about Server Side Actions. A couple of things to understand about server-side stuff:

We have, for some time, been able to run JavaScript on a server (that is, on some backend system) rather than in a browser. This is most commonly done in an environment called Node.js (which first appeared in 2009) and it’s basically a virtual browser that runs on a server.

In Bubble, we can create plugins that run in a Node environment on Bubble’s backend. Like client-side (browser) plugins, these plugins have a configuration interface where we can pass some data to the plugin and then that plugin can return various values to the backend workflow. (SSAs can also be used in the browser: In this case, the plugin does its magic on the backend but then can return values to the client-side workflow.)

We don’t have to use Bubble for this, by the way, we can also use other “function-as-a-service” services like Google Cloud Functions, Netlify Functions, and others to do very similar stuff (though we would interact with those via Bubble’s API connector rather than through a plugin dialog).

Node (which again, you can think of as sort of a virtual browser in that it runs JavaScript) supports many of the browser APIs that we would use client side, but not all of them. Some browser APIs don’t make sense in the server-side environment and localStorage/sessionStorage are among these, especially in the context of function-as-a-service and Bubble plugins (which are basically the same thing with slightly different interfaces).

To be clear: What happens when we invoke a Bubble Server Side Action plugin (or, for example, a Google Cloud Function) is that (1) a Node environment is spun up (this creates what’s essentially a virtual machine that has some amount of compute, memory, and even the equivalent of a file system we could access temporarily), (2) that environment is used to execute our plugin/function code, (3) the plugin/function does some computation and then (4) returns the results of its computations to the workflow (in the case of Bubble SSAs) or as the response to our API call (in the case of something like Google Cloud Functions) and then… (5) the Node environment disappears (it’s like we closed the virtual browser, but also we threw out the whole virtual computer) – it just doesn’t exist anymore.

So you can see, in this scenario, “persistent storage” doesn’t really make any sense. Anything we want to “store” only lives for the (very short) duration of the virtual environment. Regardless of whether something’s just a variable or we interact with a virtual file system, none of that will “persist” once the SSA/function spins down.

So, anything we need to extract from that environment, we would send with our return values.

On the Bubble backend, your “persistent storage” is the Bubble database. (Just as it is on the front-end.) And, in a backend workflow, if we have an SSA that computes something that we want to store permanently, we call the same workflow steps as on the front end (e.g., Make a new thing, make changes to a thing, etc.) We might also, at the end of some backend workflow, kick off some other backend workflow and pass data to it, in much the same way as we might use URL parameters in the browser (to “pass data” from one page to another).

The above being said, vanilla Bubble doesn’t have a server-side workflow action that evaluates some expression and then simply publishes the resulting data value to its output, so that we can refer to it in later workflow steps. This can make building backend workflows more difficult than it needs to be. So there are a couple of handy SSA plugins in my “List Popper and Friends” open source plugin collection that do just what I described (these are the “FLOW State List” and “FLOW State Single” Actions).

As for the encryption/obfuscation feature: I get that some folks think that’s important, even though I do not. That’s not a high-priority feature for me, but it might be part of a future update.

As for my plugin interfaces: In general, all of my plugin interface fields have show/hide documentation, but I also use “Information” fields to present essential info and to organize the various sections of my main plugin interfaces and interfaces to Actions. The types of interfaces that the plugin builder lets us create are quite limited and, personally, I find it helpful to have non-hidden text that reminds me of important facts about the main setup and what the various actions do.

7 Likes

keith… that plugin is so hot, it should be listed on p…hub haha. Can’t wait to try it out, you’re (yes, ONCE AGAIN) bringing features that should be native to Bubble’s environment.

Thank you so much for what you’re bringing to community.

Two questions for you, I watched your long video, you’re saying you can save anything… Is it really anything? aka api connector results? if so… whoa.

And second : Could you explain what would be the best way to use floppy in a (for example) one page app with many reusable elements… Aka : Save some basic user data on the main page element… and use that data in the reusable elements? Would you go by setting states manually or there’s a fancy way of using that data anywhere?

Thanks again.

2 Likes

Hey @Future - so, the way objects come from the Bubble API connector, they can’t be stringified, so can’t be saved to browser storage. However, I believe what one could do is just retrieve the raw API response and then set up a clone of that call to just accept the string of the raw response (which can be written to storage as it is, in fact, already JSON stringified).

This is a really good question and I’ll check it out and give you a more formal response and probably a video about this soon.

Oh, @Future, what you’re asking is possible. Just set up a version of whatever API calls you need and tell Bubble they return text (so that will capture the raw api response). Bubble seems to have a “raw data” option in the “Get data from external API” expression/action, but I’ve been unable to make that work, BTW.

Then define a public backend workflow that simply takes a text and returns that same text as text (not JSON). Do this for each API call you want to later parse.

Then you can call that endpoint from the API connector, telling it the response is JSON (because it is) and initialize the call just like the “original” one. But instead this will simply parse the JSON.

So now you’ve got an API connector call that goes to the original service and refers the raw response. This you can store with Floppy as a text (a string).

Then you can call your “parse” call whenever you want to restore that call to a “real” Bubble API response object.

I’ll do a little video on this. It’s quite easy but there are several little steps if you’ve never configured your own workflow API.

1 Like

Thanks man! I almost got around to make it work (just missing time), but I still can’t believe the amount of “workarounds” we got to do to make things work haha. Can’t wait to try your plugin.

Just a little update here: At the moment, it seems Floppy is still under review by Bubble. However, I’ve added a new feature so that Floppy supports not just localStorage and sessionStorage, but read/write to IndexedDB as well!


When using IndexedDB, you’ll be able to name whatever database you want to write to, as well as the datastore (which is basically like the concept of a “table” in IndexedDB).

Floppy leverages Mozilla’s own “localForage” library which makes reading and writing to IndexedDB more-or-less just like using localStorage. Tip ‘o’ the hat to @equibodyapp for inspiring me to do this.

9 Likes

You’re the GOAT!!!

2 Likes

Looking forward to a classic Keith video on this.

Nice work man

2 Likes