Reputation: 160
I have this function which has to remove an object from firebase firestore database and also should remove the id of this object from the users which this object belongs to. I am using double for loop to check all of this and removing the id's from user when it is the object id. But as long as this condition is true for loop stops execution immediately. Here is the function structure :
removeObj(obj) {
for (let i = 0; i < obj.users.length; i++) {
for (let j = 0; j < obj.users[i].objects.length; j++) {
//WHEN THIS CONDITION IS TRUE LOOP STOPS EXECUTION
if (obj.id == obj.users[i].objects[j]) {
//this scope never gets executed although the condition is true.
console.log("if is true");
obj.users[i].objects.splice(j, 1);
} else {
console.log('object id : ', obj.users[i].objects[j])
}
}
}
}
So in the code above, when the if statement should evaluate to true, the second for loop execution stops(didn't check for the first one). Everything goes fine is the statement is false tho. But the moment it is true loop stops. I tried with triple and double equals sign. same behavior. I also tried with foreach same behavior.
No idea what is going on. Thanks In advance!
obj structure in this example :
obj = {
id : "abcd",
users : [
{
id : "aqwuiop",
objects : [
"tyui",
"kjhg",
"uhbg",
"abcd",
"fghj"
]
},
{...}
]
}
So what happens is I see this first 3 element of the objects array of the user in log that comes from else scope but in the forth element(which is the one that if should evaluate to true) I don't see it in the log coming from else scope of course but I also don't see the log in the if scope. And fifth element log also doesn't appear and rest of the function gets executed.
Upvotes: 1
Views: 333
Reputation: 22939
You need to loop in reverse/backwards.
As mentioned in the comments, when you remove an element from an array, the array itself gets reindexed so the .length
in the for
condition is no longer valid.
Here's an example of a reverse loop with a splice
:
const numbers = [1,2,3,4,5,6,7,8,9,10]
// iterate from the last element towards the first.
for (let i = numbers.length; i > 0; i--) {
// remove all even numbers, i.e the ones perfectly divisible by 2.
if (numbers[i] % 2 === 0) {
numbers.splice(i, 1)
}
}
console.log(numbers)
Upvotes: 4
Reputation: 329
Because you're operating on the object over which the for-loop is iterating, this can result in the loop getting cut short.
Specifically, the line obj.users[i].objects.splice(j, 1);
is likely causing unexpected behavior.
The splice array method operates destructively, changing the contents of the array on which the for loop operates.
It may be easier to keep track of logic if, rather than iterating over and destructively operating on the array at the same time, you perform your if
check on the original array, then copy passing elements over to a new array.
Upvotes: 1