0

I'm new to react, and I'm working on a small project that uses a search bar to find data that I've gotten from my database.

The code that I tried is below:

function Posts() {

    const [notes, setNotes] = useState([]);

    useEffect(()=>{
        getAllNotes();
    }, []);

    const getAllNotes = async () => {
        await axios.get(`/buyerPosts`)
            .then ((response)=>{
                const allNotes=response.data.existingPosts;
                setNotes(allNotes);
            })
            .catch(error=>console.error(`Error: ${error}`));
    }
    console.log(notes);

    const filterData = (postsPara, searchKey) => {
        const result = postsPara.filter(
            (notes) =>
                notes?.address.toLowerCase().includes(searchKey) ||
                notes?.contact.toString().toLowerCase().includes(searchKey)
        );
        setNotes(result);
    };

    const handleSearchArea = (e) => {
        const searchKey = e.currentTarget.value;

        axios.get(`/buyerPosts`).then((res) => {
            if (res?.data?.success) {
                filterData(res?.data?.existingPosts, searchKey);
            }
        });
    };

    return(
        <div className="posts-b">
            <div className="posts__container-b">
                <div className="search-box">
                    <input type="text" placeholder="What are you looking for?" onChange={handleSearchArea}></input>
                    <i className="fas fa-search"></i>
                </div>
                <main className="grid-b">
                    {notes.map((note,index)=> (
                        <article>
                            <div className="text-b">
                                <h3>Post ID: {index + 1}</h3>
                                <p>Location: {note.address}</p>
                                <p>Post Type: {note.postType}</p>
                                <p>Address: {note.address}</p>
                                <p>Telephone No: {note.contact}</p>
                            </div>
                        </article>         
                    ))}
                </main>
            </div>
        </div>
    );
}

export default Posts;

From the first API call, I get a length 10 array of objects. This image shows the data that I got from the first API call.

Results of the first API call

There is another array of objects called as wasteItemList in all 10 array as in this picture. I created the search function correctly and it works to search the data in the above length 10 array of objects using this code notes?.address.toLowerCase().includes(searchKey) || notes?.contact.toString().toLowerCase().includes(searchKey). Then I try to modify above code to search the data inside the wasteItemList array like this notes?.wasteItemList?.item.toLowerCase().includes(searchKey) || notes?.wasteItemList?.wasteType.toLowerCase().includes(searchKey). But it does not work and get an error that says 'Unhandled Rejection (TypeError): Cannot read property 'toLowerCase' of undefined'.

What is the reason for this problem. Is this impossible to search the data in an inside array of objects that are already in another array of objects? If possible how can I solve this problem?

Any other comments on the code are also welcome. I'm here to learn.

Thank you!

3 Answers 3

1

notes?.address is single string attribute however, notes?.wasteItemList is list of objects. hence notes?.wasteItemList?.item will return an undefined

what you can do is run a map to extract a list of item key and join using join function and then use includes function, the following snippets will get you the idea

notes?.wasteItemList?.map(wasteItem => wasteItem.item).join(' ').toLowerCase().includes(searchKey)

Sign up to request clarification or add additional context in comments.

Comments

1

wasteItemList is an array, you are trying to access it with:

wasteItemList?.item.toLowerCase()

AND

wasteItemList?.wasteType.toLowerCase()

This will cause wasteType to be undefined, so toLowerCase() will also throw an error since it will be similar to that you are executing this:

undefined.toLowerCase() => Cannot read property 'toLowerCase' of undefined

For wasteItemList is an array so if you want to access its variable need to access it with another loop.

Comments

1

You're trying to call .toLowerCase() on an array. You will need to search within that array (it doesn't matter that it's nested inside an object in another array) - here's a suggestion for how to do that:

 const result = postsPara.filter(notes =>
    notes?.wasteItemList?.some(
      wasteItem =>
        wasteItem.item?.toLowerCase().includes(searchKey) ||
        wasteItem.wasteType?.toLowerCase().includes(searchKey),
    ),
  );

Since this is a general javascript question and not specific to react, you might want to change the tag.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.