Unable to render out array in React using Array.map

Viewed 388

I was using axios to GET an array of usernames and use setState to update the state. I have log the users to console to ensure that it is an array.

axios.get("http://localhost:5000/users/")
        .then((res) => {
            if (res.data.length > 1) {
                const users = res.data.map(el => el.username);

                setState((preValue) => {
                    return {
                        ...preValue,
                        users : users
                    }
                })
                console.log(state)
            }

        })
        .catch((err)=>console.log(err)) 

When it get rendered out in JSX. The map method of the array returns an undefined error. However, the array can be rendered out as a string.

enter image description here

enter image description here

<h3>Edit Exercise</h3>
            <form onSubmit={onSubmit}>
                <div className="form-group">
                    <label>Username: {state.users}</label>
                    {/* <select required className="form-control"
                        value={state.username} onChange={onChangeUsername}>
                        {
                            state.users.map(function (user) {
                                return <option key={user} value={user}>{user}</option>
                            })
                        }
                    </select> */}
                </div>
3 Answers

You need to first check if property users exists: !!state.users && state.users.map(function (user) {.

Maybe users is an array but when react is rendering your jsx users is empty because it's not finished fetching your data which means users is empty or undefined. To comeback this first try if users array is defined

<div className="form-group">
    <label>Username: {state.users}</label>
    {/* <select required className="form-control"
        value={state.username} onChange={onChangeUsername}>
        {
            state.users && state.users.map(function (user) {
                return <option key={user} value={user}>{user}</option>
            })
        }
    </select> */}
</div>

You can also check the length if that didn't work

<div className="form-group">
    <label>Username: {state.users}</label>
    {/* <select required className="form-control"
        value={state.username} onChange={onChangeUsername}>
        {
            state.users.length > 0 && state.users.map(function (user) {
                return <option key={user} value={user}>{user}</option>
            })
        }
    </select> */}
</div>

If your component is class component you should use this keyword before state(this.state.users). When using map you can check whether it is undefined or null using Optional chaining.

So it will be like this:

{ this.state?.users.map(function (user) {
                                return <option key={user} value={user}>{user}</option>
                            })
}
Related