0

I have created a database in firebase and populated it by the following:

database.ref("expenses").push({
    desctiption: "item no 1",
    note: "note 1",
    amount: 20,
    createdOn: 1220,
});
database.ref("expenses").push({
    desctiption: "item no 2",
    note: "note 2",
    amount: 10,
    createdOn: 1120,
});
database.ref("expenses").push({
    desctiption: "item no 3",
    note: "note 3",
    amount: 50,
    createdOn: 920,
});

Now i want to fetch it. So i would be using the following code:

database.ref("expenses").on("value", (dataSnapshot) => {
    const expensesArr = [];
    dataSnapshot.forEach((expense) =>
        expensesArr.push({
            id: expense.key,
            ...expense.val()
        })
    );
    console.log("expensesArr", expensesArr);
});

I have observed that, just like in the code above, if i don't put curly braces around the forEach's callback function, only the first item gets pushed in the expensesArr.

Whereas only if i put curly braces around forEach's callback function,i.e

dataSnapshot.forEach((expense) => {
    expensesArr.push({ id: expense.key, ...expense.val() })
});

the whole 3 item gets pushed into tthe expensesArr.

Can i get an explanation for that??

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
kob003
  • 2,206
  • 2
  • 12
  • 19
  • your code should work just fine . can you reproduce it in a codesandbox ? – Mohammad Faisal Sep 20 '20 at 12:57
  • Does firebase's `forEach` abort (break the iteration) if you `return` a boolean value? – Bergi Sep 20 '20 at 13:02
  • See https://stackoverflow.com/q/28889450/1048572 or https://stackoverflow.com/q/35440265/1048572 for the syntactical difference – Bergi Sep 20 '20 at 13:11
  • https://codesandbox.io/s/stackoverflowquery-1-forked-42jr8 – kob003 Sep 20 '20 at 14:03
  • i am aware of the syntactical difference.it just doesn't make sense to me since push() returns number(the length of the array). and to my knowlede forEach doesn't break. – kob003 Sep 20 '20 at 14:36

1 Answers1

1

From the Firebase documentation on DataSnapshot's forEach method:

Parameters

  • action: (a: DataSnapshot) => boolean | void

    A function that will be called for each child DataSnapshot. The callback can return true to cancel further enumeration.

As push returns a positive integer, and those are truthy in JavaScript, the forEach iteration will be cancelled after the first iteration when you don't use a statement block (braces). This is because the expression in the short expression syntax determines the return value of the callback, while a statement block will only return what you return explicitly with a return statement, or undefined otherwise. And as undefined is falsy, the forEach iteration is not cancelled in that case.

It is unfortunate that forEach is also a JS native Array method, where the return value of the callback function is irrelevant. That these methods have the same name but act differently is an understandable cause of confusion.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • 1
    You just beat me to it, but I was going from the [code](https://github.com/firebase/firebase-js-sdk/blob/0131e1fcade96853997fc04ba1fee0e8d40ed445/packages/database/src/api/DataSnapshot.ts#L137). – Frank van Puffelen Sep 20 '20 at 15:31