JavaScript array not iterable

15,245

If posts is an iterable I would look into using some version of q.all and then when all promises are resolved you can reliably log the result of push all those pieces into the statuses array.

some pseudo code:

if (user) {
        app.props.fb.database().ref(`/users/${user.uid}/timeline`)
        .once('value')
        .then(snapshot => snapshot.val())
        .then(posts => {                
            const statuses = [];

            const promises = Object.keys(posts).map(key => {
                return app.props.fb.database().ref(`/posts/${posts[key]}`).once('value')
                    .then(snapshot => statuses.push(snapshot.val()));
            }

            return Promises.all(promises)
        })
        .then(() => console.log(statuses));
    }
Share:
15,245

Related videos on Youtube

hackerman
Author by

hackerman

Updated on June 04, 2022

Comments

  • hackerman
    hackerman almost 2 years

    I hit a really weird issue with a simple JavaScript array last night. I am working on a React Native app powered by Firebase and getting data from the real-time database with the SDK.

    Here is the code:

        var app = this
    
        this.props.fb.auth().onAuthStateChanged(function(user) {
            if (user) {
                app.props.fb.database().ref('/users/' + user.uid + "/timeline").once('value').then(function(snapshot) {
                    var posts = snapshot.val()
                    return posts
                }).then((posts) => {                
                    var statuses = [];
                    for (i in posts) {
    
                        app.props.fb.database().ref('/posts/' + posts[i]).once('value').then(function(snapshot) {
                           statuses.push(snapshot.val())
                        });
                    }
    
                    console.log(statuses)
                })
            }
    
        });
    

    The above code is supposed to get the data from the timeline of each user, iterate through each of the posts on the timeline and then get the data of the post from posts. It then simply pushes the data to the statuses array, which is being console logged at the end.

    This is what shows up on the console. enter image description here

    Until the array is expanded, the console doesn't show the items in the array. Additionally, when I try to get the length of the array, it returns 0 and I also can't iterate through the items on the array.

    What am I doing wrong?

    • Sten Muchow
      Sten Muchow over 6 years
      99/100 JS errors seem to be async issues - this looks the same. u cannot log in the console an array that is being populated by an async call.
    • Phylogenesis
      Phylogenesis over 6 years
      You shouldn't iterate an array using a for..in construct. Use Array.prototype.forEach().
  • hackerman
    hackerman over 6 years
    How would that work? I am kinda new to this so would be really helpful if you could show me an example
  • Sten Muchow
    Sten Muchow over 6 years
    there ya go... seems we have Promises.all to work with -> developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • hackerman
    hackerman over 6 years
    Thank you so much!
  • Sten Muchow
    Sten Muchow over 6 years
    I added some es6-ification of your code as well, makes it a bit sexier with template strings, arrows functions, auto return statements ;)
  • hackerman
    hackerman over 6 years
    Neat stuff! Thanks again :)