I am trying to remove checked items that are true from an array with the array.splice method. It seems to work most of the time, but for some reason, there are times when two or three items are checked, and only one item is removed from the checked list when I run the function that splices the array items.
I've tried mapping through the array and returning the new array with the spliced items removed, kind of works but not always. I'm mapping the array with two arguments, (index and item). I am creating an if statement that if the item is checked, or done, to remove it by (index, 1). After that I'm returning the new array. The issue is happening in the removeCheckedBeer
function
// if there is no item string, create an empty array
const items = JSON.parse(localStorage.getItem('items')) || []
function addItem(e) {
// prevent the form from submitting
e.preventDefault()
const text = (this.querySelector('[name=item]')).value
const item = {
text,
done: false
}
items.push(item)
// rerenders list without having to reload the page
populateList(items, itemsList)
localStorage.setItem('items', JSON.stringify(items))
this.reset()
}
// function removes all items in the array
const removeAllItems = e => {
e.preventDefault()
items.splice(0)
localStorage.setItem('items', JSON.stringify(items))
populateList([], itemsList)
}
// remove all checked items
const removeCheckedBeer = e => {
e.preventDefault()
items.map((item, index) => {
if (item.done === true) {
console.log(index, item)
items.splice(index, 1)
}
return items
})
localStorage.setItem('items', JSON.stringify(items))
populateList(items, itemsList)
}
// toggle a single item
const toggleDone = e => {
if (!e.target.matches('input')) return // skip this unless it's an input
const el = e.target
const index = el.dataset.index
// toggle from done to !done
items[index].done = !items[index].done
localStorage.setItem('items', JSON.stringify(items))
}
// toggle inventory of all items to true or false
const toggleAllItems = e => {
items.forEach((item, index, array) => {
e.target.name === 'checkAll' ? (items[index].done = true) : (items[index].done = false)
console.log(e.target.name)
})
localStorage.setItem('items', JSON.stringify(items))
populateList(items, itemsList)
}
const populateList = (beers = [], beerList) => {
// map through the array, and create a new array to render the beer list
beerList.innerHTML = beers.map((beer, i) => {
return `
<li>
<input type="checkbox" data-index=${i} id="item${i}"
${beer.done ? 'checked' : ''} />
<label for="item${i}">${beer.text}</label>
</li>
`
}).join('')
}
So I'm expecting that the number of checked items will be removed from the array starting at the index of the first checked item. The result is that the item is being removed, but at times, just one item at a time. Sometimes more than one item is being removed. Can someone explain what's happening with my function?
The issue with splice()
is that the element is removed from the array shifts all other elements down by one as well. It would be better to use filter()
:
items = items.filter(e => e.done !== true);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.