0

I got a question here. I got an object (usrobj) after parsing a JSON object from ajax

console.log(usrobj.available[0]);

where usrobj.available is an array

(2) [{…}, {…}]
0:{currency: "ETH", amount: "0.5"}
1:{currency: "BTC", amount: null}
length:2
__proto__:Array(0)

This results a vardump like this

{currency: "ETH", amount: "0.5"}
amount:"0.5"
currency:"ETH"
__proto__:Object

However when I try to loop through the

for(i = 0; i < usrobj.available.length; ++i) {
    $('#assets-table').append('<tr>\
      <td>'+usrobj.available[i].currency+'</td>\
      <td>Available: '+usrobj.available[i].amount+' (Frozen: '+usrobj.frozen[i].amount+')<br /></td>\
...removed for brevity...

Uncaught TypeError: Cannot read property '0' of undefined

at Object.success (readAssets.js:22)
at i (jquery-3.2.1.min.js:2)
at Object.fireWith [as resolveWith] (jquery-3.2.1.min.js:2)
at A (jquery-3.2.1.min.js:4)
at XMLHttpRequest.<anonymous> (jquery-3.2.1.min.js:4)

could anyone please advise me if they are in different scope? and how do i fix this problem?

Pointy
  • 405,095
  • 59
  • 585
  • 614
Alexander Ho
  • 503
  • 2
  • 7
  • 18
  • It's probable that you're attempting to use the data before it's retrieved. Try putting the append loop code in the callback part of your ajax request. – zfrisch Jun 05 '18 at 15:37
  • 1
    maybe the problem is in the `usrobj.frozen[i]` part, since you did not test it in your snippet ? – Logar Jun 05 '18 at 15:39
  • 1
    Please update your question with a [mcve] demonstrating the problem, ideally a **runnable** one using Stack Snippets (the `[<>]` toolbar button; [here's how to do one](https://meta.stackoverflow.com/questions/358992/ive-been-told-to-do-a-runnable-example-with-stack-snippets-how-do-i-do-tha)). As @zfrisch said, you're probably trying to use the object before it's been filled in, and are getting fooled by [this console behavior](http://stackoverflow.com/questions/38660832/element-children-has-elements-but-returns-empty-htmlcollection). (Try `console.log(JSON.stringify(usrobj.available[0]));`) – T.J. Crowder Jun 05 '18 at 15:39
  • Thanks! It is true that frozen is not definded. And Thanks for the ajax explanation part too! – Alexander Ho Jun 05 '18 at 16:03

2 Answers2

0

Your object doesnt have the "frozen" property

"usrobj.frozen[i].amount" so it crash

If usrobj.frozen has in the same position the same value than usrobj.avaiable you will need something like:

let usrobj = {
  available: [
    {currency: "ETH", amount: "0.5"},
    {currency: "BTC", amount: null},
  ],
  frozen: [
    null,
    {ammount: '10'}
  ]
}

  for(let i in usrobj.available){
    console.log(
      `Avaiable ${usrobj.available[i].amount}
      Frozen ${(usrobj.frozen && usrobj.frozen[0] && usrobj.frozen[0].amount) || 0}
      `)
  }
Alvaro Molina
  • 108
  • 1
  • 12
  • 2
    I'd say that too, but you can't state that the object does not have the frozen property, since we don't know the shape of `usrobj`, we only have a guess of the shape of `usrobj.available` – Logar Jun 05 '18 at 15:43
0

as you are running the code usrobj.available[i].currency inside the jquery append function,try saving the this reference to a variable outside the jquery function and access usrobj.available[i].currency inside the append function using ref.usrobj.available[i].currency

for(i = 0; i < usrobj.available.length; ++i) {
    let ref = this;
    $('#assets-table').append('<tr>\
      <td>'+ref.usrobj.available[i].currency+'</td>')
 ....     
}      
it is just a small snippet ,try it
ravi
  • 1,127
  • 9
  • 10
  • Not necessary. The global scope is still the global scope and you don't need to reference it to get to the variable at hand. – scrappedcola Jun 05 '18 at 15:57