0

I need to get check that given zone exists or not through "getOneParkingZone" function. Can anyone suggest a better way to do this and also explain what this is not working?

 let result = Array.filter(async (zone) =>{
           const checkZone = await getOneParkingZone({id: zone.id})
           return checkZone ? true : false ;
       }));
Rishabh Singh
  • 149
  • 1
  • 6

2 Answers2

2

You need to resolve the promises first, then you can filter them.

Ex:

const ids = [1, 2, 3, 4]


const resolvedPromises = await Promise.all(ids.map(id => getOneParkingZone({id})))

const result = resolvedPromises.filter(item => item)
Mina
  • 14,386
  • 3
  • 13
  • 26
  • 1
    Just be aware of potential thrashing with `promise.all` , it's a shame the ES spec doesn't have a promise map, with a concurrency, a bit like Bluebirds map. It just seems such an obvious addition.. – Keith Jul 13 '22 at 12:27
  • I'm sorry, what do you mean by `potential thrashing with promise.all`? – Mina Jul 13 '22 at 12:33
  • I use the term `thrashing` loosely, from the days of HD and reading too many files at once. But the issue with concurrency can still happen in these days of Web. Maybe an example SO Post will explain better -> https://stackoverflow.com/questions/40639432/what-is-the-best-way-to-limit-concurrency-when-using-es6s-promise-all Not saying your answer is wrong by the way, I just wish `Promise.all` came with some warnings, personally I use `for of`, and then `Promise.all` were it seems more advantageous. – Keith Jul 13 '22 at 13:11
  • I got your point, Yes, I think so. – Mina Jul 13 '22 at 14:09
1

filter needs the callback function to return a truthy or falsy value.

Your callback function returns a promise that resolves to true or false which will always be a truthy value.


Map the array to get the data you need, wait for the promises to resolve, then deal with the new values.

const baseArray = [/*...*/]
const arrayOfPromises = baseArray.map(
    async (value) => ({
        ...value, 
        checkZone: await getOneParkingZone({id: zone.id}) 
    }
);
const arrayWithCheckZone = await Promise.all(arrayOfPromises);
const filteredArray = arrayWithCheckZone.filter(value => value.checkZone);
const filteredArrayWithoutCheckZone = 
    filteredArray.map(value => {
        const { checkZone, ...rest } = value;
        return rest;
    });
);

Or without the extra variables:

(await Promise.all([/*...*/].map(
    async (value) => ({
        ...value, 
        checkZone: await getOneParkingZone({id: zone.id}) 
    }
))).filter(value => value.checkZone).map(value => {
        const { checkZone, ...rest } = value;
        return rest;
    });
);
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335