Home > Back-end >  TypeError: categories.map is not a function in ReactJs
TypeError: categories.map is not a function in ReactJs

Time:10-31

I've got this error:

TypeError: categories.map is not a function

This is App.js:

export default function Header() {
  const [categories, setCategories] = useState([]);
    useEffect(() => {
           const loadCategories = async () => {
               let res = await API.get(endpoints['categories'])
               setCategories(res.data)
           } 

           loadCategories()
    }, []);

    return (
        <Navbar bg="light" expand="lg">
            <Container>
                <Navbar.Brand href="#home">ECoursesAPP</Navbar.Brand>
                <Navbar.Toggle aria-controls="basic-navbar-nav" />
                <Navbar.Collapse id="basic-navbar-nav">
                <Nav className="me-auto">
                    <Link className="nav-link" to="/">Trang chủ</Link>
                    {categories.map(c => <Link className="nav-link" to="#link">{c.name}</Link>)}
                </Nav>
                </Navbar.Collapse>
            </Container>
        </Navbar>
    )
}

This is API.js:

import axios from "axios";

export let endpoints = {
    "categories": "/categories/"
}
    
export default axios.create({
    baseURL: "http://localhost:8000"
})

CodePudding user response:

You should always have a null check before .map to avoid run-time errors

{(categories || []).map(c => <Link className="nav-link" to="#link">{c.name}</Link>)}

CodePudding user response:

probably your api end point does not return an array so you can fix that or you can use categories?.map

CodePudding user response:

At the first render, your categories array is an empty array. So you are doing something like this:

[].map(item => <p>{item.name}</p>)

when there is no item in the array, using dot notation to get the item value will cause an issue.

There are two options for you:

  1. add a default value at initializing phase on setState, for example:
const [categories, setCategories] = useState([
  {id: 0, name: "" , ...}
]);
  1. wait for the API response before rendering the categories:
{
  categories.length > 0 && categories.map(
    // rest of the codes ...
  )
}

Update

there is another issue with your api.js

In Javascript objects, no need to wrap the key with the quotation marks. so remove it from categories:

let endpoints = {
    categories : "/categories/"
}

CodePudding user response:

Hey According to your error the issue is array not show element at first time rendering so you use the logic if array exist then array map the data let i show you

    export default function Header() {
  const [categories, setCategories] = useState([]);
    useEffect(() => {
           const loadCategories = async () => {
               let res = await API.get(endpoints['categories'])
               setCategories(res.data)

       } 

       loadCategories()
}, []);

return (
    <Navbar bg="light" expand="lg">
        <Container>
            <Navbar.Brand href="#home">ECoursesAPP</Navbar.Brand>
            <Navbar.Toggle aria-controls="basic-navbar-nav" />
            <Navbar.Collapse id="basic-navbar-nav">
            <Nav className="me-auto">
                <Link className="nav-link" to="/">Trang chủ</Link>
                {categories && categories.map(c => <Link className="nav-link" to="#link">{c.name}</Link>)}
            </Nav>
            </Navbar.Collapse>
        </Container>
    </Navbar>
)

}

  • Related