Problem with tableView when pulling JSON-data into a Lua array

Hi,

I started coding with Lua and Corona yesterday and have run in to a problem with tables. I am using one of the examples from the Ansca blog (Gilbert’s Coffee application), except that I am loading my data from a database. I use a server-side script to return JSON-formatted results, which I then gather using a HTTP request, like this:

responseJSon = http.request("http://www.mysite.com/getData.asp")  
jSon\_result = json.decode(responseJSon)  

I then set up an array and read the JSON data in to it. I have “name”, “unitprice” and “image” fields in my sample JSON data, which I can access as simple array elements in Lua:

...  
local data = {}  
for i=1, jSon\_result.recordcount do  
 data[i] = {}  
 data[i].title = jSon\_result.data.name[i]  
 data[i].subtitle = jSon\_result.data.unitprice[i]  
  
 local path = system.pathForFile(jSon\_result.data.image1[i], system.DocumentsDirectory)  
 thisFile = io.open(path, "w+b")  
 imgUrl = http.request {  
 url = "http://www.mysite.com/images/" .. jSon\_result.data.image1[i],   
 sink = ltn12.sink.file(thisFile),  
 }  
 data[i].image = jSon\_result.data.image1[i]  
 table.insert(data, data[i])  
end  

As you can see, I loop over the JSON records, the total of which is kept in the “recordcount” variable. I also display the image, the URL of which is passed in my data as field “image”. All straightforward stuff.

Finally, I output the data using a tableView as follows:

myList = tableView.newList {  
 data=data,   
 default="listItemBg.png",  
 top=topBoundary,  
 bottom=bottomBoundary,  
 callback = function( row )  
 local g = display.newGroup()  
 local img = display.newImage(row.image, system.DocumentsDirectory, 0, 0)  
 g:insert(img)  
 img:scale(0.4, 0.4)  
 img.x = 150  
 img.y = 44  
  
 local title = display.newText(row.title, 0, 0, "georgia", 10)  
 title:setReferencePoint(display.CenterLeftReferencePoint)  
 title:setTextColor(0, 0, 0)  
 g:insert(title)  
 title.x = 6  
 title.y = 10  
  
 local subtitle = display.newText(row.subtitle, 0, 0, "georgia", 10)  
 subtitle:setReferencePoint(display.CenterLeftReferencePoint)  
 subtitle:setTextColor(80,80,80)  
 g:insert(subtitle)  
 subtitle.x = 6  
 subtitle.y = 25  
 return g  
 end   
}  

This all works and renders fine in Corona, but the wierd issue I’m having is that when I preview my application, the final row of data is always duplicated. So I get two identical final table rows, with duplicate image and other data.

I have checked the JSON data and all is ok there. The issue seems to be happening in the table.insert() stage since that will run 11 times if there are 10 records, or 6 times if there are 5 records, and so forth. By putting in print() statements to debug, the tableView.newList callback code seems to always get called one more time than is necessary (but the loop iterates correctly.) The loop structure is correct, it starts at 1 and goes up to the number of items in “recordset” (both correctly verified when debugging.)

Is this a bug in Corona, or Lua? Can anyone shed some light? I’ve used tableView.lua v1.4 and v1.8 and also tableViewXL.lua and all do the same thing.

I would also like to know if there is a better way to get JSON data directly into a tableView without using the intermediate array.

Help greatly appreciated. [import]uid: 116752 topic_id: 20231 reply_id: 320231[/import]

Try Putting -1 at the end of your record count for loop [import]uid: 84637 topic_id: 20231 reply_id: 79142[/import]

Danny, thanks for the reply. I thought of that too, and tried it, but no luck. I changed the code to:

for i=1, jSon\_result.recordcount-1 do  

and the same issue occurs - always duplication of the last item. Even if there is 1 item in the array/JSON data, still 2 items appear.

The -1 should not be needed because the loop index starts from 1, and not 0.

Stumped on this :frowning: [import]uid: 116752 topic_id: 20231 reply_id: 79147[/import]

Im typing this from my phone so i cant quote the code but i have another idea.

In the for loop where you are buliding your table view, pass -1 to that and that might get rid of the dupe

If it doesnt work i can help better when im back home (just at the dentist) [import]uid: 84637 topic_id: 20231 reply_id: 79154[/import]

Tried -1 just about everywhere, no joy. Thing is that the data is correct, the issue seems to be the creation of the tableView with the array. If the array is correct, the table should be too.

Appreciate your reply btw. [import]uid: 116752 topic_id: 20231 reply_id: 79155[/import]

Heya, I’m back home now.

Ok, that’s a shame… time for step 2.

Could you also post up the code where you are creating your tableView please? Also are you using the widget library or the standalone tableView library from the sample code? [import]uid: 84637 topic_id: 20231 reply_id: 79161[/import]

Hi. The code is actually already shown above. I am using the tableView.lua include:

...  
local tableView = require("tableView")  
...  
myList = tableView.newList() {  
 ...  
}  

So, the table should be populated from the array. Bug in tableView.lua perhaps? [import]uid: 116752 topic_id: 20231 reply_id: 79164[/import]

Maybe so… I can’t investigate it just yet as I just got a new iMac and am in the process of waiting for lion to download (can’t believe it didn’t come pre-installed) so i have none of my coding programs or Corona for that matter installed yet.

In the mean time, fancy trying the tableView code from the widget library to see if the same issue occurs there? (the implementation is very similar so it won’t require much code change) [import]uid: 84637 topic_id: 20231 reply_id: 79172[/import]

I am not a subscriber, so can I use widgets? If so, where do I download from?

Thanks. [import]uid: 116752 topic_id: 20231 reply_id: 79174[/import]

It’s available in the latest current public release.

Should be under coronaSDK > sample code > interface > widget or coronaSDK > sample code > widget

If memory serves me correctly

And the api page : http://developer.anscamobile.com/content/widget [import]uid: 84637 topic_id: 20231 reply_id: 79177[/import]

I will try and get back to you. A fix is to do this just before the end of the loop:

for i=1, jSon\_result.recordcount do  
 ...  
 if i \< jSon\_result.recordcount then  
 table.insert(data, data[i])  
 end  
end  

You’d think the main loop could do that though? Do you have an example of a for loop that loops “from 1 to < limit” ? [import]uid: 116752 topic_id: 20231 reply_id: 79178[/import]

I think it might work if you use:
[lua]for i=1, #jSon_result do[/lua] [import]uid: 10048 topic_id: 20231 reply_id: 79181[/import]

Hi. That value returns 0, so no result at all :frowning: [import]uid: 116752 topic_id: 20231 reply_id: 79185[/import]

Try this then:
[lua]local data = {}
for i=1, jSon_result.recordcount do
data[i] = {}
data[i].title = jSon_result.data.name[i]
data[i].subtitle = jSon_result.data.unitprice[i]

local path = system.pathForFile(jSon_result.data.image1[i], system.DocumentsDirectory)
thisFile = io.open(path, “w+b”)
imgUrl = http.request {
url = “http://www.mysite.com/images/” … jSon_result.data.image1[i],
sink = ltn12.sink.file(thisFile),
}
data[i].image = jSon_result.data.image1[i]
– table.insert(data, data[i]) --> This might be causing the duplicate data.
end[/lua] [import]uid: 10048 topic_id: 20231 reply_id: 79188[/import]

Well done, that was it. Not knowing Lua, I assumed the insert() was needed. Thanks again. [import]uid: 116752 topic_id: 20231 reply_id: 79191[/import]

@arbt: great spot, can’t believe I missed that :slight_smile: [import]uid: 84637 topic_id: 20231 reply_id: 79198[/import]

No problem. You might find interesting the following link:
http://lua-users.org/wiki/TablesTutorial [import]uid: 10048 topic_id: 20231 reply_id: 79200[/import]

I got a similar Problem but I made it a bit different but it does´t work. Could anybody help it is very urgent.

[lua]local data{}
local responseJSon

local function networkListener( event )
if ( event.isError ) then
print( “Network error!”)

else
print ( "RESPONSE: " … event.response )
jSon_result = json.decode(event.response)

for i=366, (366+jSon_result.entrycount) do
data[i] = {}
data[i].title = jSon_result.entry_366.name
data[i].subtitle = jSon_result.entry_366.street
end
end
end
responseJSon = network.request( “http://…”, “GET”, networkListener )[/lua]

in my Response i get something like this:

RESPONSE: {“result”:200,“message”:“Success”,“entry_366”:{“id”:“366”,“name”:“Testeintrag Abnahme”,“street”:“Keine Strasse 20”,“zip”:“22275”,“city”:“Hamburg”},“entry_367”:{“id”:“366”,“name”:“Testeintrag Abnahme”,“street”:“Keine Strasse 20”,“zip”:“22275”,“city”:“Hamburg”},“entry_366”:{“id”:“368”,“name”:“Testeintrag Abnahme”,“street”:“Keine Strasse 20”,“zip”:“22275”,“city”:“Hamburg”}“entrycount”:4}
the tableview script is same as your example

[import]uid: 149464 topic_id: 20231 reply_id: 111719[/import]