最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vuex action which returns a promise never resolves or rejects - Stack Overflow

programmeradmin2浏览0评论

I'm trying to build up my API service in my VueJS application by using Vuex. I'm in the process of refactoring some stuff to centralize error handling, clean-up, etc. The issue I'm running into is properly chaining Promises through my function calls.

At the root level, I have a BaseService class, which simply make API requests using AXIOS (not full class):

export abstract class BaseService {
  protected readonly API: AxiosInstance; // Full init left out

  protected deleteItem(url: string): Promise<any> {
    return new Promise((resolve, reject) => {
      this.API.delete(url)
        .then((response: any) => {
          resolve(response);
        })
        .catch((error: any) => {
          this.handleError(error); // Local function that logs error
          reject(error);
        });
    });
  }
}

Then I have one layer above which managers different features of the API by assembling the request URL and handling the data:

class CompanyService extends BaseService {
  private constructor() {
    super();
  }

  public delete(id: number): Promise<any> {
    return this.deleteItem(`${this.baseUrl}/api/panies/${id}`);
  }
}

Then in my Vuex action I'm calling the panyService delete function:

const action = {
  COMPANY_DELETE(context: any, id: number) {
    return new Promise((resolve, reject) => {
      panyService // Instance of CompanyService
        .delete(id)
        .then((response: any) => {
          console.log(response); // This logs successfully
          resolve(response);
        })
        .catch((error: any) => {
          console.log(error); // This logs successfully
          reject(error);
        });
    });
  }
};

The two console logs plete successfully as indicated by my ments. This issue es in when I get to the ponent which invokes this action:

this.$store
  .dispatch("pany/COMPANY_DELETE", pany.id) // Namespaced
  .then((response: any) => {
    console.log(response); // Never gets called
  })
  .catch((error: any) => {
    console.log(error); // Never gets called
  });

Those two console logs are never called. What am I doing wrong here?

I'm trying to build up my API service in my VueJS application by using Vuex. I'm in the process of refactoring some stuff to centralize error handling, clean-up, etc. The issue I'm running into is properly chaining Promises through my function calls.

At the root level, I have a BaseService class, which simply make API requests using AXIOS (not full class):

export abstract class BaseService {
  protected readonly API: AxiosInstance; // Full init left out

  protected deleteItem(url: string): Promise<any> {
    return new Promise((resolve, reject) => {
      this.API.delete(url)
        .then((response: any) => {
          resolve(response);
        })
        .catch((error: any) => {
          this.handleError(error); // Local function that logs error
          reject(error);
        });
    });
  }
}

Then I have one layer above which managers different features of the API by assembling the request URL and handling the data:

class CompanyService extends BaseService {
  private constructor() {
    super();
  }

  public delete(id: number): Promise<any> {
    return this.deleteItem(`${this.baseUrl}/api/panies/${id}`);
  }
}

Then in my Vuex action I'm calling the panyService delete function:

const action = {
  COMPANY_DELETE(context: any, id: number) {
    return new Promise((resolve, reject) => {
      panyService // Instance of CompanyService
        .delete(id)
        .then((response: any) => {
          console.log(response); // This logs successfully
          resolve(response);
        })
        .catch((error: any) => {
          console.log(error); // This logs successfully
          reject(error);
        });
    });
  }
};

The two console logs plete successfully as indicated by my ments. This issue es in when I get to the ponent which invokes this action:

this.$store
  .dispatch("pany/COMPANY_DELETE", pany.id) // Namespaced
  .then((response: any) => {
    console.log(response); // Never gets called
  })
  .catch((error: any) => {
    console.log(error); // Never gets called
  });

Those two console logs are never called. What am I doing wrong here?

Share Improve this question asked Jun 22, 2018 at 13:55 brykenbryken 1673 silver badges15 bronze badges 6
  • 1 Not knowing your code base fully is "pany/COMPANY_DELETE" the correct action name? should it not be "COMPANY_DELETE" – Francis Leigh Commented Jun 22, 2018 at 14:14
  • Yeah, the store modules are namespaced. That is correct name. Prior to refactoring I did not have the Base and Company services, so everything was in the action and it worked as expected. The ponent calling the action has not changed. The purpose of refactoring is to declutter the store and improve the reusability and error handling. – bryken Commented Jun 22, 2018 at 14:18
  • Are you getting any error messaging in your console? – Francis Leigh Commented Jun 22, 2018 at 14:18
  • No error messages or warnings during build or in the console. – bryken Commented Jun 22, 2018 at 14:19
  • It maybe best to place a couple of breakpoints along your functional journey to see at which point it is breaking. – Francis Leigh Commented Jun 22, 2018 at 14:28
 |  Show 1 more ment

2 Answers 2

Reset to default 3

Small example to demonstrate an action with axios without an extra promise wrap...

const store = new Vuex.Store({
	state: {
  	followers: 0
  },
  mutations: {
  	updateFollowers(state, followers){
    	state.followers = followers;
    }
  },
  actions: {
    getFollowers({mit}) {
        return axios.get('https://api.github./users/octocat').then( (response) => {
        	mit("updateFollowers", response.data.followers);
          return "success!!!";
        });
    }
  }
})

Vue.ponent('followers', {
  template: '<div>Followers: {{ putedFollowers }}</div>',
  created () {
    this.$store.dispatch('getFollowers').then( (result) => {
    	console.log(result);
    });
  },
  puted: {
  	putedFollowers() {
    	return store.state.followers;
    }
  }
});

const app = new Vue({
	store,
  el: '#app'
})
<script src="https://unpkg./vue"></script>
<script src="https://unpkg./vuex"></script>
<script src="https://unpkg./axios/dist/axios.min.js"></script>
<div id="app">
  <followers></followers>
</div>

What ended up working was to remove the extra Promise like Void Ray said. However, in my particular use-case I also need to support error propagation. So the below action contains the fixes that I needed to make.

const action = {
  COMPANY_DELETE(context: any, id: number) {
    return panyService // Instance of CompanyService
      .delete(id)
      .then((response: any) => {
        console.log(response);
      })
      .catch((error: any) => {
        console.log(error);
        throw error; // Needed to continue propagating the error
      });
  },
};
发布评论

评论列表(0)

  1. 暂无评论