Storing a JSON object
-
wrote on 7 Dec 2016, 18:56 last edited by
Hi,
I am stuck with my JSON object. I am able to get a JSON response from a server, see the code below. But I am unable to work with the retuned JSON object.
function get(url, task, id) { var xhr = new XMLHttpRequest(); xhr.open("GET",url,true); xhr.onreadystatechange = function(){ if ( xhr.readyState == xhr.DONE){ if ( xhr.status == 200){ var jsonObject = JSON.parse(xhr.responseText) if(task === "service"){ console.log(JSON.stringify(jsonObject)) // correct output of the object return jsonObject } } } } xhr.send(); }
In a QML file I try to put the object in a property:
property var event: Parser.get(accountModel.get(0).urlRead + "/api/app/v1/details.php?id="+ eventModel.get(eventModel.activeEvent).i +"&sids="+accountModel.get(0).sids, "service", 0) Label { text: eventPage.event["t"] } // [W] unknown:57 - file:///.../EventPage.qml:57: TypeError: Cannot read property 't' of undefined
The property event is always undefined. Is it not possible to put a JSON object in a property or am I just doing something wrong?
-
Hi,
I am stuck with my JSON object. I am able to get a JSON response from a server, see the code below. But I am unable to work with the retuned JSON object.
function get(url, task, id) { var xhr = new XMLHttpRequest(); xhr.open("GET",url,true); xhr.onreadystatechange = function(){ if ( xhr.readyState == xhr.DONE){ if ( xhr.status == 200){ var jsonObject = JSON.parse(xhr.responseText) if(task === "service"){ console.log(JSON.stringify(jsonObject)) // correct output of the object return jsonObject } } } } xhr.send(); }
In a QML file I try to put the object in a property:
property var event: Parser.get(accountModel.get(0).urlRead + "/api/app/v1/details.php?id="+ eventModel.get(eventModel.activeEvent).i +"&sids="+accountModel.get(0).sids, "service", 0) Label { text: eventPage.event["t"] } // [W] unknown:57 - file:///.../EventPage.qml:57: TypeError: Cannot read property 't' of undefined
The property event is always undefined. Is it not possible to put a JSON object in a property or am I just doing something wrong?
wrote on 7 Dec 2016, 20:20 last edited byThis post is deleted! -
Hi,
I am stuck with my JSON object. I am able to get a JSON response from a server, see the code below. But I am unable to work with the retuned JSON object.
function get(url, task, id) { var xhr = new XMLHttpRequest(); xhr.open("GET",url,true); xhr.onreadystatechange = function(){ if ( xhr.readyState == xhr.DONE){ if ( xhr.status == 200){ var jsonObject = JSON.parse(xhr.responseText) if(task === "service"){ console.log(JSON.stringify(jsonObject)) // correct output of the object return jsonObject } } } } xhr.send(); }
In a QML file I try to put the object in a property:
property var event: Parser.get(accountModel.get(0).urlRead + "/api/app/v1/details.php?id="+ eventModel.get(eventModel.activeEvent).i +"&sids="+accountModel.get(0).sids, "service", 0) Label { text: eventPage.event["t"] } // [W] unknown:57 - file:///.../EventPage.qml:57: TypeError: Cannot read property 't' of undefined
The property event is always undefined. Is it not possible to put a JSON object in a property or am I just doing something wrong?
-
@Sikarjan
Result of get() function is undefined because you do not return anything from it.
You do return event value, but in a callback function. You should update your property value directly from callback. -
Thanks for looking at my question but I do not understand your answer. Why is return jsonObject not returning anything?
wrote on 7 Dec 2016, 20:47 last edited by@Sikarjan
Okey, let's try another way.
Fix your code like this... xhr.send(); return { t: "yep" }; }
This is return from your function get().
Where you try to return it is another function, called from another place, with processing it's return value at place, where it has called asynchronously.
-
wrote on 7 Dec 2016, 23:22 last edited by
ha i didn't even notice the lambda function() declaration due to the lack of indentation there :D But yes, the get(...) function you wrote doesn't have a return statement, therefore you aren't getting anything from it.
-
wrote on 7 Dec 2016, 23:35 last edited by
Also a thought: Since XMLHttpRequest will execute the query most likely asynchronously, you won't get your reply with JSON when the get() function finishes. Use your callback function to set the property event there(this means that the property also must be visible from there), like this:
function get(url, task, id, eventHolder) { var xhr = new XMLHttpRequest(); xhr.open("GET",url,true); xhr.onreadystatechange = function(){ if ( xhr.readyState == xhr.DONE){ if ( xhr.status == 200){ var jsonObject = JSON.parse(xhr.responseText) if(task === "service"){ console.log(JSON.stringify(jsonObject)) // correct output of the object //return jsonObject eventHolder.event = jsonObject } } } } xhr.send(); }
Item { id: myItem property var event Component.onCompleted: { Parser.get(accountModel.get(0).urlRead + "/api/app/v1/details.php?id="+ eventModel.get(eventModel.activeEvent).i +"&sids="+accountModel.get(0).sids, "service", 0, myItem) } }
-
wrote on 8 Dec 2016, 16:32 last edited by
You can use jsonCache.com or myjson.com to test you function. They are both easy to use and very usefull.
Regards,
NNCU -
wrote on 8 Dec 2016, 17:48 last edited by
Thanks for all your suggestions. I still do not 100 % the problem but I solved it similar to Jagh's suggestion. In stead of the line
eventHolder.event = jsonObject
I assign the jsonObject to a parameter in my main.qml. This variable is visible in all other pages of my program.
It still baffles me that I can assign the object to a variable but not return it. I see that XMLHttpRequest works asynchronously and that get will be finished first but the rest I do not understand.
-
Thanks for all your suggestions. I still do not 100 % the problem but I solved it similar to Jagh's suggestion. In stead of the line
eventHolder.event = jsonObject
I assign the jsonObject to a parameter in my main.qml. This variable is visible in all other pages of my program.
It still baffles me that I can assign the object to a variable but not return it. I see that XMLHttpRequest works asynchronously and that get will be finished first but the rest I do not understand.
wrote on 8 Dec 2016, 18:29 last edited by@Sikarjan the key problem i think here is to understand, what happens when functions are treated as first class citizens. C++ does this too(with lambda syntax for instance), but it is way more common to see in JavaScript, a language that has functional roots.
In this example, we actually have 2 functions: one that is called get(url, task, id), and one that doesn't have a name(lambda function), its declaration begins with function(){... on line 4. To see it better, you could write the program from your first post as
function onReadyState(xhr, task) { if ( xhr.readyState == xhr.DONE){ if ( xhr.status == 200){ var jsonObject = JSON.parse(xhr.responseText) if(task === "service"){ console.log(JSON.stringify(jsonObject)) // correct output of the object return jsonObject } } } } function get(url, task, id) { var xhr = new XMLHttpRequest() xhr.open("GET", url, true) xhr.onreadystatechange = onReadyState.bind(null, xhr, task) xhr.send() }
As you can see here, you only have return statement in the first function(but you only directly call get) The onReadyState is not called in this code, .bind() only does here partial function application(basically the same as std::bind in C++).
JavaScript has quite good support for functional-style programming, and professionals use this extensively. If in C++ it's very rarely that you encounter something like an std::function<void(int, string)> type, use of functional idioms in JavaScript is very common place. You will get used to them in time.
-
wrote on 8 Dec 2016, 18:36 last edited by
Thanks again for the explanation. I wish I had more time to learn programming correctly...
1/11