0

I have this function is javascript that I hope to construct an array from data I have stored in my firebase database. It is evident that the array is being created properly (by use of console.log statements), but I cannot get the array outside of the function. So far, this is what I have:

// my function
function foo(){
    firebase.database().ref("data").once('value').then(function(snapshot){
        var list = snapshot.val();
        var newlist = [];
        for(var item in list){
            newlist.push(
                {axis:"x-axis", value:list[item].info, definition: list[item].def},
                {axis:"y-axis", value:list[item].info, definition: list[item].def},
                {axis:"z-axis", value:list[item].info, definition: list[item].def},
            );
        }
        return newlist;
    })
}

// my creation
var fooList = foo();

// my test
setTimeout(function(){
    console.log(fooList); // returns undefined...
},5000);

Whenever I run this function, I always get an undefined element back. I would really appreciate the help!

  • try `console.log(snapshot.val())` in beginning of the function , what you get ? – Ali Faris Jan 31 '18 at 05:22
  • It returns my list in the form of an object. That is the only reason the for-loop is there; to convert it into an array. – OliviaHarmon Jan 31 '18 at 05:26
  • `in the form of an object` - what sort of object? does `console.log(item)` output anything? – Jaromanda X Jan 31 '18 at 05:27
  • why are you waiting 5 seconds before outputting (console.log) the results? – Jaromanda X Jan 31 '18 at 05:29
  • I just figured that I was trying to print out "fooList" before it was actually set. But by in the form of an object, I mean that the results where initially in the form "{D1:{...d1...}, D2:{...d2...}, D3:{...d3...}}" but I wanted it in the form "[{...d1...},{...d2...},{...d3...}]". console.log(item) outputs "D1","D2", and "D3". – OliviaHarmon Jan 31 '18 at 05:34
  • It's odd that fooList is **`undefined`** though – Jaromanda X Jan 31 '18 at 05:36
  • My apologies...I forgot to add a line from my code. I just edited it. – OliviaHarmon Jan 31 '18 at 05:36
  • ahhhh, now with the real code, it is indeed a case of not knowing how to deal with asynchronous code – Jaromanda X Jan 31 '18 at 05:37
  • try `foo().then(result => console.log(result))` - does that output what you expect? (oh, and add a `return` in front of `firebase.database()... etc` – Jaromanda X Jan 31 '18 at 05:37
  • The reason you get `fooList` as `undefined` is because your `foo` function does not return anything – Jaromanda X Jan 31 '18 at 05:39

1 Answers1

0

you can return Promise from your foo function and use await get the result somewhere else , or you can use then on the returned promise which is a better solution

checkout the code

function foo(){
    return new Promise(function(resolve , reject){
        firebase.database().ref("data").once('value').then(function(snapshot)
        {
            var list = snapshot.val();
            var newlist = [];
            for(var item in list){
                newlist.push(
                    {axis:"x-axis", value:list[item].info, definition: list[item].def},
                    {axis:"y-axis", value:list[item].info, definition: list[item].def},
                    {axis:"z-axis", value:list[item].info, definition: list[item].def},
                );
            }

            resolve(newlist);
        });
    })
}

//or without await
foo().then(function(list){
    console.log('using then , '  , list);
})

var fooList = await foo();

// my test
setTimeout(function(){
    console.log('in setTimeout' , fooList); 
},5000);

console.log('without setTimeout' , fooList); 
Ali Faris
  • 17,754
  • 10
  • 45
  • 70
  • [Avoid the explicit promise construction antipattern](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it) - also, you can't `await` outside of a function tagged as `async` – Jaromanda X Jan 31 '18 at 05:45
  • `firebase.database().ref("data").once('value')` results in a promise - there's no need to construct one around it – Jaromanda X Jan 31 '18 at 05:53
  • `once` will return DataSnapshot object not array , and you can see OP want to generate new array based on that snapshot – Ali Faris Jan 31 '18 at 05:57
  • `once` is returning a `Promise` ... it was the `.then` right after it that was the giveaway – Jaromanda X Jan 31 '18 at 05:57
  • I know , calling then on `foo` will get an array , calling `then` on `once` will get `DataSnapshot` object – Ali Faris Jan 31 '18 at 05:59
  • anyway , thanks for the advice :) , really appreciated – Ali Faris Jan 31 '18 at 06:02