0

I have a table on the frotend where account data is displayed. To get the data, I use Action in VueX with a request to the server:

@Action({ rawError: true })
public async getAccount(accountId: number): Promise<Account> {

try {
    const url = `/api/accounts/${accountId}`;

    const response = await $axios.get(url);

    return response.data;
   }   catch (e) {
      // eslint-disable-next-line no-console
      console.log(e);

      throw e;
   }
}

At the moment there are only 5 users in the table, but there are > 50 rows in the table (users are repeated), as a result of which the request to the server is made > 50 times, I want to solve this by caching, and make the request only 5 times. To do this, I added an array, where I decided to save all accounts for which the request has already been made:

  accountsCache: Account[] = [];

  @Mutation
  public addAccountToCache(account: Account) {
     this.accountsCache.push(account);
  }

  @Action({ rawError: true })
  public async getAccount(accountId: number): Promise<Account> {

  let account;

  for(let i = 0; i < this.accountsCache.length; i++) {
     if(this.accountsCache[i].id === accountId) {
       account = this.accountsCache[i];
       break;
     }
  }

  console.log('account', account);

  if(account) {
     return account;
  } else {
    try {
       const url = `/api/accounts/${accountId}`;

       const response = await $axios.get(url);

       this.context.commit('addAccountToCache', response.data);

       return response.data;
    } catch (e) {
       // eslint-disable-next-line no-console
       console.log(e);

       throw e;
    }
  }
}

But when searching (I tried all the methods I know of iterating over an array, including async search and I know that searching in an array can be done through a Getter, this will not change the result), JS returns account undefined and as a result it does not work as intended.

Component where Action is used:

@Component
export default class AccountInfo extends Vue {
    @accounts.Action
    public getAccount!: (accountId: number) => Promise<Account>;

    @Prop({ required: true }) readonly accountId!: number;

    account: Account | null = null;

    async created() {
        if (this.accountId) {
            const account = await this.getAccount(this.accountId);

            this.account = account;
        }
    }
}

The component is used in the table where the account parameters are displayed, therefore the component in the table is used many times, but the table may contain the same accounts - for this purpose, I want to save the data so as not to make requests for the same accounts.

It is interesting, but after going through the routes (I work in Nuxt.js), requests don't go back again, i.e. the cache still works, but there are 92 values ​​and these are repetitions of the same users (and there are only 5 of them).

How can this be solved and why is this happening? Thanks.

  • Pretty sure we will need some reproduction of your code here. Or you need to provide us some of the data at a given point thanks to the Vue devtools. – kissu Jan 31 '21 at 03:00
  • @kissu I have a component where the account name is displayed, for this I need to get the account data by ID. I use Action (in the code above) in `created()` hook in the component. I use this component in a table where names are displayed many times and they are repeated (accounts). – uglegorsky Jan 31 '21 at 04:12
  • @Dan In my opinion, this doesn't make sense, if also transfer the `account` object in the data from the server on which the table is drawn (now only the `accountId` comes in) - there is no query optimization in this. Yes, I still have to receive `account` data by `ID`, but there are only 5 of them, while there can be > 50 `items` in the table - I see no point in storing an `account` object in each one, besides, they will also be repeated - to solve this, I am trying make data caching :) – uglegorsky Jan 31 '21 at 08:43
  • Not sure what you're referring to so I'll assume you know what you're talking about. – Dan Jan 31 '21 at 08:51

0 Answers0