2

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>
2
  • you need to check the users contain data or not. before rendering. Commented Sep 28, 2020 at 9:41
  • One possibility is that the users list from the backend is empty so if res.data.length > 1 condition is not satisfied then the state will not get updated. In order to avoid that you can initialse the state like this.state = { users: [] }. Also while rendering you can use (state.users || []).map or state.users?.map in order to avoid the crash. Commented Sep 28, 2020 at 9:44

3 Answers 3

1

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>

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

1 Comment

Yes, it worked. I think it is like what u said, the JSX get rendered out before the promise was resolved.
1

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

Comments

1

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>
                            })
}

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.