Home > Mobile >  Fetch data trough a computed function in a v-for loop
Fetch data trough a computed function in a v-for loop

Time:10-23

In event.agents I've plain text ID's stored, which I want to fetch do get the specific data. I wrote a computed function to fetch the data, but my backend server always crashes through this way.

CastError

Cast to ObjectId failed for value "[object Object]" (type string) at path "_id" for model "User"

So, I guess I have to work with Promise somehow. But I don't know how.

The idea is to display the required agent data e.g. like this:

<p>{{ getAgent(agent).first_name }}</p>

Is it even possible like that?

<div v-for="agent in event.agents" :key="agent.id">
  <p>{{ getAgent(agent) }}</p>
</div>
computed: {
  getAgent(agentID) {
    const agent = this.fetchAgentData(agentID)
    return agent
  }
}

// I tried it with async/await, but eslint tells me 'no-async-in-computed-properties'
async fetchAgentData(agentID) {
  try {
    const agent = await this.$axios.$get(`/api/get-specific-agent/${agentID}`)

    if (agent.success) {
      return agent.data
    }
  } catch (err) {
    console.log(err)
  }
},

CodePudding user response:

computed are not meant to be used with side effects. It's goal is to have a result based on some other variables, here you're calling a method with an HTTP call, I thought you would get a side-effect ESlint warning here too, but it's kinda avoiding it.
Also, a computed does not take a param as seen here, it's mainly
key function hence getAgent: { ... in your case.

There is no possibility to have several computed with their own state, you can only have one single value for a given computed.

What you're looking for here is mainly a casual method, nothing else.

If you want to handle some performance concerns, you can use a memoization on it to not run avoidable HTTP calls etc, like that. Not sure that it's worth the trouble in your case tho.

Overall, I'm not sure if you need to even run it per-element, using a single Promise.all to populate all of your event.agent ahead of time is probably the simplest way here.

  • Related