Skip to content

Problems using values after axios

I am sorry if this problem is already solved somewhere but I can’t wrap my head around what my problem is. In my scenario I want to make 2 axios calls and do some stuff with the two data responses before the page is finally rendered. If I output the data in my template it is visible but when I want to use it before the page is rendered the value is always undefined. After some research I came up with the following solution:

 created() {
   this.getStuff()

},


methods: {
    async getStuff(){
        this.Stuff1= await this.getSomething1()
        this.Stuff2= await this.getSomething2()
        
        var test = this.Stuff1[2].name 
        console.log(test)
    },

    async getSomething1(){
        const response=await axios.get('http://localhost:4000/apiSomething1');
        return response.data;
    },

    async getSomething2(){
       const response=await axios.get('http://localhost:4000/apiSomething2');
       return response.data;
   },
}

If I want to do something with these values for example pass it to another value it wont work because Stuff1 is undefined. Why is that the case? In my understanding the async functions should wait until the promise is finished because of await so the value should exist after the 2 awaits in getStuff() but this is not the case. I am really thankful for any help!

Edit I tried both solutions mentioned but getting the same mistake. For clearness I added the whole code.

<template>
  <h3>List all players</h3>
  <br />
  <table>
    <tr v-for="player in PlayerAll" :key="player._id">
      <td>{{ player.lastname }}</td>
      <td>{{ player.name }}</td>
      <td>{{ player.birthdate }}</td>
      <td>{{ player.hash }}</td>
      <td>
        <Button
          @click="deleteSpieler(player._id)"
          class="p-button-danger"
          label="Delete Player"
        />
      </td>
    </tr>
  </table>
</template>

<script>
import axios from "axios";

export default {
  data() {
    return {
      PlayerAll: [],
      TeamAll: [],
      Combined: [],
    };
  },

  async created() {
    await this.fetchData();
    var test = this.TeamAll[2].name;
    console.log(test);
  },

  methods: {
    async fetchData() {
      let requests = [];
      try {
        requests = await axios.all([
          axios.get("http://localhost:4000/apiPlayer"),
          axios.get("http://localhost:4000/apiTeam"),
        ]);
      } catch (e) {
        console.error(e);
      }
      this.PlayerAll = requests[0].data;
      this.TeamAll = requests[1].data;
    },
  },
};
</script>

<style scoped>
.btn-success {
  width: 150px;
  height: 150px;
  background: red;
}
</style>

Answer

I think you should use a promise as so this means once the axios call is done you fill the data and not before it happens I saw that in you edit u added console.log in created that doesn’t work for sure because it happens before the data is fetched in the code i offered i added v-if on the table that way you will avoid any error in the console for rendering this before the data is fetched, I used mounted instead of created because it is called after DOM has been mounted, this should work and let me know if you have any problems

<template>
  <h3>List all players</h3>
  <br />
  <table v-if="PlayerAll">
    <tr v-for="player in PlayerAll" :key="player._id">
      <td>{{ player.lastname }}</td>
      <td>{{ player.name }}</td>
      <td>{{ player.birthdate }}</td>
      <td>{{ player.hash }}</td>
      <td>
        <Button
          @click="deleteSpieler(player._id)"
          class="p-button-danger"
          label="Delete Player"
        />
      </td>
    </tr>
  </table>
</template>

<script>
import axios from "axios";

export default {
  data() {
    return {
      PlayerAll: null,
      TeamAll: [],
      Combined: [],
    };
  },

  mounted() {
    this.getStuff();
  },

  methods: {

    getStuff(){
        let vm = this;

        Promise.all([vm.getSomething1(), vm.getSomething2()]).then((values) => {
            vm.PlayerAll= = values[0].data
            vm.TeamAll = values[1].data
        });
    },

    async getSomething1(){
        return await axios.get('http://localhost:4000/apiPlayer');
    },

    async getSomething2(){
        return await axios.get('http://localhost:4000/apiTeam');
    },
};
</script>

<style scoped>
.btn-success {
  width: 150px;
  height: 150px;
  background: red;
}
</style>