0

I'm trying to get some data from firebase and put it in an Array, the value in question is listquestion. For debugging I tried to show it using listquestion.map but it's not showing anything but if I look at my console, the Array has 3 objects inside it. I'm assuming the error is when I trying to put the data in the array but I did not find how to fix it

export function onceGetQuestion() {
  var listquestion = [
    {
      answercount: "",
      question: "",
      status: ""
    }
  ];

  db.ref("questions")
    .once("value")
    .then(function(snaps) {
      const foo = snaps.val();
      if (foo !== null) {
        Object.keys(foo).forEach(key => {
          db.ref("questions")
            .child(key)
            .once("value")
            .then(function(snap) {
              var questionlist = listquestion;
              questionlist.push({
                answercount: snap.val().answercount,
                question: snap.val().question,
                status: snap.val().status
              });
              listquestion = questionlist;
            });
        });
      }
    });
  console.log(listquestion);
  return listquestion;

front end (react )

class HomePage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      listquestion: [],
      done: undefined
    };
  }
 componentDidMount() {
    this.state.listquestion = db.onceGetQuestion();
  }
  render() {
    return (
       questions.map(function(position, i){
         ........ 
       <span >{position.question}</span>
         ........
    }
.......

the array : [1]: https://i.stack.imgur.com/YL7zM.jpg

1 Answers1

1

It's because of the callback. When you call

Object.keys(foo).forEach(key => {
          db.ref("questions")
            .child(key)
            .once("value")
            .then(function(snap) {
              var questionlist = listquestion;
              questionlist.push({
                answercount: snap.val().answercount,
                question: snap.val().question,
                status: snap.val().status
              });
              listquestion = questionlist;
            });

even if listquestion have been declare in the global scope of your function, the value that you assign inside the .then are local so the value stop existing when you leave the .then

So you have to do whatever treatment needed inside the .then.

A possible solution would be to return the promise (db.ref("questions").once("value")) from your onceGetQuestion() function. Create a method in your class for the treatment (it would be the code inside the then in your original solution). call the method .then of the value returned from your function and in this context (the .then) change the state of your class using this.setState({})

A comment pointed out a very good answer about asynchronous calls: https://stackoverflow.com/a/16825593/12016897

ref: https://www.sitepoint.com/demystifying-javascript-variable-scope-hoisting/

ref: https://reactjs.org/docs/state-and-lifecycle.html