arraysvue.jspromisesetresolve

Iterating through an array with a fakeAPI promise function Vue.js


<template>
  <div class="hello">
    <h1>Example 2</h1>
    <input @click="send" type="button" value="Send" />
    <div class="out" v-if="successIds.length">{{ successIds }}</div>
  </div>
</template>

<script>
/*
@return
  resolve: { id: 1, success: true }
  or
  reject: { success: false }
*/

const fakeApiRequest = (id) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = id % 2;
      success ? resolve({ id, success }) : reject({ success });
    }, 2000);
  });
};

export default {
  data() {
    return {
      // Fetch ids
      ids: [1, 2, 3, 4, 5, 6],
      // Complete ids
      successIds: [],
    };
  },
  methods: {
  // iterating through the ids array    
    newValues(id) {
      this.ids.forEach((el) => el.this.fakeApiRequest(id));
    },
  // filling the successIds array
    send(id) {
      this.$set(this, "successIds", this.newValues(id));
    },
  },
};
</script>

How can I fill and display the successId array in the template with the iterated elements of the existing array using Promise function within a $set Vue method? I seem to fail trying to reach the fakeApiRequest in the newValues function.


Solution

  • I'm not sure why you think you need to use the $set method. There are clear documented uses for it, and setting/replacing an array is not one. Besides that though, to be frank, there are a lot of issues with your code, and it's not very clear what you're trying to do, but I did my best to correct all the issues and left comments describing my changes.

    sandbox example

    <template>
      <div class="hello">
        <h1>Example 2</h1>
        <input type="button" value="Send" @click="send" />
        <div v-if="successIds.length" class="out">{{ successIds }}</div>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          // Fetch ids
          ids: [1, 2, 3, 4, 5, 6],
          // Complete ids
          successIds: []
        };
      },
      methods: {
        // note 1: method loops through all ids so not sure what the 'id' param is for
        // note 2: calling other async methods requires we use 'async' and 'await' keywords
        async newValues(id) {
          // note 3: the code in this method before was non-sensical to me, e.g. "el.this.fakeApiRequest" isn't valid syntax
          // and the forEach loop didn't do anything with the actual result returned by fakeApiRequest.
          // note 4: forEach actually isn't designed for async code. Must use normal for loop
          const results = [];
          for (let i = 0; i < this.ids.length; i++) {
            let res = null;
            try {
              res = await this.fakeApiRequest(this.ids[i]);
            } catch (rejectVal) {
              res = rejectVal;
            }
            console.log('res', res);
            results.push(res);
          }
          return results;
        },
        // note 5: not sure why id is a param as this method isn't called with any specific id
        async send(id) {
          // note 6: the use of $set before was unnecessary
          this.successIds = await this.newValues();
        },
        /*
        @return
          resolve: { id: 1, success: true }
          or
          reject: { success: false }
        */
        // note 7: moved this here so it can be called by other methods. decreased timeout time for sanity's sake
        fakeApiRequest(id) {
          return new Promise((resolve, reject) => {
            setTimeout(() => {
              const success = id % 2;
              success ? resolve({ id, success }) : reject({ success });
            }, 100);
          });
        }
      }
    };
    </script>