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

This isn’t Floppy. That’s just Bubble.

Howdy, @ihsanzainal84 – thanks so much for the pointers to what was causing this. (I was doing something a bit stupid with loading the list for “List to Step”. It’s annoying how Bubble internally fetches lists and this can on occasion lead to this sort of issue. I hadn’t discovered it because I was testing in ways that didn’t reliably trigger this bug.)

Anyway, this is fixed in just-published 1.7.8 and your little test setup you shared with me previously should work properly now. There’s also some new debug messages that appear in the console when you’re in step mode and “debug” is yes that tell you interesting stuff like how long it took to load the “List to Step”.

Cheers, K

1 Like

UPDATE TIME: Latest Floppy version 1.7.8 fixes a boneheaded bug in Step Mode that caused the “List to Step” to load incorrectly in certain situations.

(Shouts to @ihsanzainal84 for patiently explaining when/how this happens.)

I’m pretty sure Step Mode works as intended now and we’ll do a little video about this feature soon (not that it’s hard to understand).

1 Like

I wish all the other “pro” plugin creators would care as much as you to iterate and add features, rather than fill the marketplace with half baked plugins.

Thanks Keith!

6 Likes

Thanks @troy.roberge! I basically only release actually useful stuff (regardless of whether it’s open source or commercial) and, as they say, “I service what I sell”.

2 Likes

@Future: I made a (very long) video for you where I talk about using Floppy with API responses and illustrate how (with a little annoying work) one can save the raw body response from an API call, store it in Floppy as a text key and then, via a different API call (to your own app’s backend), “rehydrate” the raw response back into a Bubble API response object.

Hopefully you find this informative and not too confusing. (Also, watching it at 1.5x will make it less painful. :stuck_out_tongue_winking_eye:)

EDIT: I didn’t (fortunately) demonstrate this in the video, but the get raw data feature DOES NOT yet work properly for sub-objects (like my Event objects that are inside the full raw body response). So it’s good that I didn’t talk about that too much. That problem is described in my reply to this other thread: Enable “raw body text” for Request Data feature! - #16 by keith

3 Likes

:clap: :clap: :clap:

2 Likes

dude… badass content here. Thanks so much again for all that. On a side note, I just got copy of the (work in progress) xano beta framework (i outsourced all my db stuff for legal reasons). I’ll try to see how floppy and that framework can work together to deliver content to the user while NOT proxy-ing all requests through Bubble. (direct browser to db api)

2 Likes

“rehydrate”… That is some real serious Bubble terminology right there @Keith :slight_smile:

1 Like

Ha, @bubble.trouble - that is actually the techical term that is often used in situations like this, even though it sounds funny. Like, if we’re converting some JS object to its JSON form and passing it to some external api, when we receive that JSON value on the other end and then parse it, it is sometimes referred to as “rehydrating” the object (it was just text, but now it’s the actual object… so… rehydrated). The term is also used in React programming where when a static web page is converted into a dynamic web page by React, it is sometimes said that the page was “rehydrated”.

It’s kind of a useful metaphor!

1 Like

@Keith yeah I was being totally serious. The Bubble framework is using the paradigm extensively. I figured you were digging under the hood a bit and hence using very accurate terminology.

1 Like

Oh yeah, there’s rehydration’ all over the place in Bubble (with plugin props, Lists, Things, API response objects and prolly lots of places I’ve not bothered to think about). There was at one point a specific bug with list properties (if I remember correctly) not being properly rehydrated and that was exactly the terminology Bubble engineering used. Anyway, thanks for watching my talky derpy videos!

The biggest problem with Floppy is its awesomeness compels me to re-do dozens of workflows to replace other plugin-ins with Floppy… really great addition to Bubble. :slight_smile:

I know you are busy trying to document everything that Floppy can do, but I am intrigued by the code:array method and wondering if it can help to populate data to Google’s Gantt Chart basically to produce an array that could replace

data.addRows([
[‘Research’, ‘Find sources’,
new Date(2015, 0, 1), new Date(2015, 0, 5), null, 100, null],
[‘Write’, ‘Write paper’,
null, new Date(2015, 0, 9), daysToMilliseconds(3), 25, ‘Research,Outline’],
[‘Cite’, ‘Create bibliography’,
null, new Date(2015, 0, 7), daysToMilliseconds(1), 20, ‘Research’],
[‘Complete’, ‘Hand in paper’,
null, new Date(2015, 0, 10), daysToMilliseconds(1), 0, ‘Cite,Write’],
[‘Outline’, ‘Outline paper’,
null, new Date(2015, 0, 6), daysToMilliseconds(1), 100, ‘Research’]
]);

Using dynamic data from Bubble.

If anyone has some guidance on this, I am hoping Floppy can come to the rescue.

1 Like

Thank you! But of course that’s not the intent. The intent is to give you new tools to do regular Bubble things “better” (more efficiently), as you feel like doing them. But I’m gratified that Floppy is inspiring you!

I will soon get to the Code Action, but in the mean time, think of Code Action as “Run JavaScript” where you can pass data to the code block without having to render that data to text first. You can simply pass it in without conversion and access it there. Ultimately there will be other features (that you would usually have to build a plugin to access) but those aren’t available just yet.

UPDATE TIME AGAIN!: I just pushed version 1.8.0 of Floppy. This version fixes “not ready” errors that could happen when loading certain types of lists in Floppy actions such as “Set RAM List Value”. (Shoutout to @promax7 for discovering a repeatable way to trigger this bug.)

All users should get on this version as it fixes some problems that could happen in many places within Floppy and are rather unpredictable in nature.

While fixing this particular issue, I experimented with many different solutions (and so that’s why you may notice several different DEBUG VERSION - DO NOT USE versions of Floppy). Again, never use one of those as they are always defective in some way.

BONUS BEATS FOR NERDS OR OTHER PLUGIN BUILDERS:

This problem was ultimately quite simple to solve, but it took a lot of thrashing to figure out (1) what/when it was caused and (2) the right way to fix it.

The issue itself manifested as follows: When attempting actions like “Set RAM List” (there are many Actions in Floppy that allow us to read a list and then do something with it and so have list-type input fields), the action would fail and if one were looking at the console, they’d see an error like this:

Now, these errors only started showing up after I had added support for IndexedDB, which required me to refactor quite a bit of my action code to support the asynchronous nature of IndexedDB (and the library I use to support it). And I use async/await type style to do this.

And it was hard to understand why and where they these errors were coming from. This is a Bubble error being thrown inside of my own code. (And I can’t recall ever having seen this error when using more “traditional” synchronous code.)

It turned out that the easiest and most reproducible way to trigger such an error was to attempt something like “Set RAM List Values” to an expression like Current User's Something List (that is the User datatype has some list of Things on it and it is that list that we want to read and use).

And then, looking closely at the error, it seems to be telling us that something is “not ready”. Looking closer, it became clear that the thing that was “not ready” is the “initial data for blah-blah-blah”. And of course, you’ll recognize the blah-blah-blah there as a Bubble unique ID… which turns out to be unique id of the first thing in the list that I was reading.

NOW, I’m big into writing efficient and performant code and, so, I try not to do anything in my code before I’m absolutely sure I need to. So in my standard “getList()” function, I check if the list is already a JavaScript array (which might have happened already in the @keith plugin universe), or if it has no items, and then if it’s still a Bubble “List” object, I .get() its contents.

But typically, I do not bother to inspect what the list items are. If they are Things, I do not bother to .get() any of the fields on them (the individual items) until I absolutely need to. (For example, when I want to publish them as a list of their unique IDs.)

(Another way to say this is that, when I get a List and decompose it into an array of its constituent items, I keep that array of the native Bubble objects. So, if they are numbers, well it’s an array of JS numbers, but if it’s a Thing or an API response object, it’s those funky Bubble objects with their .get(), listProperties(), and __original() methods on them. And I use those methods whenever I need them.)

In regular old synchronous Bubble code, you can do this. However, it seems that, in my asynchronous functions, if such a list that I would later use contained Things that hadn’t already been fetched to the page, the error above would be thrown and the Promise(s) from my own async functions were sort of trapped/wrapped within this error.

Basically (after much futzing around), I realized that Bubble was basically saying, “hey, the minimum info about these things (which turns out to be their unique IDs) is not present in the page and we’re going to reject this Promise.” (Even though, later in the async code, these Things were going to be fetched.)

So, the fix was ultimately quite simple: When I initially read a list via the List’s .get() function, I immediately just .map() over the resulting array with a function that does a .get() on the item’s _id property if the item is a Thing. I do not, in fact, DO anything with the result of that operation, but Bubble does. This causes those Things to become “ready” in the sense that this error message means. (Basically they become available in the page.)

Anyway, if you’re a plugin builder and you ever run into a situation like this, this is Bubble saying, please .get('_id') over these Things before proceeding with whatever code you’re going to be executing here.

I know that in the (quite limited) official plugin docs, it is implied that we should do this when fetching Things, but you don’t have to do it in all cases (and if you don’t have to, why waste the CPU doing it, even if it’s a fairly inexpensive operation, eh?), but I hope this helps someone in future who might run across this vexing situation in their own code! -K-

4 Likes

Hello, I’m a beginner in the bubble, only 1 month of work on it. I’m building an ecommerce and I didn’t know anything about localstorage, I started to study the videos, despite my bad English I managed to build a cart that is stored in localstoragedb.

The big issue is that when adding a product to the cart and removing it without reloading the page, it works normally. If I navigate to the cart that also has a floppy in it and return to the store page the removal doesn’t work.

If I reload the page or if I go to another I can’t get the removal to work.

As I said I’m a beginner, but I would like to know what I’m forgetting to do.

I leave a video where I demonstrate this.

https://watch.screencastify.com/v/qwHn9aKjNiFvQrGtQK5L

When click in trash icon this workflow is running:





Thank you very much and congratulations for the plugin, it’s excellent and I’m sure I’ll change the game of bubble development.

Hug
joce

Hi, @jocenunes, thanks for using Floppy!

So there are a couple of potential issues that I see in your workflows that you provided screenshots of. But first, make sure you’re using the latest “good” version of Floppy, which at present is version 1.8.4.

So, in your “Remove RAM List Values” steps 1 and 2, I think you’re a little confused about how Remove RAM List Values works. The Remove action lets you remove an item by its index OR Remove an item by its value. (But do not do both.)

In your case, you clearly want to remove the items (one from the Carrinho and one from the Quanties), so only use the “Remove Single Index” option. Do not use the “Remove Single Value” option. So what I’m saying is keep the “Remove Single Index” field, but clear the expressions in the “Remove Single Value” field:

ALSO, you don’t need the conditions at the bottom of those Remove steps. So clear those, too. (Make these changes in both step 1 and in step 2.)

And then, you also do not need the “Clear RAM List Values” steps 3 and 4. Just remove them. (Delete steps 3 and 4.)

There are two reasons for this: (1) If you eventually remove all the items from the RAM List, the RAM List is already empty. There is no need to manually clear it, and (2) because in steps 1 and 2, you have the “Store New Value” option set to yes, when the RAM List becomes empty, the stored values will also become empty (and Floppy will automatically remove the keys in storage when this happens).

@jocenunes, if I understand correctly what you are doing: When you first visit your page and your cart is empty, I assume that, if the user adds an item to their cart, you are adding the item to Floppy’s RAM List (Carrinho) and then adding the quantity to Floppy’s RAM List (Quantities), and you are using “store new values” to also push those to storage, yes?

Now, once there are some items in the cart (stored in localStorage), when you reload the page, the Carrinho and Quantities Floppy elements will automatically read those values back. Those values then appear at each Floppy’s List Values (Storage) outputs.

But keep in mind that they DO NOT automatically appear in Floppy’s RAM List. Floppy’s RAM List is a general-purpose state that can be used for any purpose. In your case, you are using the RAM List to represent the state of your cart, so when the page is loaded, if there are cart values in storage, you need to read those back into the RAM List.

So, you should have workflows for each of your Floppy elements that triggers on When Floppy Initialized and then does Set RAM List to that Floppy’s List Values (Storage). So for Carrinho it would look something like:

And you would do the same thing for the Quantities cart. And now, your cart values from storage are back in the RAM List(s).

Wow, what a class. It became much clearer, top. It worked and thanks for the explanations. Undoubtedly the best support.

What you reported makes sense, it was exactly what I needed.

I will take advantage of your kindness and ask you to check the flow to save the data when click in buy





Thank you again

I don’t really understand what you’re doing here. You’re doing a lot of checking for things in weird ways. Have you done the Bubble lessons? It looks like you don’t understand many of the basic concepts very well, though your pages’ visual design is quite nice.