How can I insert into a new arr promise values of an old array. A splice method required due to vue reactivity. Somehow the newArray is empty and not getting the any values. https://codesandbox.io/s/sweet-sammet-fyomv0?file=/src/components/Example2.vue
<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: {
async send() {
let newArr = await Promise.allSettled(
this.ids
.map(fakeApiRequest)
.filter((promise) => promise.status === "fulfilled")
.map((promise) => promise.value)
);
// console.log(newArr) --> gets an empty array
this.successIds.splice(0, 0, newArr);
},
},
};
</script>
<style scoped>
.out {
margin: 20px 0;
color: #41b883;
}
</style>
Several issues:
You are applying a .filter
call on the promises returned by the .map
call, but promises don't have a status
property to filter by. You can only filter on the resolved values, not on the promises. So you first need to await the resolution of the allSettled
promise before you can start filtering.
splice
expects the insert-values as individual arguments, not as an array. So use the spread syntax
As you want to populate your successIds
with id
values, and your api returns objects with id
and success
properties, you still need to extract that id
property from each object.
Here is a correction (I removed the vue dependecies):
const fakeApiRequest = (id) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = id % 2;
success ? resolve({ id, success}) : reject({ success });
}, 200);
});
};
const app = {
data() {
return {
// Fetch ids
ids: [1, 2, 3, 4, 5, 6],
// Complete ids
successIds: [],
};
},
methods: {
async send() {
const results = await Promise.allSettled(
this.ids.map(fakeApiRequest)
);
const ids = results.filter((settled) => settled.status === "fulfilled")
.map((settled) => settled.value.id);
this.successIds.splice(0, 0, ...ids);
console.log(this.successIds); // for this demo only
},
},
};
// Mimic vue
app.methods.send.call(app.data());