0

I'm doing a project where I'm fetching an api data from my backend laravel with axios get and using its property to concatenate a channel within the mounted section of my component.

I'm fetching api/user through axios get which contains

{
  "id": 1,
  "name": "admin",
  "email": "admin@company.com",
  "email_verified_at": null,
  "created_at": "2019-08-17 10:06:14",
  "updated_at": "2019-11-27 02:03:30",
  "phone_number": "+12345678911",
  "phone_number_verified": 0,
  "company_id": 1,
  "verification_code": "",
  "signature": "",
  "signature_image": null,
}

Here's how I'm getting the user data from my laravel backend through axios:

mounted() {
  this.$http
    .get('/api/user')
    .then(response => ( this.user = response.data ))
    .catch(error => console.log(error))
},

Which is then declared as an empty array in my data() section as such:

data() {
  return {
    user: [],
  };
},

I can access the properties for example, id, in my template through {{ user.id }} and when I try to access it within the mounted() section, it gives me an object but when I try console.log(this.user.id) within the mounted, it throws undefined instead. The reason I need to access this.user.id within the mounted section is because I'm using it to concatenate the channel I'm using through Laravel Echo given as such:

mounted() {
  this.$http
    .get('/api/user')
    .then(response => ( this.user = response.data ))
    .catch(error => console.log(error))

  this.$echo
    .channel(`new-notification.${this.user.id}`)
    .listen('NewNotification', (data) => {
    // eslint-disable-next-line no-alert
      this.notifications.unshift(data);
    });
},

I'm fairly new to Vue and I don't know what I'm doing wrong in this. It would be of great help if someone can point out what I'm doing wrong or if there's a better method of doing it.

  • You are using an ansyc call to get the user, so the `console.log` is running before the api call returns. Chain another `then` and do the concatenation there. – Brian Lee Apr 09 '20 at 10:14
  • That is because the `this.user` object is updated asynchronously and is dependent on waiting for a response from the API: so logging `this.user.id` to console without waiting for the promise to resolve will of course show `undefined`. The reason why it shows in the template is because VueJS will re-render once `this.user` is updated. – Terry Apr 09 '20 at 10:14
  • 1
    Does this answer your question? [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) – Terry Apr 09 '20 at 10:14
  • You have race condition. You don't wait for the response. *I'm using it to concatenate the channel* - do this inside `then` or use async/await, which is syntactic sugar for the former. – Estus Flask Apr 09 '20 at 10:14

1 Answers1

0

The issue is the console will run before the response of api call. You can make the call async and try.

mounted() {
  this.fetchApi();
},
methods:{
  fetchApi: async function(){
    let response = await this.$http
     .get('/api/user');
    this.user = response.data;
    this.$echo
    .channel(`new-notification.${response.data.id}`)
    .listen('NewNotification', (data) => {
    // eslint-disable-next-line no-alert
      this.notifications.unshift(data);
    });
  }
}
Rijosh
  • 1,538
  • 1
  • 8
  • 11