'Trying to call an API every-time a search is completed. Am I misunderstanding useEffect()?

I'm new to React. Using useEffect(), I'm trying to call an api every time a search term is entered by the user.

The general code for this is shown below:

cosnt [search, setSearch] = useState("");    

useEffect(() => {
    fetch(`https://url/${search}`)
        .then(res => res.json())
        .then(data => data.map((entry) => {
            return {
                id: entry.id,
                name: entry.name,
                // more mapping
            }   
        }))  
        // for table
        .then(volcanoes => setRowData(() => setRowData(volcanoes)))
}, [search])


    <input aria-labelledby='search-button'
    name="search"
    id="search"
    type="search"
    onSubmit={(event) => setSearch(event.target.value)}
    />

The error I get from this is that data.map is not a function. When I manually enter a working url (e.g. https://url.com/australia), and set the useEffect array dependency to empty, the fetch works fine. From my limited understanding of react, it seems to be calling the fetch on the search when it is still empty, which results in something JS cannot map over. Why is this happening? Doesn't me declaring search as the dependency for useEffect mean it will only call useEffect once search has changed?

I can post more code if needed.



Solution 1:[1]

Your useEffect will be mounted when you load or refresh a page, causing the fetch request being activated, and your initial state for search is empty string '', resulting in error in your map function.

perhaps you should include a condition in your useEffect like this:

useEffect(() => {
  if (search)
    fetch(`https://url/${search}`)
        .then(res => res.json())
        .then(data => data.map((entry) => {
            return {
                id: entry.id,
                name: entry.name,
                // more mapping
            }   
        }))  
        // for table
        .then(volcanoes => setRowData(() => setRowData(volcanoes)))
}, [search])

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 David Ho