JSON Database question.

I’ve come up on h** opefully** the last problem I face with this project and I need some help. I have a JSON databse that looks like this called ZIPDATABASE.json;

[{ "Zipcode": 98807, "City": "WENATCHEE", "State": "WA" }, { "Zipcode": 98811, "City": "ARDENVOIR", "State": "WA" }, { "Zipcode": 98812, "City": "BREWSTER", "State": "WA" },]

To call back to it I use the following code;

local fr = io.open(system.pathForFile("ZIPDATABASE.json")) local data = fr:read('\*a') fr:close() data = json.decode(data) local dbtbl = {} local record for i=1, #data do record = data[i] dbtbl[record["Zipcode"]] = { city = record.City, state = record.State } end

Everything works great except for one problem.

I’m trying to get it so when someone types in a text field the zip code for example “98811” after the phase has ended the state and city are auto-filled into the other fields. so currently the code looks like this;

local function zipListener( event ) if ( "began" == event.phase ) then elseif ( "editing" == event.phase ) then zipString = event.target.text elseif ( event.phase == "ended" or event.phase == "submitted" ) then zipString = event.target.text stateString = dbtbl[zipString].state cityString = dbtbl[zipString].city cityField.text = dbtbl[zipString].city stateField.text = dbtbl[zipString].state native.setKeyboardFocus( nil ) end end -- Create text field zipField = native.newTextField( 150, 150, 140, 15 ) zipField.isEditable = true zipField:addEventListener( "userInput", zipListener ) zipField.x = display.contentCenterX - 105 zipField.y = display.contentCenterY + 115 sceneGroup:insert(zipField)

This however gives me an error "attempt to index field ‘?’ (a nil value). Now if I were to replace the dbtbl[zipString].state with an actual zipcode for example dbtbl[98811].state then it works no problem. I cant, however, write separate code for every zipcode I’m using (which is the entire USA).

Is there a way for me to substitute the “98811” in dbtbl[98811].state with the string the user types out so that whatever zip they type in will show the corresponding state/city?

Thank you!!

-B

you are using zipString as a record number.

that wont work but it is easily fixed.

exchange:

zipString = event.target.text

for:

zipString = tonumber(event.target.text)

obviously this will only work as long as you are sure the content of zipString is in fact a number.

That worked perfectly! I added in zipField.inputType = “number” to make sure it always is a number. Thank you!!!

It looks like the only issue im facing now is if the number is not one within the database. Is there a way to have it where if the number isnt found it just does nothing rather then crashing?

Yeah thats easy, you will have to validate it

Something like this after:

zipString = tonumber(event.target.text)

add:

if data[zipString] then

   – execute your code

else

   – tell user the code is invalid

end

A small explanation, if you didnt know it, 

if data[zipString] then

is equal to writing

if data[zipString]~=nil then

which practically validates it.

I’m not at the PC all the time so sometimes it cant take some time before I reply, but I usually reply.

Hope that helps.

Thank you!! It worked. It still gives me an error if I type in the zip wrong a bunch of times but I dont think that will be an issue.

I really appreciate all your help!

It shouldnt do that an you always need to code for the worst events no matter how unlikely.

It would help if i could see that error message in full

you are using zipString as a record number.

that wont work but it is easily fixed.

exchange:

zipString = event.target.text

for:

zipString = tonumber(event.target.text)

obviously this will only work as long as you are sure the content of zipString is in fact a number.

That worked perfectly! I added in zipField.inputType = “number” to make sure it always is a number. Thank you!!!

It looks like the only issue im facing now is if the number is not one within the database. Is there a way to have it where if the number isnt found it just does nothing rather then crashing?

Yeah thats easy, you will have to validate it

Something like this after:

zipString = tonumber(event.target.text)

add:

if data[zipString] then

   – execute your code

else

   – tell user the code is invalid

end

A small explanation, if you didnt know it, 

if data[zipString] then

is equal to writing

if data[zipString]~=nil then

which practically validates it.

I’m not at the PC all the time so sometimes it cant take some time before I reply, but I usually reply.

Hope that helps.

Thank you!! It worked. It still gives me an error if I type in the zip wrong a bunch of times but I dont think that will be an issue.

I really appreciate all your help!

It shouldnt do that an you always need to code for the worst events no matter how unlikely.

It would help if i could see that error message in full