title: Vue.js/Axios - Duplicate results in list. Has unique-keys in v-for
body: <p>I have two other uses of v-for in separate components. They also sometimes throw errors. All three v-for invocations are wrapped with v-if/else. Here is the code that produces duplicate key errors &amp; renders data twice:</p>
  
  <p><strong>AccountDashboard.vue</strong></p>
  
  <pre><code>&lt;tbody&gt;
    &lt;tr v-if="!residents.length" class="table-info"&gt;
      &lt;td class="text-center"&gt;
        &lt;p&gt;
          No residents on record. 
        &lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;template v-else&gt;
      &lt;tr is="AccountResidentList"
        v-for="resident in residents"
        v-bind:key="'resident-list-' + resident.id"
        v-bind:first_name="resident.first_name"
        v-bind:last_name="resident.last_name"
        v-bind:dob="resident.dob | date_formatted"
        &gt;
      &lt;/tr&gt;
    &lt;/template&gt;
  &lt;/tbody&gt;
  </code></pre>
  
  <p>Note the unique id attempt in the binding of key.</p>
  
  <p>Here is a look at the child component</p>
  
  <p><strong>ProviderAccountList.vue</strong></p>
  
  <pre><code>&lt;template&gt;
    &lt;tr class="AccountResidentList"&gt;
      &lt;td&gt;
        {{ this.$attrs.id }}
      &lt;/td&gt;
      &lt;td&gt;
        {{ this.$attrs.first_name }} {{ this.$attrs.last_name }}
      &lt;/td&gt;
      &lt;td&gt;
        {{ this.$attrs.dob }}
      &lt;/td&gt;
      &lt;td&gt;
        &lt;button @click="toResidentProfile({account_id, id})" class="btn btn-sm btn-purple btn-with-icon"&gt;
          &lt;div class="ht-25"&gt;
           &lt;span class="icon wd-25"&gt;&lt;i class="fa fa-eye"&gt;&lt;/i&gt;&lt;/span&gt;
           &lt;span class="pd-x-10"&gt;view&lt;/span&gt;
         &lt;/div&gt;
        &lt;/button&gt;
      &lt;/td&gt;
      &lt;!--TODO: Add view profile button--&gt;
    &lt;/tr&gt;
  &lt;/template&gt;
  
   &lt;script&gt;
   import Axios from "axios";
   import router from "../../router";
   import { mapGetters } from "vuex";
   import moment from "moment";
  
   export default {
    name: "AccountResidentList",
    computed: {
      ...mapGetters['Resident', {
        resident: 'getResident'
      }]
    },
    filters: {
      date_formatted: (date) =&gt; {
        return moment(date).format('MMMM Do, YYYY');
      }
    },
    methods: {
      toResidentProfile(account_id, resident_id) {
        router.push(`/accounts/${account_id}/residents/${resident_id}`)
      }
    },
  };
   &lt;/script&gt;
   &lt;style scoped&gt;&lt;/style&gt;
  </code></pre>
  
  <p>My Axios call looks like:</p>
  
  <p><strong>Account.js</strong> <em>(a namespaced vuex-module)</em></p>
  
  <pre><code>  async retrieveAccount(context, account_id) {
        // Axios.defaults.headers.common['Authorization'] = 'Bearer ' + window.$cookies.get('jwt')
        let response
        let valid_id = window.$cookies.get('valid_id');
        response = await Axios.get(`http://localhost:3000/api/v1/providers/${valid_id}/accounts/${account_id}`, { headers: { 'Authorization': 'Bearer ' + window.$cookies.get('jwt') } })
        .then((response) =&gt; {
          let account = response.data.locals.account;
          let account_address = response.data.locals.account_address;
          let residents = response.data.locals.residents;
          // set Account
          context.dispatch('Account/setId', account.id, {root: true});
          context.dispatch('Account/setProviderId', account.provider_id, {root: true});
          .
          .
          .
  
          // set AccountAddress
          // !Array.isArray(array) || !array.length
          if (account.address) {
            context.dispatch('Account/setAddressId', account_address.id, {root: true});
            context.dispatch('Address/setId', account_address.id, {root: true});
          .
          .
          . 
  
          // set AccountResidents
          // !Array.isArray(array) || !array.length
          residents.forEach(resident =&gt; {
            if (resident) {
              // Add object to parent's list
              context.dispatch('Account/setResidents', resident, {root: true});         // Set attr values for object
              context.dispatch('Resident/setId', resident.id, {root: true});
              .
              .
              .
              (remaining attrs removed for brevity)
            }
          })
  
          router.push(`/providers/${account.provider_id}/accounts/${account_id}`);
        })
        .catch(function(error) {
          console.log(error);
        })
  </code></pre>
  
  <p>Note: the Account action #setResidents simply calls the mutator that adds one resident to a list total. </p>
  
  <p><code>i.e state.list.push(resident)</code></p>
  
  <p>I logged the response to the console and can confirm that the data isn't being sent twice (or more) from my Axios call.</p>
  
  <p><a href="https://i.stack.imgur.com/OSJpI.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/OSJpI.png" alt="console.log results"></a></p>
  
  <p>I have reviewed &amp; attempted the following to no avail:</p>
  
  <ul>
  <li><p><a href="https://alligator.io/vuejs/iterating-v-for/" rel="nofollow noreferrer">https://alligator.io/vuejs/iterating-v-for/</a></p></li>
  <li><p><a href="https://www.reddit.com/r/vuejs/comments/7n3zi4/vue_warn_duplicate_keys_detected_vfor_with/" rel="nofollow noreferrer">https://www.reddit.com/r/vuejs/comments/7n3zi4/vue_warn_duplicate_keys_detected_vfor_with/</a></p></li>
  <li><p><a href="https://github.com/hejianxian/vddl/issues/23" rel="nofollow noreferrer">https://github.com/hejianxian/vddl/issues/23</a></p></li>
  <li><p><a href="https://github.com/hejianxian/vddl#warning" rel="nofollow noreferrer">https://github.com/hejianxian/vddl#warning</a></p></li>
  <li><a href="https://medium.com/@chiatsai/vue-js-common-issue-duplicate-keys-stops-components-rendering-df415f31838e" rel="nofollow noreferrer">https://medium.com/@chiatsai/vue-js-common-issue-duplicate-keys-stops-components-rendering-df415f31838e</a></li>
  </ul>
  
  <p>Finally, It should be mentioned that I have tried variations of using/not using <code>template</code> to wrap the list, including/not including the for loop in the <code>template</code>, etc..</p>
  
  <p>Did not anticipate it would be this bothersome to iterate a collection.</p>
  
  <p>Am I overlooking something obvious? </p>
  
  <p><strong>Update: What worked for me</strong></p>
  
  <p>I needed access to the resident.id also the id declared in the paren seems like an index. So here is a look at what removed the duplicate render errors and allow me access to the resident's id even after fixing the duplicate keys error:</p>
  
  <pre><code>&lt;template v-else&gt;
    &lt;tr is="AccountResidentList"
      v-for="(resident, id) in residents"
      v-bind:key="id"
      v-bind:id="resident.id"
      v-bind:first_name="resident.first_name"
      v-bind:last_name="resident.last_name"
      v-bind:dob="resident.dob | date_formatted"
    &gt;
    &lt;/tr&gt;
  &lt;/template&gt;
  </code></pre>
  
  <p>Thanks again @Billal Begueradj for the assist!</p>