After updating data user.map is not a function anymore

Hello everyone, I am writing crud-operations using redux-toolkit and typescript. I have a component UserInfo , where I map through user - and all users are displayed on the homepage. I have a childComponent named userDisplay, where the particular user is displayed. There I update the data and that works. But when I go back to /home, I have a blank site and the error:

user.map is not a function

I logged the typeof user in the UserInfo and it gives me back ‘object’. So, when it is an object, I cannot use map(). But why this map is working, when I call the homepage and after updating it works not anymore.
userInfo:

const UserInfo = () => {
const dispatch = useAppDispatch();
 const selector = useAppSelector((state:RootState)=>state.user);
 const {user} = selector;
  console.log(typeof user); //gives back object
  useEffect(()=>{
    dispatch(getAllUser())
  }, [dispatch])
  return (
    <Container>
      <Title>Neue Benutzer</Title>
      <ContentWrapper>
        {user.map((item)=>(
          <div key={item._id}>

Userslice update:

type AsyncThunkConfig = {
    state: RootState
}
export const updateUser = createAsyncThunk<User[], UpdateData, AsyncThunkConfig>('/user/update', async (updateData, thunkAPI)=>{
    try{
        const token:string = thunkAPI.getState().auth.user!.accessToken;
        return await userService.updateUser(updateData, token);
    }catch (error:any) {
      const message =
        (error.response &&
          error.response.data &&
          error.response.data.message) ||
        error.message ||
        error.toString()
      return thunkAPI.rejectWithValue(message as string)
    }
});

userSlice getAll:

export const getAllUser = createAsyncThunk<User[], void, AsyncThunkConfig>('/user/findAll', async (_, thunkAPI)=>{
    try{
        const token = thunkAPI.getState().auth.user!.accessToken;
        return await userService.getAllUser(token);
    }catch (error:any) {
      const message =
        (error.response &&
          error.response.data &&
          error.response.data.message) ||
        error.message ||
        error.toString()
      return thunkAPI.rejectWithValue(message as string)
    }
})

The http.Request works, so perhaps the error is in my backend
update:

userRouter.put('/:id', verifyTokenAndAuthorization, async (req:Request, res:Response)=>{
    try{
    const updatedUser = await User.findByIdAndUpdate(req.params.id,{
        $set: req.body,
    },{new:true})
        res.status(200).json(updatedUser);
    } catch(error){
        res.status(404)
        throw new Error("User not found");
    }
});

getAll:

 userRouter.get('/find', verifyTokenAndAdmin, async (req:Request, res:Response)=>{
    try{
        const allUsers = await User.find();
        res.status(200).json(allUsers);
        console.log(typeof allUsers); //gives back object, object (I have two users in the database)
    } catch(error){
        res.status(404).json("Users not found");
    }
});

Thanks for your help.

I’m not positive here, but something to check would be whether this returned user object, which I’m assuming is a Mongoose query, can be parsed with .map by react. Could that be the problem?

Thanks for your response. I logged the response.data in my http.request, and it is an array. So, I 'am sure that it is a frontend or redux problem.

I tested again, it has nothing to to with updating itself. The homepage opens and all users are there. I leave the site to the childpage and come back, then I have the error user.map is not a function. When I visit another page or refresh the site, all users stay there. So, I think, it is a problem between UserDisplay and UserInfo.

Lets see your reducer function. The problem may be from there. Make sure you are returning an array the contains previous value with the new value like so:

update: (state, action) => ([…state, action.payload])

Just as an aside, don’t use typeof to check if something is an array, use Array.isArray()

typeof []
'object'

Array.isArray([])
true

Or log it out using JSON.stringify

I found out, that getAllUser is not dispatched when I switch back from UserDisplay to the homepage. Someone give me the hint, that I should not dispatch the function in useEffect. I tried this and the userlist was displayed. But in the moment I clicked the display button my computer terribly crashed. Since than my application not runs anymore. When I do the npm start, the console gives me the error: C:\xampp\htdocs\webshop_ts_mern\admin\node_modules\react-scripts\scripts\start.js:19
[1] throw err;
[1] ^
[1]
[1] SyntaxError: Unexpected token in JSON at position 0
Has someone an idea how I could repair this.

That is usually caused by fetching against an endpoint that is returning HTML instead of JSON and calling .json() on the response.

The server might be sending back a response like a 404. Check the server and the endpoint(s) you are fetching from when the app is starting up.


As an aside. Not sure how you are doing the fetch but a try/catch will only catch network errors, not response errors. You have to check the response object for the ok property.

MDN: Checking that the fetch was successful

I checked the response.The response.status is (200). It is okay. So what I found out, when I log the user in the userInfo on the homepage, I get at first an array of all users. It is my getAll Function. Then I switch to the userDisplay and get the particular user, by dispatching my getUser(id).But when I go back to the homepage, the new log of user contains only this user, that was shown in the userDisplay. I tried something with shallowEqual but that should not be the solution. So this using of getUser(id) seems to change the user in general for this parent and child page.

The problem was in my redux-slice. There must be two states in initialState, one for user to get the single user and another for all users.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.