Ricardo Swarovsky Ricardo Swarovsky - 16 days ago 5
Javascript Question

How to send a object array with promise [SOLVED]

I have tried a lot and didn't get anything that works good for me.
I tried with promise.all and setting the array globally, but with no success.

I want to search in three collections on MongoDB and when the find matches, set an object with the infos and push to an array. At the end, send a response with the objects array.

router.post('/certificado', (req, res) => {
let cpf = splita(req.body.cpf)
let array = []

function pesquisaProjeto(cpf) {
return new Promise(function (fulfill, reject) {
ProjetoSchema.find({'integrantes.cpf':cpf}, 'integrantes.$ nomeProjeto -_id',(err, usr) => {
if (err) return reject(err)
fulfill(usr)
});
})
}

function pesquisaAvaliador(cpf) {
return new Promise(function (fulfill, reject) {
avaliadorSchema.find({'cpf':cpf}, 'nome -_id',(err, usr) => {
if (err) return reject(err)
fulfill(usr)
})
})
}

function pesquisaParticipante(cpf) {
return new Promise(function (fulfill, reject) {
participanteSchema.find({'cpf':cpf}, 'nome eventos -_id', (err, usr) => {
if (err) return reject(err)
fulfill(usr)
})
})
}

pesquisaProjeto(cpf)
.then(usr => {
let participante = ({
tipo: usr[0].integrantes[0].tipo,
nome: usr[0].integrantes[0].nome
})
array.push(participante)
console.log(participante)
})
.catch(err => console.log("Não encontrou nada nos projetos. " + err.message))

pesquisaAvaliador(cpf)
.then(usr => {
let participante = {
tipo: "Avaliador",
nome: usr[0].nome
}
array.push(participante)
console.log(array)
})
.catch(err => console.log("Não encontrou nada nos avaliadores. " + err.message))

pesquisaParticipante(cpf)
.then(usr => {
let participante = ({
tipo: "Participante",
nome: usr[0].nome,
eventos: usr[0].eventos
})
array.push(participante)
console.log(array)
})
.catch(err => console.log("Não encontrou nada nos participantes dos eventos. " + err.message))

**Anything like res.send(array) that I was tired to try**
});


Sorry for the stupid doubt, but I've spent so much time trying to find the solution that I decided to resort to the community.

Thanks!




Solution



Thanks to errnesto;
Created variables to receive the continuity of the promises and added
Promise.all
to send all the objects on finish, filtering the undefined ones.

router.post('/certificado', (req, res) => {
let cpf = splita(req.body.cpf)
let array = []

function pesquisaProjeto(cpf) {
return new Promise(function (fulfill, reject) {
ProjetoSchema.find({'integrantes.cpf':cpf}, 'integrantes.$ nomeProjeto -_id',(err, usr) => {
if (err) return reject(err)
fulfill(usr)
});
})
}

function pesquisaAvaliador(cpf) {
return new Promise(function (fulfill, reject) {
avaliadorSchema.find({'cpf':cpf}, 'nome -_id',(err, usr) => {
if (err) return reject(err)
fulfill(usr)
})
})
}

function pesquisaParticipante(cpf) {
return new Promise(function (fulfill, reject) {
participanteSchema.find({'cpf':cpf}, 'nome eventos -_id', (err, usr) => {
if (err) return reject(err)
fulfill(usr)
})
})
}

const one = pesquisaProjeto(cpf).then(usr => ({
tipo: usr[0].integrantes[0].tipo,
nome: usr[0].integrantes[0].nome
}))
.catch(err => console.log("Não encontrou nada nos projetos. " + err.message))

const two = pesquisaAvaliador(cpf).then(usr => ({
tipo: "Avaliador",
nome: usr[0].nome
}))
.catch(err => console.log("Não encontrou nada nos avaliadores. " + err.message))

const three = pesquisaParticipante(cpf).then(usr => ({
tipo: "Participante",
nome: usr[0].nome,
eventos: usr[0].eventos
}))
.catch(err => console.log("Não encontrou nada nos participantes dos eventos. " + err.message))

Promise.all([one, two, three])
.then(arr => {
res.send(arr.filter(val => val !== undefined ))
})
});

Answer

If I understand your question right you have multiple promises and want to wait for all of them to finish. You can do that with Promise.all().

If one Promise will fail Promise.all() will also fail. But if you catch them like you do in your example and return nothing I think the Array should be populated with undefined for that Query. So you could then filter those empty values out if you want to.

const one = dbQueryOne.then(usr => ({
  key: usr.val
}))
.catch(err => { console.log(err) })

const two = dbQueryTwo.then(usr => ({
  key: usr.val
}))
.catch(err => { console.log(err) })

const three = dbQueryThree.then(usr => ({
  key: usr.val
}))
.catch(err => { console.log(err) })

Promise.all([one, two, three]).then(arr => {
  res.send(arr.filter(val => val !== undefined ))
})

usr => ({ key: val }) is just short for usr => { return { key: val } }