I'm getting the following error when attempting to update a new Item, due to my filter function(filteredItems). Once I click the Add Item button and navigate away from the page, this error comes up:
"Uncaught TypeError: Cannot read properties of undefined (reading 'toLowerCase')"
Here is the Items Component where the filter function resides.
import React, {useState,useEffect} from 'react'
import PickupList from './PickupList'
import Search from './Search'
import UpdateItems from './UpdateItems'
import NewItem from './NewItem'
function Items(){
const [items,setItems]=useState([])
const [search, setSearch]=useState('')
const itemURL = '/items/'
useEffect(()=>{
fetch(itemURL)
.then(res => res.json())
.then((allItems) => setItems(allItems))
},[])
const filteredItems = items.filter((item)=>item.bottle.toLowerCase().includes(search.toLowerCase()))
console.log(items)
return (
<main>
<UpdateItems setItems={setItems} />
<NewItem items={items} setItems={setItems}/>
<Search search={search} setSearch={setSearch}/>
<PickupList allItems={filteredItems} />
</main>
)
}
export default Items
Here is my NewItem component:
import React, {useState} from "react";
const startValue = {
bottle: '',
size: '',
count: '',
}
function NewItem({setItems}) {
const [newItem, setNewItem] = useState({
bottle: '',
size: '',
count: '',
})
function handleChange(e){
setNewItem((currentNewItem) => {
return {
...currentNewItem,
[e.target.name]: e.target.value,
};
})
}
function handleSubmit(e) {
e.preventDefault()
fetch('/items', {
method:"POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(newItem),
})
.then(res => res.json())
.then(handleItems)
}
function handleItems(data) {
setNewItem(startValue)
setItems((currentItems) => [...currentItems,data])
}
return (
<div className="new-item-form">
<h2>New Item</h2>
<form onSubmit = {handleSubmit}>
<input
type="text"
name="bottle"
value={newItem.bottle}
placeholder="Bottle type"
onChange = {handleChange}
/>
<input
type="text"
name="size"
value ={newItem.size}
placeholder="Size"
onChange = {handleChange}
/>
<input
type="number"
name="count"
step="0"
value = {newItem.count}
placeholder="Count"
onChange = {handleChange}
/>
<button type="submit">Add Item</button>
</form>
</div>
);
}
export default NewItem;
CodePudding user response:
You have to add an condition before filtering
let filteredItems;
if(items){
filteredItems = items.filter((item)=>item.bottle.toLowerCase().includes(search.toLowerCase()))
}
return (
<main>
{ items &&
<UpdateItems setItems={setItems} />
<NewItem items={items} setItems={setItems}/>
<Search search={search} setSearch={setSearch}/>
<PickupList allItems={filteredItems} />
}
</main>
)
CodePudding user response:
Something maybe trying to read the value while it still doesn't exists.
Try to conditionally write it with ?. (optional chaining operator)
const filteredItems = items?.filter((item)=>item.bottle.toLowerCase().includes(search?.toLowerCase()))