1

The API I'm using receives a phone number as a parameter to return data from a user. So in the UI, I receive this number and through console.log I can see the data. But I also want, when clicking the button the user is taken to a link containing only data related to them and to do that I believe that I have to redirect the user to a dynamic link eg: '/user/john'. I'm always getting undefined in the link and I have no idea why. It feels like the state itself is not storing the API data

const Login =()=> {
  const history = useHistory()
  const location = useLocation()
  const [state, setState] = useState('')
  const [data, setData] = useState({});
  const phone = state
...
  let headers = new Headers();
  headers.set("Authorization", "Basic " + btoa(username + ":" + password));

    const handleClick=() => {
    getData();
  };    
  
  const getData = async () => {
    const a = await fetch(url, { method: "GET", headers: headers });
    const response = await a.json();
    setData(response.user[0].attributes[0]);
    history.push(`/user/${data.name}`)
  };
  
   const onTextChange = event => {
        setState(event.target.value);
      }
<input onChange={onTextChange}>
 <Button  onClick={handleClick} >
    login
 </Button> 
kapil pandey
  • 1,853
  • 1
  • 13
  • 26
Rowan Frank
  • 117
  • 6

1 Answers1

1

State always sets asynchronously (more details). setData(response.user[0].attributes[0]) will take some and since js is asynchronous next line will be executed i.e history.push('/user/${data.name}'). Since there is no data yet so data.name will be undefined.

Instead you must directly use history.push(/user/${(response.user[0].attributes[0]).name})

Here is the updated code:

    const Login = () => {
    const history = useHistory()
    const location = useLocation()
    const [state, setState] = useState('')
    const [data, setData] = useState({});
    const phone = state
    ...
    let headers = new Headers();
    headers.set("Authorization", "Basic " + btoa(username + ":" + password));

    const handleClick = () => {
    getData();
    };

    const getData = async () => {
    const a = await fetch(url, { method: "GET", headers: headers });
    const response = await a.json();
    const respData = response.user[0].attributes[0]
    setData(respData);
    history.push(`/user/${respData.name}`)
    };

    const onTextChange = event => {
    setState(event.target.value);
    }
    <input onChange={onTextChange}>
    <Button onClick={handleClick} >
      login
    </Button>
kapil pandey
  • 1,853
  • 1
  • 13
  • 26