Home > Mobile >  Replace objects within nested Array
Replace objects within nested Array

Time:10-24

I have an array in which another array with agents is stored. In this agents array only the id of each agent is stored. Using the id's, I fetch the data I need for each agent and I want to replace the original agent array (where only the id's are stored) with the new, completed agent data. Or at least push the new data to the specific agent. Here is what I have tried so far. Is there a simple way to do it?

How to push the fetched agent to filteredEvents -> agents? As seen in my expected result

filteredEvents: [
 { 
  agents: ['id', 'id'], // the id's are as plain text located
  eventData: ''
 }
]


// Expected result
filteredEvents: [
 { 
  agents:
  [
    { id: '', name: '', ...}, // the data from the fetched id
    { id: '', name: '', ...},
  ],
  eventData: ''
 }
]
otherAgentsEvents() {
  // Not that relevant currently
  // const events = this.events
  // const user = this.getUser._id
  // const filteredEvents = events.filter(event => !event.agents.includes(user));

  filteredEvents.forEach(event => {
    const agents = event.agents

    agents.forEach(agent => {
      const data = this.fetchAgentData(agent)
      // replace 'event.agents[agent]' with this data
    })
  })

  return filteredEvents
}
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)
  }
}

Edit: as .map function

// But still, how can I replace the agent with the new data?
filteredEvents.map(event => {
  const agents = event.agents
  
  return agents.map(agent => {
    const data = this.fetchAgentData(agent)
    return data
  })
})

Html for better understanding

<div v-for="(event, key) in otherAgentsEvents" :key="key">

  <div v-for="agent in event.agents" :key="agent.id">
    // Currently I haven't access to first_name etc. 
    // only to agent where only the plain ID is stored
    <p>{{ agent.first_name }}</p>
  </div>
  
  <div>
    {{ event.eventData }}
  </div>

</div>

CodePudding user response:

If i didn't misunderstand you have a problem with async operation, forEach method should not use with async operations, I prefer you to use for .. of .. loop instead of it. It can be done with;

for (const event of filteredEvents) {
    for (let agent of event.agents) {
       const data = this.fetchAgentData(agent);
       agent = data;
    }
}

CodePudding user response:

As per my understanding, You want to basically replace the agent id's with the whole agent object based on the id's. If Yes, There could be a two scenario :

  1. If you want to replace all the id's with the respective objects on component load itself. Then you can fetch all the agents data in a single go with a single API and then replace the id's with the objects at client side. (Recommended) as it will improve the performance.
  2. If you want to load the single agent data at a time. i.e. on some event against each id, then you can go for getting the single agent data.

Now, let's talk about the implementation (As per 1st scenario). You can achieve this requirement with the help of Array.map() along with the Array.find() method.

Live Demo :

new Vue({
  el: '#app',
  data: {
    filteredEvents: [
      { 
        agents: [1, 2, 3]
      }
    ]
  },
  mounted() {
    // I am just use mock response, You can replace it with actual API call.
    const apiResponse = [{
      id: 1,
      first_name: 'Agent 1'
    }, {
      id: 2,
      first_name: 'Agent 2'
    }, {
      id: 3,
      first_name: 'Agent 3'
    }, {
      id: 4,
      first_name: 'Agent 4'
    }, {
      id: 5,
      first_name: 'Agent 5'
    }];
    this.filteredEvents = this.filteredEvents.map(obj => {
      const agents = obj.agents;
      obj.agents = agents.map(agentId => {
        return apiResponse.find(({ id }) => id === agentId);
      });
      return obj;
    });
    console.log(this.filteredEvents);
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="(event, key) in filteredEvents" :key="key">
    <div v-for="agent in event.agents" :key="agent.id">
      <p>{{ agent.first_name }}</p>
    </div>
  </div>
</div>

  • Related