Consider the following simple function with a URLSearchParams
iterator.
const foo = (qs) => {
const sp = new URLSearchParams(qs);
console.log(`pre: ${sp}`);
for (const [key, val] of sp.entries()) {
console.log(`'${key}: ${val}'`);
sp.delete(key);
}
console.log(`post: ${sp}`);
}
foo('a=1&b=2&c=3&d=4');
With the sp.delete(key)
line commented out, it prints
pre: a=1&b=2&c=3&d=4
'a: 1'
'b: 2'
'c: 3'
'd: 4'
post: a=1&b=2&c=3&d=4
But when I uncomment that line, the output is
pre: a=1&b=2&c=3&d=4
'a: 1'
'c: 3'
post: b=2&d=4
I expect all the keys to be deleted, but in the second case, the iterator skips over every other key,val
pair. Why? Where am I being "stupid" or "blind" to my error?
Note: I realize I am changing the iterator while iterating over it, but am not able to wrap my head around skipping every other key
This is because you are modifying the underlying data structure (the URLSearchParams object) that the iterator (for...of loop) is using. and, when you call sp.delete(key) inside the loop this causes the iterator to skip over the next key-value pair, because the iterator's internal state is updated when the data structure changes.
To fix this, iterate over the copy of entries i.e:
for (const [key, val] of Array.from(sp.entries())) {
console.log(`'${key}: ${val}'`);
sp.delete(key);
}