1

I have a Vue-App which runs with Vuex and Axios. In this app I have vuex-store which handles API-calls, but a problem is that when I call the store-actions I cant chain the response in the caller.Any ideas what Im doing wrong?

Calling code:

import { FETCH_PRODUCTS, ADD_PRODUCT } from './actions.type'

methods: {
    sendNewProduct () {
      this.$store
        .dispatch(ADD_PRODUCT, this.newProductForm)
        .then(() => {
          console.log('This never gets called')
        })
    }
  }

Vuex-store:

const actions = {
  [ADD_PRODUCT] (context, credentials) {
    return new Promise((resolve) => {
      ApiService
        .post('/Products/', {
          Name: credentials.Name,
          Description: credentials.Description,
          Price: credentials.Price
        })
        .then(({ data }) => {
          this.$store
            .dispatch(FETCH_PRODUCTS)
            resolve(data)
        })
        .catch(({ response }) => {
          console.log(response)
          context.commit(SET_ERROR, 'Error adding product')
        })
    })
  }
}
  • 3
    Looks like the explicit Promise construction antipattern, for one, though the Promise chain *looks* to be linked together properly, I think – CertainPerformance Oct 20 '18 at 20:51
  • 2
    Also, it never resolves (or rejects) in case of errors. – robertklep Oct 20 '18 at 20:53
  • `[ADD_PRODUCT] (context, credentials) {` is this a typo? there's no colon after the key name – Andy Ray Oct 20 '18 at 20:55
  • I have setup a file for all actions to avoid magic strings, probably should include it :-) Will update code. How do I avoid this antipattern? Promises and javascript are abit new to me. –  Oct 20 '18 at 20:58
  • 1
    https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it – trincot Oct 20 '18 at 21:08

1 Answers1

0
const actions = {
  [ADD_PRODUCT](context, credentials) {
    return ApiService.post("/Products/", {
      Name: credentials.Name,
      Description: credentials.Description,
      Price: credentials.Price
    })
      .then(({ data }) => {
        this.$store.dispatch(FETCH_PRODUCTS);
        return data;
      })
      .catch(({ response }) => {
        console.log(response);
        context.commit(SET_ERROR, "Error adding product");
        throw new Error("Error adding product");
      });
  }
};

I've removed the new Promise(...) because axios already creates a promise. If added a return data in the then callback and a throw in the catch callback to let the calling api receive the data/error.

Note that the promise resolves before the FETCH_PRODUCTS completes, to make sure that action is also completed, you'd write:

.then(({ data }) => {
  return this.$store.dispatch(FETCH_PRODUCTS)
    .then(() => data);
})
Bob Fanger
  • 28,949
  • 7
  • 62
  • 78