Harry
Harry

Reputation: 93

useEffect .map not a function React Hooks

Here's my issue: I am setting the state of currentUser, sometimes its undefined, sometimes its not (from the API). I then pass it to the second useEffect, I set the carrier state, and then as I try to fetch users from that carrier based on the ID, carrier.id appears to be undefined for some reason.

What am I doing wrong here?

I use this useEffect to watch for any changes to the currentUser that is logged in. I pass the user from Auth Service to currentUser state.

useEffect(() => {
  const user = AuthService.getCurrentUser();
  // console.log(user);

  if (user) {
    setCurrentUser(user);
    // console.log(currentUser);
  } else {
    console.log("user not logged");
  }
}, []);

I am trying to pass the ID from currentUser to the fetch endpoint for the useEffect below to receive the carrier the user is attached to/supervisor of.

// Fetches the carrier that the user is supervisor in 


const [carrier, setCarrier] = useState({

});

useEffect(() => {
    fetch(`http://localhost:8080/supervisor/${currentUser.id}/carriers`, {
        headers: new Headers({
            'Authorization': 'Bearer ' + currentUser.accessToken, 
          }), 
    })
    .then(response => response.json())
    .then(json => setCarrier(json))
}, [carrier])

const [employees, setEmployees] = useState([

])

I then pass the carrier.id to the endpoint to receive the users attached to the specific carrier that the user is in.

// fetches the users from the specific carrier

useEffect(() => {
  fetch(`http://localhost:8080/supervisor/carriers/${carrier.id}/employees/`, {
      headers: new Headers({
          'Authorization': 'Bearer ' + currentUser.accessToken, 
        }), 
  })
  .then(response => response.json())
  .then(json => setEmployees(json))
}, [employees])



 {employees.length > 0 && employees.map((employeeCarrier) => (   
      <Slide direction="up" in={employees} mountOnEnter unmountOnExit>
      <TableRow key={employeeCarrier.id}>
            <TableCell>{employeeCarrier.fullname}</TableCell>
            <TableCell>{employeeCarrier.email}</TableCell>
            <TableCell>{employeeCarrier.crn}</TableCell>
            <TableCell>{employeeCarrier.role}</TableCell>
            <TableCell>{employeeCarrier.address}</TableCell>
            <TableCell>{employeeCarrier.birthday}</TableCell>
            <TableCell align="center">
            <Tooltip title="Modify">
                        {/* <IconButton aria-label="modify" size="small" onClick={() => handleClickOpenEditUser(user)}> */}
                            <EditIcon />
                         {/* </IconButton> */}
                        </Tooltip> 
                      <Tooltip title="Delete">
                        {/* <IconButton aria-label="delete" onClick={()=>deleteUser(user.id)}> */}
                          <DeleteIcon />
                        {/* </IconButton> */}
                       </Tooltip> 
            </TableCell>
          </TableRow>
          </Slide>
        ))}

Upvotes: 0

Views: 255

Answers (1)

Parmandeep Chaddha
Parmandeep Chaddha

Reputation: 484

I think I understand your question. Your hierarchy seems to be something like this:

  1. See if the User is authenticated.
  2. If authenticated, fetch the carriers for the users.
  3. If carriers, fetch the employees for the carrier.

Okay, so first thing, as @Jayce444 mentioned, your useEffect() is problematic, because it monitors carrier, and also fetches carrier.

What you actually want is this:

useEffect(() => {
  const user = AuthService.getCurrentUser();
  // console.log(user);

  if (user) {
    setCurrentUser(user);
    // console.log(currentUser);
  } else {
    console.log("user not logged");
  }
}, []);


useEffect(() => {
fetch(`http://localhost:8080/supervisor/${currentUser.id}/carriers`, {
        headers: new Headers({
            'Authorization': 'Bearer ' + currentUser.accessToken, 
          }), 
    })
    .then(response => response.json())
    .then(json => setCarrier(json))
}, [currentUser]); //Should be currentUser not carrier

Do you see why? When the currentUser changes only then do we want the carrier to be fetched.

Extending the same concept:

useEffect( () => {
  fetch(`http://localhost:8080/supervisor/carriers/${carrier.id}/employees/`, {
      headers: new Headers({
          'Authorization': 'Bearer ' + currentUser.accessToken, 
        }), 
  })
  .then(response => response.json())
  .then(json => setEmployees(json))
}, [carrier])

Only fetch new employees when carrier changes.

Does that make sense? UseEffect basically says: If this variable/dependancy changes, what should I do?

Upvotes: 1

Related Questions