Get & set Item to storage

I seem to struggle with understanding how this connects to the On-device storage. I do see other examples but somehow they are just different enough to throw me off.

IF On Page A, I have field B bound to an appVar_C with value type text (not Boolean since this adds or removes step from what I am trying to do).
Do I go to the logic of that field B in page A and add a Set_Item_to_storage, or is this done at the Global canvas?
Where does all this happen? Im assuming its going to be very similar to the Offline storage video but cant get it.

Set_Item_to_Storage has 2 properties or whatever they are called.

  1. Item Key ( I cannot find a way to connect this to my On-Device data variable, if this is where it goes)
  2. Data to store (Does this hold the value of my appVar_C from field B in page A?)

Get_Item__from_Storage has one property:

  1. Item Key (I’m assuming that the same “Item Key” on Set_Item_to_Storage is the same for here but not sure)

How can I connect all of it together? I’ve tried to merge the info from the Offline storage video and a topic here that says that vid is out of date and another topic that seems to have my problem (although solved by now but vague for my capacity).

Start by copying one of the other examples. Implement it and get it working. By doing this you might gain the familiarity to slowly, step by step, adapt it to your requirements. But do it slowly, in small steps.

Good luck.

I’m sure I could keep trying and learn more in the process and eventually get it. I’m just trying to not get discouraged and I requested the process in a way that it not only helps me but others. I’m in a position where I am more patient with it but in this cases, documentation is alot like this topic, leaves alot to the imagination, like bone with no meat.

Regardless thank you my friend for the advise. I’m sure if I get it, I can post it here to help other.

I think the documentation reflects the reality of building with this product. To deliver an end result you need to be able to find workarounds for all sorts of issues that are not exactly as documented or are totally undocumented.

I´m just trying to suggest that the way forward is to break down as many things as possible into as small parts as you can. Start with a known solution and slowly adapt it.

Its definitely good to always come back to your own posts when you eventually solve something. That helps others for sure.

Good luck.

BTW - I haven´t worked with local storage so have no idea of the solution to your issue.

I totally get it and get what your saying now since just last night I did exactly that. I appreciate your comments.

1 Like

Been trying to figure this for a year maybe…
I’ve wrote 2 posts, countless replies on other threads…still no success :smiling_face_with_tear:

Hello there, Luis,

After writing all the novel below, I re-read your initial question and realized that there is one simple misunderstanding:

If you choose to go with the ‘“on-device storage”’ You do NOT have to use the flow functions “Set item to storage” and “get item from storage”.
All you need is the regular “create record”, “get record” etc functions. But of course as the first step you need to set up the data schema and the resource under the “Data” tab in the navigation.

I have just read your other topics as well. And would have a few questions and suggestions. Hopefully helpful.
First of all, did you manage to get your tables (data that you already have) into the app? I perfectly get your point of not using any REST api-s or online databases, but still I consider that as the easiest way to get your data inside the app. If you have the data in a spreadsheet I would suggest spending a little time on writing a simple Google Script, that would return the data of a spreadsheet as a structured JSON that you could then use with the “set item” flow function.

Until now, I just played around with local storage but the way I see it that the item key is the id or reference to the data that you store in the storage. The data itself is the other key which is a json object or in simple notation an object with key:value pairs. Similar to:

{ "tubing": "external-upset", "diameter": 1.5 }

And so on.

So the flow of storing your data in the persistent storage would be something like this:

  1. Initial loading of the app.
  2. Somehow getting your data from a spreadsheet to list of json objects.
  3. creating unique ids via the GENERATE_UUID formula, or choose a column of your data as reference. These will be your item keys
  4. looping through the list to set each and every row to the storage. (I am not sure wether set item works with lists)
  5. that is it.
    On every later app launch you should already have your data stored in the persistent storage.

At least one would think that is it… But:
You will have to know and feed the id or the item key to the storage to get the data. Then you can set it to a page or app variable and do all your functions as usual. But here comes the big question, how on earth will you know the unique item key for each of your data records if you have more than 1000 data?
Well you could in fact create another item to the storage which would contain all of the item keys.
For that you would use: item key would be like “listOfids” and the json object would be something like this:

{ "keys": ["firstKey", "secondKey", ....]}

So on loading the app you first get this list and then can find the rest.

I wish I could understand your reluctance to utilise at least Firebase. It is so much simpler. You would not need to upload all the data, just your base dataset. But you could even go with simply uploading your item keys. But then why not upload the rest?

Now another question. Will it be an ios/android app or a webapp?
And another one? Why do you wish to utilise the Persistent storage? "on-device storage" would not fit your needs? You could also set that on let’s say first launch and then use it later on. With that you can simply set data variables to the data records, use get collections, etc. etc…

1 Like

Thank you for your attention. Yes I was able to upload my table to an Appvar. I just pasted the data on the Formula bar in the flow function of the Global canvas. Now, I did use retool.com to upload .CSV file and it automatically changes it into JSON. I have not thought aBout doing it the way you suggest it but I wouldn’t mind looking for better ways to do this. One thing. I did paste a lot of data and it will work but it can cause problems depending how you use it and how much you put in there. Your method if I can get it to work may work for this.

As to why I wouldn’t want a to hook up to an API at the moment is because the app will be more of a calculator. There are tons of formulas we use and are all based an tubular standards that don’t change. Many people using it might not have service due to the nature of the work and it cost money. REST API may work later on especially because I’ve learned that working with REST API is the only way I can at the moment get my Data to dynamically update and not With my preferred method.

Example: Say I have a dropdown for tubing that I select as " 2 7/8, 6.5, L-80" I will use many other fields That dynamically bring in the data associated with the selection. Why do I only want one versus many? Is because if I can save the Tubing size and Everything else gets populated. I may use that same number for days or even weeks and months. The fields are than used to calculate capacity, yield strength, Burst, stretch, and many more calculations just of one saved field. Now, that is only the beginning so I truly want more data stored but my brain can only handle figuring out just one field for now.

The screen shots are one for the selection and the other is all dynamic fields and calculations populated based on the dropdown.


Screenshot_20220218-223120_SAP AppGyver Legend

My only issue at the moment is that the formula that searches the data based of the drop down only works with the Rest API method.

Is Persistent storage and on-device storage not the same? Reason I ask is either I’m misunderstanding what you meant or I actually understood what you meant. Persistant data does not give me the on-device storage option which is really what I want and is probably throwing me off based on a post I read here.

My Main function for my app “Android” is for calculations. My world is all about calculations and knowledge about calculations.

I will got through your message once More to see if you actually answered my question on storing data to the device. I may have overlooked it.
Thank you once more.

That is the point I wanted to make. So many things didn’t peice together.

Just this alone makes my day. I went out on a wild goose chase since I read a post that says the video on the “On-device storage” is out of date and leads me astray. I am about to work all night, and read your message just to figure this out.

Thanks

Myhaly_Toth, I think we are getting some where. you gave the steps for persintant storage. We just need the on-device data which has nothing to do with the title. So I will post my question if I’m not able to get them in a more appropriate title. Thanks I hope to see you again here.

Thank you for the detailed description of the reasons. Using retool is a good idea, if you have limited data. But it is perfectly okay for now.

Indeed persistent storage and on device storage are not the same thing. I suggest you focus solely on “on-device storage”.

On the same spot where you defined your rest api, there you can specify the “on-device storage”.

And after you specified your schema just go to your formula where you get your data by the rest api and use a loop to save the data to the “on-device storage”.

Something like this:

The download data from rest api is in fact a “get record collection” flow, I just renamed it under the properties advanced tab, to show the flow.
There is a page variable loop_index, to enable some looping opportunities. The If statement checks wether we still have data to save or not, formula:

pageVars.loop_index<outputs["download data from rest api"].totalCount

Create record creates a new record on the on-device data resource:


Formula:

outputs["download data from rest api"].records[pageVars.loop_index]

This formula will throw a warning, just ignore it. And you should end up with all your data in the local data resource. After that you can use your data as you would a rest api data resource.
Hope it helps.

My friend Mihaly Toth. I realy like your idea of copying Rest API through loop onto on-device storage and I’m sure I can and will benefit from it because it sounds like it may work for me best. I’ve tryed this with no luck.

At this time though. I realize from our discussion that Get and set item to storage is not the same Get record and create record. I’ve gone over and over it and Checked out all info out there some say they have been successful and in others they havent had a reply.

I ran into the topic I mentioned before. Here is the topic

This is different from what me and you were talking about.

My next big step is to get data from Appvar and save it to On-device storage, when my app is reopened, it restored my Appvar Like I never lost it.

Could you help with this.

Let me check it, I’ll need a day for that. Update you soon. :grin:

So when reading the question yesterday I had a first thought that the “Create record” flow function does return a response, which is the created new record, all of its properties. Including the id. So we still can avoid the set item and get item flow.
So if you want to build a dictionary object { "id": tubingrecord.id, "name": tubingrecord.name} you could simply add another “Create record” flow function after the first one. Which would be built based on the outputs["Create record"].response
This then could be in a new data resource that is "list of all tubing record names and ids".
This can be used to populate the dropdown, which would consist of value: record.id, label: record.name.
After selecting an option that can trigger a “Get record” from on-device storage with the dropdown list value as the “id”.

Let’s put it all together:

  • You have a CSV dataset that is converted to JSON by retool.com and it turns that into a REST api that you can use to populate an app variable. I assume that this app variable is a list of objects. Let’s call this tubing_data_from_api.

  • The next step is to loop through the tubing_data_from_api to load that to the on-device-storage. That is described in the reply above, here:
    Get & set Item to storage - #11 by Mihaly_Toth

  • Now let’s build a dictionary object that has 2 properties: tubing name and id of the created record. For this we need a new data resource (let’s call it tubing_dictionary for now) of on-device storage with 3 properties:

    • 1 predefined id property (this will be the id of the dictionary object, we now don’t need to deal with it)
    • 2 tube_name (text, or number or whatever, it is up to you.)
    • 3 id_of_tube_record (this will hold the id that is randomly generated by appgyver on new record creation).
  • Now we need to add into our loop the creation of the dictionary object. So between the Create record and the Set page variable in the earlier reply ad a new Create record. I also suggest renaming them to avoid data conflicts or errors.

    • In the new Create record set the data record input property to custom object and set each property to Output of another node and accordingly from the response of the previous Create record flow. Screenshots below:

  • Now you will have all of your data in the local storage and also a data resource which helps you to choose an item from that huge dataset.

When you want to do the calculations you have a dropdown, right?

  • Now on the page where you have the dropdown on Page mounted event do a Get record collection from the “tubing_dictionary” data resource and set a data variable accordingly.

    • For the dropdown “option list” use this data variable. Be cautious, you cannot simply assign it to the options list, because we named it different from “value” and “label”.
    • So make sure to in binding editor use “mapping” then choose the data variable and assign the id_of_tube_record to “value” and the tube_name to the label. Now you have a dropdown that gives you the chance to select any tubing data record you need.
  • Now to retrieve the selected data record let’s create a page variable selected_recrd_id. Bind this variable to the dropdown “Selected value” property.

  • Exit to the page’s logic canvas, where you have the “Page mounted” event.

    • Add a “Receive event” node. Find the “page variable selected_record_id changed” event in the properties.
    • To this node add a “Get record” flow and as “ID” select the page variable selected_record_id. Assign it to a data variable selected_record_data and there you have it.

Lastly you need to preserve 1 single selection after closing the app and opening it again. If you only work with 1 single data record, I would suggest create a 3rd on-device data resource with a name current tubing record which should have a schema that contains all of the ongoing calculations as well as properties so that you can preserve the calculations, too. This data should be set to update on every “Page will unmount” or at specific events that you will know.

  • On app relaunch on the global canvas after “App launched” event use a “Get record collection” flow from the current tubing record and after that set the selected app variable to the outputs["Get record collection"].records[0] this will feed the first (and yet only) tubing record from that resource to the app variable which you can later use wherever in the app.

The end. At least if I get to answer the whole question in one reply I would be really glad. But of course if anything is unclear reach out.

I think you are misunderstanding me. I am not trying to figure out how to move a database around (at the moment). Data meaning the data I am providing and maKing available. All I really want is to store the choices made by the user.

Another way to make easier sense is the following.

If the app provides a list of say fruit in a drop down. Apples, bananas and oranges. I choose oranges. My choice of oranges is stored in appvars.Fruit_selected. This choice is only available so long the app is not closed.

On the on-device storage I have a database called fruit with one property and has the ability to store data and feed it back to appvars.Fruit_selected when the app is restarted. I know this can be set up on the global canvas or the page where it mounts and starts up.

How do I connect appvars. Fruit_selected to my on-device storage and bring it back when app restarts. I already know get and set item to storage is not for this. Create and get record does not work. What other options do I have. I truly don’t want to use a rest api because the info stored is not delicate but more than anything convinient to have since it will be used regularly. If I wanted to save the choice based on jobs than at this point it would be good to save on rest api incase I lose my phone.

I hope I made more sense. I appreciate all the effort you’ve put in to help me Mihaly. At one point I will come back and use the examples you gave me and go through them because they sound like it may be a good option.

Tha K you so much and sorry for being so ignorant.

I may have a found a problem with the viewers. Ive been using the SAP AppGyver Legend instead of the Preview version. Seemed Good but after watching an excellent video called "Offline favorites list Demo in appgyver"and doing it to the T. I could not get it to work, I remembered I had 2 viewers. The legend does not preview stored data on devise and the Preview version does. I will look at all this again.

If you wish to build an app on the freshest runtime do make it work with the SAP Preview app. As the other is runtime 2.6.4 or something similar and the SAP Preview is 3.4.x…

It turns out Get and set did not work for me as my friend [Mihaly_Toth] explained. What I was looking for was to select a value and have it stay even on app restart. I have figured it out & will post it on a Topic that makes more sense for others to find in case they look for it. Topic will be “Save record on-device”.

Thank you whom helped me along.

2 Likes