2

I use VueJs (and Vuex) with Axios to communicate with an Express Api. I can delete my own user account consuming a service

import api from '@/services/api.js';

export default {
  deleteAccount: () => api().delete('/users')
};

where api is the axios instance. I don't need to pass in a user ID because the api identifies the user by the token.

Within my settings view I can consume this service

<script>
import { mapActions } from 'vuex';

import UserService from '@/services/users'; 

export default {
  name: 'Settings',
  methods: {
    ...mapActions('alert', [
      'showSuccessAlert',
      'showErrorAlert'
    ])
    deleteAccount: async function() {
      try {
        await UserService.deleteAccount();

        this.showSuccessAlert({ message: 'Account was deleted successfully' });
        // other stuff
      } catch (error) {
        this.showErrorAlert({ message: error.message });
      }
    }
  }
};
</script>

Calling UserService.deleteAccount() returns me a pending promise. Using await returns me the api response.

Currently the api always returns a 500 for testing purposes. I thought, that if the Promise gets rejected the code will always jump directly into the catch block. Here, the code returns a rejected Promise (and writes a "Internal Server Error" to the console but passes and shows a success alert / never executes the code from the catch block.

What is wrong with the code? Did I misunderstand promises?


Update

My axios instance

import axios from 'axios';

import TokensService from '@/services/tokens.js';
import store from '@/store/store.js';

function getTokenString() {
  return `Bearer ${TokensService.getToken()}`;
}

export default () => {
  const instance = axios.create({
    baseURL: 'http://localhost:3000/',
    headers: {
      'Content-Type': 'application/json',
      Authorization: getTokenString(),
    },
  });

  instance.interceptors.request.use((config) => {
    config.headers.Authorization = getTokenString();
    return config;
  }, (err) => Promise.reject(err));

  instance.interceptors.response.use((res) => res, (err) => {
    if (err.response.status === 401) {
      store.dispatch('authentication/destroySession');
      store.dispatch('alert/showErrorAlert', { message: err.message });
    }

    return err;
  });

  return instance;
};

Calling api().delete() is the same as axios.delete('http://localhost:3000/users')

8
  • 1
    returns a 500 - http status does not necessarily mean a rejected promise - the browsers fetch for instance does not reject on a 500, or 404, or any successful (as far as getting a http response) request Commented Apr 10, 2019 at 13:28
  • Does returning status code 500 automatically reject the promise? Commented Apr 10, 2019 at 13:28
  • yes, normally it does Commented Apr 10, 2019 at 13:28
  • 1
    what does the code for api().delete look like? is it your code? Commented Apr 10, 2019 at 13:29
  • as far as I know all "failed requests" will jump into the catch block Commented Apr 10, 2019 at 13:29

1 Answer 1

1

try returning a rejected promise here

  instance.interceptors.response.use((res) => res, (err) => {
    if (err.response.status === 401) {
      store.dispatch('authentication/destroySession');
      store.dispatch('alert/showErrorAlert', { message: err.message });
    }

    return Promise.reject(err);
  });

as per examples https://github.com/axios/axios#interceptors

Sign up to request clarification or add additional context in comments.

1 Comment

oh yes, I had to change return err; to return Promise.reject(err);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.