Problem filling object with node and mongodb

3

I have the following function

function getParadas(req,res){

  var find;
  let paradas ={
    paradasMetro:[],
    paradasCercanias:[],
    paradasBus:[]
  }
  var find1= ParadasMetro.find().sort('nombre_parada');
  var find2= ParadasCercanias.find().sort('nombre_parada');
  var find3= ParadasBus.find().sort('nombre_parada');

    find1.exec((err,paradasM) => {
      if(err){
        console.log('Error en la peticion(Paradas metro)');
      }else{
        if(!paradasM){
          console.log('No hay paradas de metro');
        }else{
          paradas.paradasMetro=paradasM;
        }
      }
    });

    find2.exec((err,paradasC) => {
      if(err){
        console.log('Error en la peticion(Paradas cercanias)');
      }else{
        if(!paradasC){
          console.log('No hay paradas de cercanias');
        }else{
          paradas.paradasCercanias=paradasC;
          console.log(paradas);
        }
      }
    });

    find3.exec((err,paradasB) => {
      if(err){
        console.log('Error en la peticion(Paradas bus)');
      }else{
        if(!paradasB){
          console.log('No hay paradas de bus');
        }else{
          paradas.paradasBus=paradasB;
        }
      }
    });
    console.log(paradas);

      res.status(200).send({
      paradasResponse:paradas,
    });

}

My problem is when filling the object paradas . When it reaches the console.log(paradas) of inside the function find2.exec() it paints me the following:

{ paradasMetro: [],
  paradasCercanias:
   [ { _id: 598c9fe410ebd9a7a9445c52,
       nombre_parada: 'Aeropuerto T4',
       lineas: '1' },
    /*Muchas mas paradas*/
     { _id: 598c9fe410ebd9a7a9445bf2,
       nombre_parada: 'Zarzaquemada',
       lineas: '5' } ],
  paradasBus: [] }

That is, I recognize the object paradas created above but I restart it in the execution of each find#.exec since by the time it has reached this console.log() has already passed the find1.exec() and has had to fill the paradas.paradasMetro , but I painted it empty. And when it reaches the console.log() of the end, it paints all the empty objects

{ paradasMetro: [], paradasCercanias: [], paradasBus: [] }

Any idea why it can be?

Thanks in advance!

    
asked by Hictus 10.08.2017 в 20:44
source

2 answers

2

It seems that it is because your queries are made asynchronously, not synchronously. That is, your res.status (200) .send () is executed at the end while the queries may or may not have finished their operations and changed your object .

First, I recommend restructuring your requests like this:

 find1.exec((err,paradasM) => {
  if(err)
    console.log('Error en la peticion(Paradas metro)');

  if(!paradasM){
    console.log('No hay paradas de metro');

  paradas.paradasMetro=paradasM;
});

It's cleaner without having many keys.

And second, you can place the nested callbacks but it will give you a callback hell (anti pattern that makes you the unbeatable code), so I suggest using promises, you can consult about them here or here

    
answered by 11.08.2017 / 23:53
source
2

Even if there is already an accepted answer, I will give you an example using promises and asynchronous functions. This you can use it from Node 7.8 onwards.

  

Do not use models in the drivers. This is a bad practice; makes your code more coupled and difficult to manage. Each model must have its respective service that will be used by the controllers.

Your code can be very simplified if you start using ES6 +:

exports.getParadas = async () => {
  const paradas = {};

  try {
    paradas.metro = await ParadasMetro.find().sort('nombre_parada');
    paradas.cercanias = await ParadasCercanias.find().sort('nombre_parada');
    paradas.bus = await ParadasBus.find().sort('nombre_parada');
    return paradas;
  } catch (e) {
    throw e;
  }
};

router.get('/paradas', (req, res) => {
  service
    .getParadas()
    .then(paradas => res.jsonp(paradas))
    .catch(e => res.status(500).send(e.message));
});

Regarding what they told you about the keys, it is personal preference, however, most styles recommend us to use them ( reference to ESLint ).

    
answered by 12.08.2017 в 16:56