Parsing the results of a 'useQuery'
I am experimenting with parsing the results from a ‘useQuery’
Here is my code
const assets = useQuery(Main.CitizenInvitation);
const obj = JSON.stringify(assets);
con> sole.log ("asset : " + obj);
const obj2 = JSON.parse(obj);
console.log ("obj contracts : " + JSON.stringify(obj2.contracts[0]));
console.log ("templateId : " + JSON.stringify(obj2.contracts.templateId));
Here is the console.log output:
asset : {“contracts”:[{“templateId”:“5930f9c206352112718aaa4bf0104f368d4b4763cf201e055073cdea03bc3301:Main:CitizenInvitation”,“contractId”:“00bbb0f3c6bd9a27d8ffe304bc6aca8b0cc058eea3e483704df0469be9776fa9c5”,“signatories”:[“Operator”],“observers”:[“Alice”],“agreementText”:“”,“payload”:{“operator”:“Operator”,“citizen”:“Alice”,“roletype”:“Citizen”}}],“loading”:false}
obj contracts : {“templateId”:“5930f9c206352112718aaa4bf0104f368d4b4763cf201e055073cdea03bc3301:Main:CitizenInvitation”,“contractId”:“00bbb0f3c6bd9a27d8ffe304bc6aca8b0cc058eea3e483704df0469be9776fa9c5”,“signatories”:[“Operator”],“observers”:[“Alice”],“agreementText”:“”,“payload”:{“operator”:“Operator”,“citizen”:“Alice”,“roletype”:“Citizen”}}
templateId : undefined
The results are that I can parse and console.log the ‘assets’ and the ‘contract’, but I cannot arrive at displaying the ‘templateId’ as it is ‘undefined’
Any suggestions ?
It looks like you are printing obj2.contracts.templateId instead of obj2.contracts[0].templateId. templateId is a property on each contract not on the array of contracts.
That looks like contracts is empty and therefore contracts[0] is undefined. Do you see any output from the second console.log statement?
See my above message for all the console logs. The contract is not empty.
If I apply the same statement from a static Const with exactly the same JSON it works, but for some reason for a object that comes from the stream it doesn’t
Are you sure you get the same log after making the changes? Looking at your code I’m also a bit confused as to why you first call JSON.stringify only to then call JSON.parse again.
I agree that it would be much simpler to do just a JSON.parse but it creates errors
const assets = useQuery(Main.CitizenInvitation);
//const obj = JSON.stringify(assets);
//console.log ("asset : " + obj);
const obj2 = JSON.parse(assets);
console.log ("obj contracts : " + JSON.stringify(obj2.contracts[0]));
Creates the following error :
Uncaught SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse ()
at Default (Default.js:32)
at renderWithHooks (react-dom.development.js:14803)
at mountIndeterminateComponent (react-dom.development.js:17482)
at beginWork (react-dom.development.js:18596)
at HTMLUnknownElement.callCallback (react-dom.development.js:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
at invokeGuardedCallback (react-dom.development.js:292)
at beginWork$1 (react-dom.development.js:23203)
at performUnitOfWork (react-dom.development.js:22154)
at workLoopSync (react-dom.development.js:22130)
at performSyncWorkOnRoot (react-dom.development.js:21756)
at scheduleUpdateOnFiber (react-dom.development.js:21188)
at updateContainer (react-dom.development.js:24373)
at react-dom.development.js:24758
at unbatchedUpdates (react-dom.development.js:21903)
at legacyRenderSubtreeIntoContainer (react-dom.development.js:24757)
at Object.render (react-dom.development.js:24840)
at Module…/src/index.js (index.js:16)
at webpack_require (bootstrap:785)
at fn (bootstrap:150)
at Object.1 (index.js:28)
at webpack_require (bootstrap:785)
at checkDeferredModules (bootstrap:45)
at Array.webpackJsonpCallback [as push] (bootstrap:32)
at main.chunk.js:1
If you are available… I can do a screenshare.
You shouldn’t need either JSON.parse or JSON.stringify. Use the result directly:
const assets = useQuery(…);
console.log(assets.contracts);
How can I get to the details in the contracts ? I need to retrieve a specific value ? How do I get to that value ?
obj contracts : {“templateId”:“5930f9c206352112718aaa4bf0104f368d4b4763cf201e055073cdea03bc3301:Main:CitizenInvitation”,“contractId”:“00bbb0f3c6bd9a27d8ffe304bc6aca8b0cc058eea3e483704df0469be9776fa9c5”,“signatories”:[“Operator”],“observers”:[“Alice”],“agreementText”:“”,“payload”:{“operator”:“Operator”,“citizen”:“Alice”,“roletype”:“Citizen”}}
In the example above , I need to retrieve the “roletype” value
It’s a JSON object, you can just use .field to drill down so assets.contracts[0].payload.roletype.
console.log ("roletype : " + JSON.stringify(assets.contracts[0]));
displays
roletype : {“templateId”:“5930f9c206352112718aaa4bf0104f368d4b4763cf201e055073cdea03bc3301:Main:CitizenInvitation”,“contractId”:“00bbb0f3c6bd9a27d8ffe304bc6aca8b0cc058eea3e483704df0469be9776fa9c5”,“signatories”:[“Operator”],“observers”:[“Alice”],“agreementText”:“”,“payload”:{“operator”:“Operator”,“citizen”:“Alice”,“roletype”:“Citizen”}}
console.log ("roletype : " + JSON.stringify(assets.contracts[0].payload));
displays
`console.log ("roletype : " + JSON.stringify(assets.contracts.payload));
displays
roletype : undefined
console.log ("roletype : " + assets.contracts[0].payload);
displays
@bartcant Don’t forget that the result of a useQuery is a QueryResult. One needs to make sure that it is not loading and that the number of obj.contracts.length > 0 before you access a contract payload. Those things will change once the effect gets executed by React and the underlying fetch is resolved.
I have a sneaky suspicion that the errors you are seeing are due to the timing of when you see the results from the useQuery hook. Remember in that in Javascript
>> var x = []
Array []
>> x[0]
undefined
>> x[0].foo
TypeError: x[0] is undefined
Dealing with these confusing states makes me long for the safety of effect tracking monads.
To be safe, try assets.contracts.map(c => c.payload). As @Leonid_Rozenberg said I suspect it’s called twice once while the list is still loading and it’s empty and then once the entry is there.
Issue Solved 
const QueryResult = useQuery(Main.CitizenInvitation);
const assets = QueryResult.contracts.map(c => c.payload.roletype);
const roletype = JSON.stringify (assets);
console.log ("Roletype : " + roletype)
Thanks @cocreature @Leonid_Rozenberg !!!


