Reputation: 401
I'm implementing some function in which retrieves some data of type array from firebase, then search for specific element from that array and if exists, I would like to abort the function and return back to the caller. (React-native app)
here is the Code:
ref.get().then(snapshot => {
const personArr = snapshot.data().winPerson;
...
if (personArr != undefined) {
personArr.forEach(item => {
if (item == uid.uid) {
alert(`already subscribed`);
return;
}
});
if (prop.first.length != 0) {
uploadHelper(ref, prop, "first");
}
...
}
});
I loop through the array using forEach and see if there is matching element. If there is match, then it should alert and return to the caller function without running the subsequent code below, which is
if (prop.first.length != 0) {
uploadHelper(ref, prop, "first");
}
However, assuming that the element does exist in the array, the code runs both alert and the uploadHelper function(checked through log). First I thought forEach was async function so uploadHelper executed before the return; however, forEach is not async function (after some googling).
I have no idea why uploadHelper runs if the code falls into the if (item == uid.uid) condition and returns.
any help is appreciated. Thank you
Upvotes: 1
Views: 84
Reputation: 2824
It is returning to the caller function :) a forEach()
is calling a function with each element. So you are returning, but only from the function of that one element.
I think a for of
loop would be want you want here. People who want to do functional programming want to use the .forEach
, but using a for of
achieves the same functional effect as a .forEach
(don't have to index, no side effect) and is probably more straightforward to use. (a forEach also has an issue if wanting to write async code where you would like to wait between each element)
So, rewrite your code like:
for (const item of personArr) {
if (item == uid.uid) {
alert(`already subscribed`);
return;
}
}
Upvotes: 2
Reputation: 8589
The forEach
handler is also a function. ( item => ... is an arrow function ) So returning from inside personArr.forEach()
does not actually stop the rest of the function from executing.
So if (prop.first.length != 0)
will get checked, no matter what the .forEach() does.
If the goal is to only run uploadHelper when uid is not found, you need to change the structure a little bit. Something like:
ref.get().then(snapshot => {
const personArr = snapshot.data().winPerson;
...
if (personArr != undefined) {
const match = personArr.find( item => item === uid.uid );
if ( match ) alert(`already subscribed`);
else if (prop.first.length != 0) {
uploadHelper(ref, prop, "first");
}
// else { /* some other defualt case ? */
...
}
});
If item is actually the same value as uid.uid, you can even do it simpler:
personArr.includes( uid.uid )
should return true, if uid.uid
is inside personArr
.
Upvotes: 1
Reputation: 750
Use this instead
for (let item of personArr) {
if (item == uid.uid) {
alert(`already subscribed`);
break;
}
}
forEach is not possible to break, thats why you need to use for instead and break it. in forEach return means continue to next index without processing below code not stop the loop
Upvotes: 1
Reputation: 1247
First of all, you can't stop a forEach. It will always run for every element of the array and then continue the execution of the code. The return indicates that the element you are iteration on at the moment will be changed for your return value.
If you want to stop the execution you could use a for-in loop or a generic for loop.
Upvotes: 1