Home > Mobile >  Vuejs created and mounted doesn't work properly even if at the same level than methods
Vuejs created and mounted doesn't work properly even if at the same level than methods

Time:10-05

I'm experiencing a strange behaviour with created() and mounted() in Vue.js. I need to set 2 lists in created() - so it means those 2 lists will help me to create a third list which is a merge.

Here is the code :

// return data

created () {
    this.retrieveSellOffers();
    this.getAllProducts();
  },
  mounted () {
    this.mergeSellOffersProducts();
  },

  methods: {
    retrieveSellOffers() {
      this.sellerId = localStorage.sellerId;
      SellOfferServices.getAllBySellerId(this.sellerId)
        .then((response) => {
          this.sellOffers = response.data;
          console.log("this.sellOffers");
          console.log(this.sellOffers);
        })
        .catch((e) => {
          console.log(e);
        });
    },
    getAllProducts() {
      ProductServices.getAll()
        .then((response) => {
          this.products = response.data;
          console.log("this.products");
          console.log(this.products);
        })
        .catch((e) => {
          console.log(e);
      });
    },
    mergeSellOffersProducts () {
      console.log(this.products) // print empty array
      console.log(this.sellOffers) // print empty array
      for (var i = 0; i < this.sellOffers.length; i  ) {
          if (this.sellOffers[i].productId === this.products[i]._id) {
            this.arr3.push({id: this.sellOffers[i]._id, price: this.sellOffers[i].price, description: this.products[i].description});
        }
      }
      this.arr3 = this.sellOffers;
    },
}

//end of code

So my problem is when I enter in mergeSellOffersProducts(), my 2 lists are empty arrays :/

CodePudding user response:

Are you sure your api calls are done before merging? It's better to await your methods.

CodePudding user response:

  • I think the reason is: Vue does not wait for the promises to resolve before continuing with the component lifecycle.
  • Your functions retrieveSellOffers() and getAllProducts() contain Promise so maybe you have to await them in the created() hook:
async created: {
  await this.retrieveSellOffers();
  await this.getAllProducts();
}

CodePudding user response:

So I tried to async my 2 methods :

    async retrieveSellOffers() {
      this.sellerId = localStorage.sellerId;
      this.sellOffers = (await axios.get('linkhidden/api/selloffer/', { params: { sellerId: '615b1575fde0190ad80c3410' } })).data;
      console.log("this.sellOffers")
      console.log(this.sellOffers)
    },
    async getAllProducts() {
      this.products = (await axios.get('linkhidden/api/product')).data;
      console.log("this.products")
      console.log(this.products)
    },
    mergeSellOffersProducts () {
      console.log("here")
      console.log(this.sellOffers)
      console.log(this.products)
      this.arr3 = this.sellOffers;
    },

My data are well retrieved, but yet when I enter in created, the two lists are empty...

CodePudding user response:

You are calling a bunch of asynchronous methods and don't properly wait for them to finish, that's why your data is not set in mounted. Since Vue does not await its lifecycle hooks, you have to deal with the synchronization yourself.

One Vue-ish way to fix it be to replace your method mergeSellOffersProducts with a computed prop (eg mergedSellOffersProducts). Instead of generating arr3 it would simply return the merged array. It will be automatically updated when products or sellOffers is changed. You would simply use mergedSellOffersProducts in your template, instead of your current arr3.

If you only want to update the merged list when both API calls have completed, you can either manually sync them with Promise.all, or you could handle this case in the computed prop and return [] if either of the arrays is not set yet.

  • Related