Setting Client-Side storage with output from Rest-API

Thank you Tomi, that seems to have fixed (small schema mismatch), i have now moved the data variable it onto the global canvas it is populating, but now i cant access the data from the pages. i thought the obejcts on the global canvas are accessible from all pages?

Data variables aren’t available on all pages even if you define those in global canvas. Those are closer to page variables in that way (and just get the schema from data side).

If you want to work on the same data on multiple pages and prefer to fetch the data on global canvas, one way to work would be to add the fetched record collection to app variable instead of directly to data variable. Then you could add data variables to individual pages, but instead of fetching the record collection / single record you could just set the data variable from the app variable. If you do it like this, you need to add some check to validate that the app variable containing the data is actually fetched/initialized before you try to add it to the data variable. (Of course you can work directly with the app variable also, but sometimes I prefer to keep the app variable unchanged until pushing the data to backend or storage for real)

Thank you Tomi, managed to get it working by redefining the variable as an app variable with the same schema.

Just not sure this will persist after closing the app. as the data variables are pretty much useless if they cant be used globally, so is the client side storage, it seems to me that this is just a global schema reference, which cant be used and or copied and not an actual data store. for our users they can be disconnected from the internet for 12 to 24 hours before being back in cell range to sync the jobs they have completed and fetch new ones. we need to be able to store photos and data etc.

In that case best way to keep the data saved would be by storing it on device with Set item to storage flow function. Use that whenever necessary and when the user restarts the app use ** Get item from storage** to initialize your variable values. And of course, upload the data to backend when possible and needed.

just noticed getting storage items from the global canvas on load, does not set app variables in time for the page to check the value fetched from the device. i have tried a delay on the page doing the check but it does not work.

Do you mean it didn’t work no matter how long delay you added there? If so, try using the debugger to see if the app variable is ever really initialised properly, i.e. if the configuration of Set/Get item to/from storage works properly.

But if long enough delay works, there still can be race conditions between initialisation of the page and global canvas in this case.

To tackle this, I’d use If condition on the page to check if the app variable (which is set on global canvas) has the value initialised or not. If the value is not set yet, use Delay (e.g. 10ms) and loop back to the If condition to check again. If the app variable has the value initialised, you can just set the variable values you need on the page.

This way the app variable would be certainly initialised when you try to use its value, and you wouldn’t need to add a delay that you’d hope would be long enough on all devices in all situations.

i have not checked if it doesn’t ever get set, i set a delay of 1000ms and it still didnt do it, i have since moved the check onto the page and this has sorted it for now, but i will try play around with it and use some of your suggestions above, as i have a lot more data to store and will need this resolved.

i will post my findings here when i have something robust.

Hello @Andrew_Scott and @Tomi_Laakso,

Does setting the client-side storage variable to retrieve data from the remote data source/API get stored persistently on the local device without having to use the “Set item to storage” or the “Create record” node?

I have tried using the client-side storage variable to get record collection from a remote data source which worked but the data wasn’t saved locally on the device. Appreciate any insight.

Thanks

Yes, you have to implicitly save the item. I’d suggest you to use Replace client-side record collection flow function whenever needed (after getting the real data form backend and when you have local changes that you want to sync later to the backend).

Hello @Tomi_Laakso,
I have attached the “Replace Client-Side Record Collection” to the output of the
“get record collection” of the backend database. But i couldn’t get it to work.

The output of “Replace Client-Side Record Collection” flow function defaults to an Array of
records. but so far, i’ve been unable to map the BackendDB record collection to that of the
“Replace Client-Side Record Collection”. please assist.

Thanks

Okay, so instead of the empty Records array you have to choose Output value of another node and from there select Get record collection / Collection of records.

If Composer doesn’t allow you to select this option, it most likely due to differences in TESTBackendDB and TESTlocalStore schemas. In that case, check that you have identical schemas for the two resources, and then try again

Hi Tomi, to this comment about saving the data locally and persisting, “you have to implicitly save the item” by this you mean use the “set item to storage” flow object correct? because using the data variables does not persist if you close the app correct?

Yep, data variables don’t persist if you close the app. So Set item to storage is the way to go. And then Get item from storage when you need the values again.

(Or Replace client-side record collection in cases with record collections and defined Client-side storage data as you can see above)

Hello @Tomi_Laakso,
The two schemas are the same yet Composer doesn’t give me the option to select the “Get Record Collections”. Composer greys/disables it hence unable to select it.

When the output of the “Replace Client-Side Record Collection” is forced using formulas ie “outputs[“Get record collection”].records”, the formular editor displays this validation error message “Array items are incompatible”. Still no joy.

Thanks

This situation should only come up if there’s differences in the schemas. Even tiny differences are enough (e.g. typos, different value types).

But I can also take a look at your app if that’s ok for you. Could you then give me the id of your app? You can find it in the app URL, it’s the number after applications/

Hello @Tomi_Laakso,
App ID is 100009.

Many Thanks

Hello @Tomi_Laakso,
Did you get any chance to look at the App ?

Thanks

Hello @Tomi_Laakso,
Checking in again if you’ve had a look at the “Replace Client-Side Record Collection

Thanks

Hi,

I took a look at the app, and seeing it was for testing purposes, hooked up a working example with new resources LocalResource and RemoteResource.

I’m 99% sure the issue is with your resources not having an id property. A client-side resource always has to have an id as the underlying implementation requires it. We recently changed (fixed?) it in Composer so that new client-side resources will always have it included, and you cannot delete it. You could do that previously, but it’d still secretly have it, and your types simply would not match. Looks like your resource was created and modified before that fix went live.

Note that this means whatever you put into the client-side resource will have to have an id. If your remote resource does not have one, you can use a formula to map an id for each record when setting it to client-side storage. Something along the lines of: MAP<item>(data var / output of get collection, SET_KEY(item, 'id', item.code)).

Hello @Pekka_Aaltonen,

You’re absolutely right on the dollar. It indeed does require an ID to function correctly.
Many thanks for the assistance. AppGyver Rocks !!!

Cheers

1 Like