Rob Miracle's json saving method

at the end of utility.lua you need the line:

    return M

Just jumping in here a few months late, but I have been running code to do similar things, but have found a problem that I cant see the cause. Probably not easy to decide any suggestions or help, from this description, but here goes…

I have been downloading a text file and writing it to a file with no problems.

    params.progress = “download”

    params.response = { filename = “results.txt”,baseDirectory = system.DocumentsDirectory}

    network.request( _G.set.Url, “GET”, networkListener,  params )

Even detecting network errors and falling back to prior saved file data ok. I then read back the file, one line at a time to parse each line for the apps use and then build a table for showing later in several scene treeviews, which is also working fine.

There are many scenes and each scene picks up the table ok, which is held in a module locally and the module returns the table name at the end of the module  locals.ResultsReadList=ResultsReadList return locals.

This is reference in each scene via  local Results = require “libname.modulename” and #Results.ResultsReadList

The download file is getting rather large so to avoid taking up  to much mobile hard storage I thought I would modify the content and truncate the string in each line to 50 chars, and then write back out the table as a Json file created for use in the treeviews. TableFile.save(ResultsReadList, “Results.json”,system.DocumentsDirectory) (a general sub written)

This also works fine while the wifi connection is working. So I was very pleased and ready to write code to delete the ‘results.txt file’ to save space.

BUT, now when I test without the wifi on, the application scenes fail to find the table data content. #Results.ResultsReadList shows zero. Yet when wifi is connected each scene sees #Results.ResultsReadList=52

Debugs shows that the module checks the internet and if not active reads the last created JSON file into the table ok (as it  does also when the wifi is on).

Print statements show the table has been loaded and has content in the module (as it does with wifi connected) and the table size #ResultsReadList =52 and a loop prints out each table entry (as it does with wfi connected). So it is definitely work either way in the module regardless of wifi.

When the scenes are loaded and the wifi is off they  find the #ResultsReadList =0 , no content. Run with wifi on and they all work fine going the exactly the same load table json code. The file has data (new or prior) in all  wifi tests  on or off and the module level.

I cannot see where the  ResultsReadList table gets deleted (if at all). The only difference is that with wifi on, extra IF code writes out the Json file. That is the only difference I can see. The table is initially created then  by  ResultsReadList[#ResultsReadList+1] =     string.sub(readResultLine,1,50) in a loop (but this is a red-herring I think)

I have even deleted the ResultsReadList={} after being saved  on the Json file(or when it is not saved due to no download) in all cases. The table is only ever created via the Json load table in all cases. Some how the table is loosing scope or being deleted between module code and scene change but why I cannot see or understand.

Alec

Can you post some code?

Thanks Rob,

I will need to create  a test project try that and paste if still not working because project too many scenes and modules…

Code now submitted/uploaded via zip files[original content removed from here]

Hi Rob,

A  code zip file [subset of my app-] has been upload along with log output for your attention.

(Case 27809) [For the Attention of Rob Miracle] This app seems to be loosing the ‘require   link’


I hope this process is acceptable to you and Corona team, as there was
far too much to paste here. So it has been submitted via the Bug Report
system for your attention.

Thanks

Alec

Rob,

I have now changed the code back here-not in the uploaded code]  to not use a required module  variable, but place the variable in my Globals section .

The app works if using a global!

very interesting…

I hope this does not start a debate of globals vs modules.

But it does show me that I dont think it is really my code (is it?)

I have the bug report, and I have the app up in the simulator.  How do I make it fail?

Rob

Ok, Good.

I use outlaw, to test. Place in outlaw and just run the app making sure the wifi is connected. This will download and create a txt file in tempdirectory and create a json file in DocumentsDirectory.

On start up there will be a flash screen and a small bar goes across the top and a download icon appears indicating down loaded ok.

You can now either wait the 10 seconds for the screen to go or click the [tlc] icon to move on.

A 'dashboard’scene tree view appears. Click on the  top entry and the ‘swing’ scene treeview list should show latest-uk results.

Close down the app. Turn off wifi connection and re-run app.

This time the flash screen will not show the progress bar or the download icon.

Press the [tlc] icon to move on. The code should now detect no down load and read the prior json file and show the treeview  but the results are empty(debug prints in outlaw window). App will crash if you click return…

But this time you will see that ResultsReadList is 0 after the json file has been read [ResultsReadList=52]. the treeview cannot find any data because ResultsReadList has gone empty.i.e lost reference/out of scope what ever…

(There is no code in your pack for the situation to first run the app with no wifi or fallback file-it will crash if you run this way)

_Overcome the problem by making _ResultsReadList as a global rather than the advised method of placing in a module as is the case you have.

Thanks

Alec

Okay, here’s what I can tell you.  I ran the app with WiFi on.  I made a copy of lottoResults.json to another file.  I turned off my WiFi and reloaded the app. I never got any errors, but I can see where:  #LotteryResults.ResultsReadList    0.

I looked in the Documents directory and lottoResults.json was still there and looked complete.  I turned WiFi back on, reloaded it and let it download the data again and ran an diff on the two files.  They are identical.  So the WiFi being off has no impact on the file or it’s contents. 

That said, a couple of things to note that may help you.

1.  I see you are calling storyboard.removeScene(CurrentScene).  I don’t advise this.  How can you remove the scene that is showing?  It’s best to remove a scene just before you goto it if you want to clear things.

2.  If the scene’s are not getting removed correctly, then your code at the top of each module is not going to get executed each time the scene loads.  This could be creating issues for you.

3.  I would recommend putting some debug statements in your _.load() function in your table save routines to see what’s going on when  you try to read the data.  Is “contents” nil?  what you expect.   Perhaps dump the myTable table when you’re done with a print_r type function to see if you’re getting the data back correctly there.    You could even try loading the table at the beginning of main.lua to try and isolate the rest of the code or see if it’s a problem with your loading data.

Rob

Rob,

Thanks for the time to go through the logic- .

1.The storyboard.removeScene(CurrentScene) is at the end (well should have been) of the scene . The idea being to reduce memory needs as much as possible by ‘killing’ scenes as soon as possible when not required(being old school working in 256k), and as you noted, to refresh and clean out variables in one go. Otherwise there would be  many scenes sitting around doing nothing.

(I had tried this [storyboard.purgeOnSceneChange = true] in the past but did not seem to do what I expected -ie refresh all variables with local scope  to the scene.

I have not met any problems in load of tests for weeks/months with this method. It was only when checking various users actions (wifi on /off etc) and taking different  code routes that this situation arose-but take the point as very valid.

To ensure scenes are not sitting around I will remove them in the ‘dashboard’ and ‘setting’ scenes, in the new  and different scene and reload again when required. Reloading the scenes as new is no impact here, being a sort of business app rather than a game.

  1. Agreed- my point (1) hopefully will resolve.

  2. I have had no problems with the json files(until now)  and I am confident the cause is the ‘link’ to the required module is being corrupted by the storyboard.removeScene(CurrentScene)…

So this is closed here as … User Error.

Alec

Purging scene’s just removes the scene’s view (its display group).  The Lua module is still “required” at that point.  Purging does not do an “unrequire”.  The removeScene() does an unrequire and with Lua the code in a scene is only executed once when it’s first loaded. 

Lets hope this solves your problem.

H’mm, thanks for continued interest in this Rob…

I will have come back to this after more tests, when I have a moment… but for now I have removed the un-recommended storyboard.removeScene(CurrentScene). Also commented out storyboard.purgeOnSceneChange = true.

I understand from your comment that the unrequire is done by removeScene().

However, the code is still loosing the require association even with all this code removed.

So to move on with my app I have made the readlist table a global and all working as designed (?).Maybe more on this later.

Just as an aside….

I had felt really confident with storyboard and all my scenes with many newTableViews all working very nicely; until, I try testing ‘error’ cases, and user fast button clicking etc. I then discover the a-synchronicity of scenes where (unexpectedly) some scenes have not yet ended while others are entered. Also clicking where a button was and will be again, but not yet drawn (fast multiclicks) creates some interesting failures…so still a lot to understand of the Corona UI implementations…

You probably should still be removing the scene. I just recommend doing it **before** you goto it:

storyboard.removeScene(“somescene”)

storyboard.gotoScene(“somescene”, options)

Rob

Hello Master,

Im completely newbie on Corona but… I make a feew progress on the last days and now I´m really enjoying :slight_smile:

I´m trying to use your Loadsave and when I do it, the savetable functions seems to be working perfect, but the loadone… tells me that cannot find the file (attempted to load a table from an invalid location)… quite sure that I´m doing something wrong… can you help me, please?

Thanks a lot!

Can you post your code where you are trying to save the file and where you are trying to load the file?

Thanks

Rob

Wuau… that was a quick reply! Thanks a lot!

Well… probably is that I´m not understanding something :frowning:

mySettings = {}

mySettings.ToggleMusic = 1

mySettings.ToggleSound = 1

mySettings.ToggleNotifications = 0

loadsave.saveTable(mySettings, “mySettings.json”)

With this I save the data and is created on a Documents folder inseide the sandbox (emulator).

After is created (works perfect), I just replace the saveTable for the loadTable thinking that is going to load the data from there.

The emulator is giving me the error about the location.

Please, let me know if you need somthing else… and thanks a lot for your support, help and the functions :slight_smile:

Can you post the loading code?   What errors are you getting?

Rob

Ok, sorry, maybe is difficult to me to explain :slight_smile:

I have your loadsave.lua as downloaded from the github.

In my main.lua I have:

mySettings = {}

mySettings.ToggleMusic = 1

mySettings.ToggleSound = 1

mySettings.ToggleNotifications = 0

 

loadsave.saveTable(mySettings, “mySettings.json”)

 

I execute the program and works perfect and creates the JSON file.

 

After that I modify the code changing like this: 

 

mySettings = {}

loadsave.loadTable(mySettings, “mySettings.json”)

Expecting that variable MySettings is going to be filled with the JSON data.

The problem is that give me the error below on loadsave.loadTable(mySettings, “mySettings.json”) :

“Attempted to load a table from an invalid location”

No rush, I will no be able to reply you until tomorrow night (sleep and work :))

Have a nice day and thanks a lot again :slight_smile:

mySettings = loadsave.loadTable(“mySettings.json”)

Rob

There is not enough words to say how I feel… works like a charm!

Thanks a lot… really :slight_smile: