[Vuejs]-How to disable Vue Component if Ajax call will fail

0đź‘Ť

You should make your “target” field not required and instead add a default value empty string.

And add an “if” condition to your load method. If “target” is empty, it will not proceed.

export default {
  name: 'load content',
  props: {
    target: {
      type: String,
      default: ''
    }
  },
  methods: {
    load() {
      if (!this.target) return;
      $('#load-content-modal').modal('show');
      this.$store.dispatch('loadContent', this.target);
    },
  }
};

0đź‘Ť

Create a store variable loading and mutate it in your actions as follows:

loading: false

const actions = {
  loadContent ({ commit }, target) {
    $.ajax({
      url: '/api/fetch-content/' + target,
    }).then((data) => {
      // Load Modal Window
      commit(setLoading)
    });
  },
};

Then in muatations ->

setLoading (state, loading) {
    state.loading = true
  }

Now in your vue file use this store variable and check if it is true then load the component.You may check this created or mounted events of the component.

0đź‘Ť

Option 1

Preemptively load the content, and disable the ones that return an error.

This is what the parent component will look like

<template>
  <load-content 
    v-for="(target, index) in loadedTargets"
    :key="index"
    target="target"
  />
</template>

<script>
export default {
  name: 'load content parent',
  data: function() {
    return {
      targets: [
        {link: 'foo', data: null, loaded: false, error: null},
        {link: 'bar', data: null, loaded: false, error: null},
        {link: 'oof', data: null, loaded: false, error: null},
        {link: 'rab', data: null, loaded: false, error: null},
      ]
    }
  },
  computed: {
    loadedTargets() {
      return this.targets.filter(t => t.loaded)
    }
  },
  methods: {
    load(target) {
      const self = this;
      $.ajax({
        url: '/api/fetch-content/' + target.link,
      }).then((data) => {
        self.targets[indexOf(target)].data = data
        self.targets[indexOf(target)].loaded = true
      }).catch((error) => {
        self.targets[indexOf(target)].error = error
      });
    },
  },
  mounted() {
    this.targets.forEach(target => this.load(target))
  }
};
</script>

Option 2

Preemptive loading is expensive (and since I don’t know how many targets you might have), you could also show success/error in the modal. Proper UX would dictate that an explicit action by the user should lead to a result (i.e. if the user clicks a link, he should either see data in the modal, or an error)

This is what your action will look like:

const actions = {
  loadContent ({ commit }, target) {
    $.ajax({
      url: '/api/fetch-content/' + target,
    }).then((data) => {
      // Load Modal Window
    }).catch((error) => {
      // Load Modal Window, and show the error
    });
  },
};

Leave a comment