0

The second useEffect block runs before the first has received any data back. This causes the second block to return an error and an empty array.

I've tried using async/await, as this has solved problems like this for me in the past. However, it doesn't seem to have an effect here.

    const [session, setSession] = useState("");
    const [champions, setChampions] = useState([]);

    useEffect(() => {
        axios.get(`http://api.paladins.com/paladinsapi.svc/createsessionJson/${devId}/${generateSignature('createsession')}/${moment.utc().format('YYYYMMDDHHmmss')}`).then((response) => {
            setSession(response.data.session_id);
            console.log(session);
        }).catch((error) => {
            console.log(error);
        })
    }, [])

    useEffect(() => {
        axios.get(`http://api.paladins.com/paladinsapi.svc/getchampionsJson/${devId}/${generateSignature('getchampions')}/${session}/${moment.utc().format('YYYYMMDDHHmmss')}/1`).then((response) => {
            setChampions(response.data);
            console.log(champions);
        }).catch((error) => {
            console.log(error);
        })
    }, []);

It should return an array of objects to champions, but since it doesn't receive a session id, the api call is not the correct address keeping champions as an empty array.

Javad Khodadadi
  • 410
  • 1
  • 4
  • 13
CodyLee
  • 81
  • 1
  • 5
  • [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call/14220323) – Andreas Oct 13 '19 at 14:54
  • useEffect (possibly) or axious.get (definitely) are asynchronous functions. Google for what does it mean in JavaScript. Generally you need to call it first time and then make the second call in a callback, something like axious.get(oneCall).success(() => {axiouse.get(… etc. – d.k Oct 13 '19 at 14:54
  • This gives me an error saying ".success is not a function". – CodyLee Oct 13 '19 at 16:34

2 Answers2

0

useEffect is an asynchronous function so you need to just move the calls both into one useEffect function and then call your api's synchronously. I would move this into a separate function and use async/await to run your api call synchronously. Then call that function in your useEffect function like so:

useEffect(() => {
  getData();
},[]);

const getData = async () => {
  try{
    const session = await axios.get(`your first call here`);
    const champions = await axios.get(`your second call here`);

    setSession(session.yourData);
    setChampions(champions.yourData);
  }catch(err){
    console.log(err);
  }
} 

If you have data from the first api call that the second one uses then you don't need to set that to any state object you can just use it directly in your second api call.

Steve K
  • 8,505
  • 2
  • 20
  • 35
  • Using this I'm still getting the same problem. It's still returning an empty string into the second axios call, causing the url for the call to not be found. – CodyLee Oct 13 '19 at 16:08
  • How are you setting your session id to the second request? Instead of setting the sessionid to the state you should be setting your sessionid directly to the second api request from the first one. So instead of setting response.data.session_id to the state you should just set session.data.session_id directly into your second api call. – Steve K Oct 13 '19 at 16:38
  • Doing this I no longer get the 404 not found error, however, it doesn't seem to be updating the champions array still. Using: setChampions(myChamps.data); – CodyLee Oct 13 '19 at 16:55
  • It seems that it is setting the setChampions array before the data is being received – CodyLee Oct 13 '19 at 17:55
0

    const [session, setSession] = useState("");
    const [champions, setChampions] = useState([]);

    useEffect(() => {
  try{
    const session = await axios.get(`http://api.paladins.com/paladinsapi.svc/createsessionJson/${devId}/${generateSignature('createsession')}/${moment.utc().format('YYYYMMDDHHmmss')}`);

    setSession(session.session_id);

    const champions = await axios.get(`http://api.paladins.com/paladinsapi.svc/getchampionsJson/${devId}/${generateSignature('getchampions')}/${session.session_id}/${moment.utc().format('YYYYMMDDHHmmss')}/1`);

    setChampions(champions );
     }
catch(err){
    console.log(err);
     }
}, [])



i am davood
  • 175
  • 15
  • Using this I'm still getting the same problem. It's still returning an empty string into the second axios call, causing the url for the call to not be found. – CodyLee Oct 13 '19 at 16:08