Search code examples
asynchronousvue.jsvuejs2computed-properties

Vue.js - Update computed property after async computed property gets updated


I have a computed property (filteredSyms) that depends on the asynchronous computed property (allSynonyms). I am using async-computed plugin for this: https://www.npmjs.com/package/vue-async-computed.

However, when the data gets updated the computed property doesn't wait until the result of the async property update. Therefore, I receive not up to date information. Then after the async property actually return new value computed property doesn't run update again.

How can I make it work the way that computer property waits until there is a result from the async computed property?

The code is below:

asyncComputed: {
  async allSynonyms() {
    let allSyns = await this.$axios.$post('/db/sym/synonyms', this.model.syms);
    return allSyns;
  }
},

computed: {
  filteredSyms() {

    let that = this;
    let allSyn = this.allSynonyms;

    let exactMatch = this.symsByRating.filter(
      function (v) {
        let isExactMatch = v.title.toLocaleLowerCase().indexOf(that.searchString.toLocaleLowerCase()) >= 0;

        return !that.idsToFilter.includes(v.id) && isExactMatch
          && (!that.currentBodyPart || v.bodyParts.indexOf(that.currentBodyPart) >= 0)
          && that.hasMoreSubsyms(v)
          && (!allSyn || !that.containsObject(v, allSyn))
          && (v.sex == that.model.sex || v.sex == 'NA');
      });

    let partialList = [];

    exactMatch.forEach(ex => partialList.push({n: 100, sym: ex}));

    for (let sym of this.symsByRating ) {

      let searchWords = this.searchString.toLocaleLowerCase().split(' ');
      let symWords = sym.title.toLocaleLowerCase().split(' ');

      let n = 0;
      let isPartialMatch = false;
      symLoop:for (let symWord of symWords) {
        symWord = symWord.substring(0, symWord.length - 1);
        for (let searchWord of searchWords) {

          // don't count last letters of the words
          searchWord = searchWord.substring(0, searchWord.length - 1);

          if (searchWord.length > 2 && symWord.indexOf(searchWord) >= 0) {
            n++;
            isPartialMatch = true;
          }
        }
      }

      if (exactMatch.indexOf(sym) < 0 && isPartialMatch
        && (!this.currentBodyPart || sym.bodyParts.indexOf(this.currentBodyPart) >= 0)
        && this.hasMoreSubsyms(sym)
        && (!allSyn || !this.containsObject(sym, allSyn))
        && (sym.sex == that.model.sex || sym.sex == 'NA')) {

        partialList.push({n: n, sym: sym});

      }
    }

    partialList.sort(function(obj1, obj2) {
      return obj2.n - obj1.n;
    });

    if (this.searchString && this.searchString != '') {
      partialList = this.filterSynonyms(partialList);
    }

    let fs = partialList.map(ws => ws.sym);

    console.dir(fs);

    return fs;

  }
}

A lot of stuff is going on the filtered method, but I guess the main point here that it is using this.allSynonyms to do the check but it is not updated at the time filteredSyms is executed.

Thanks for your suggestions!


Solution

  • (I haven't really tested this out, but it should work.)

    vue-async-computed does provide the status in this.$asyncComputed.allSynonyms.success.

    try adding this.$asyncComputed.allSynonyms.success as a dependencies to filteredSyms and it should update when success state change.