0

I'm new to javascript and I'm strugguling with synchonous/asynchronous function call, especially here, as i'm trying to concatenate data from two collections of the same database.

Here is my code:

function getAcquisitionAreas(req) {
  PartAreas.getAcquisitionAreasByAcquisitionId(req.params.id, (err, partArea) => {
    particle.areas = partArea._doc.areas;
  });
}

function getAcquisitionPerimeters(req) {
  PartPerimeters.getAcquisitionPerimetersByAcuiqisiontId(req.params.id, (err, partPerimeter) => {
    particle.borders_intern = partPerimeter._doc.borders_intern;
    particle.borders_extern = partPerimeter._doc.borders_extern;
  });

}

function getParticleData(req, callback) {
  getAcquisitionAreas(req);
  getAcquisitionPerimeters(req);
  callback;
}

function constructParticle(req) {
  particle.id = req.params.id;
}

// Register
router.get('/get/:id', (req, res, next) => {
  getParticleData(req);
  constructParticle(req);
  res.send(particle);
});

and it returns {"id":"1508515120"}, this means it execute res.send(particle) before putting in areas and borders. How should I implement this? I've seen Promises but couldn't make it work, and implementing callback methods in callback methods seems very dirty.

Thanks!

Edit

var particle;

function getAcquisitionAreas(req) {
    return new Promise((resolve, reject) => {
    PartAreas.getAcquisitionAreasByAcquisitionId(req.params.id, (err, partArea) => {
            if (err) { reject(err); }

        particle.areas = partArea._doc.areas;
        resolve();
    });
});
}

function getAcquisitionPerimeters(req) {
    return new Promise((resolve, reject) => {
    PartPerimeters.getAcquisitionPerimetersByAcuiqisiontId(req.params.id, (err, partPerimeter) => {
        if (err) { reject(err); }

        particle.borders_intern = partPerimeter._doc.borders_intern;
        particle.borders_extern = partPerimeter._doc.borders_extern;
        resolve();

    });
   })
}

function constructParticle(req) {
    return new Promise((resolve, reject) => {
    particle.id = req.params.id;
        resolve();
    })
}

function sendParticle(res) {
    res.send(particle);
}

// Register
router.get('/get/:id', (req, res, next) => {
    particle = {};
    getAcquisitionAreas(req)
        .then(getAcquisitionPerimeters(req))
        .then(constructParticle(req))
        .then(sendParticle(res));
});

Edit 2

I finally managed to have a working solution:

function getAcquisitionAreas(particle) {
    return new Promise((resolve, reject) => {
    PartAreas.getAcquisitionAreasByAcquisitionId(particle.id, (err, partArea) => {
            if (err) { reject(err); }

        particle.areas = partArea._doc.areas;
        resolve(particle);
    });
});
}

function getAcquisitionPerimeters(particle) {
    return new Promise((resolve, reject) => {
    PartPerimeters.getAcquisitionPerimetersByAcuiqisiontId(particle.id, (err, partPerimeter) => {
        if (err) { reject(err); }
        else {        
            particle.borders_intern = partPerimeter._doc.borders_intern;
            particle.borders_extern = partPerimeter._doc.borders_extern;
            resolve(particle);
        }
    });
   })
}



// Register
router.get('/get/:id', (req, res, next) => {
    particle = {"id":req.params.id};
    getAcquisitionAreas(particle)
        .then(getAcquisitionPerimeters)
        .then((particle) => {res.send(particle)});
});
  • I believe that [this](https://stackoverflow.com/a/4700433/863110) answer your question. – Mosh Feu Oct 23 '17 at 15:12
  • 1
    Perhaps you should focus on why promises werent working and how to get them to work, it seems that's what they're use for (what you're trying to accomplish). – jdmdevdotnet Oct 23 '17 at 15:20

1 Answers1

0

There are several ways of achieving this(Promises, Yield, Async/Await). You've tried Promises, so let's go through that. I've made some assumptions here, and there are neater ways of doing it, but given what you posted the code sample below should get you most if not all the way there I think.

function getAcquisitionAreas(req) {
    return new Promise((resolve, reject) => {
    PartAreas.getAcquisitionAreasByAcquisitionId(req.params.id, (err, partArea) => {
            if (err) { return reject(err); }

        particle.areas = partArea._doc.areas;
        resolve();
    });
});
}

function getAcquisitionPerimeters(req) {
    return new Promise((resolve, reject) => {
    PartPerimeters.getAcquisitionPerimetersByAcuiqisiontId(req.params.id, (err, partPerimeter) => {
            if (err) { return reject(err); }
        particle.borders_intern = partPerimeter._doc.borders_intern;
        particle.borders_extern = partPerimeter._doc.borders_extern;
        resolve();
        });
   })
}

function getParticleData(req, callback) {
    getAcquisitionAreas(req)
        .then(getAcquisitionPerimeters(req));
        .then(callback);
}

function constructParticle(req) {
    particle.id = req.params.id;
}

// Register
router.get('/get/:id', (req, res, next) => {
    getParticleData(req, () => {
        constructParticle(req);
            res.send(particle);
    });
});

I'm not doing things like catching the errors thrown when the promises are rejected, and to me it seems strange to switch from promises to a callback in the middle, but hopefully the example above will give you a basic idea of how to use them.

CD-jS
  • 1,125
  • 1
  • 15
  • 32
  • Thanks ! Since you seems to know your subject, I also saw something like an async array, where you could put your functions and they would be executed sequentially. Does it ring a bell to you ? I saw it in a youtube video and can't find it back. I found async-arrays on npm but it doesn't seems to be it. – Gaetan L'Hoest Oct 23 '17 at 16:23
  • Hi, I tried your code and could not have both areas and perimeters, I only had areas. Tried to improve my code according to your suggestion, but it does not work. I have really no idea why i don't get no area or perimeters now. My new code is in the question, under edit tag – Gaetan L'Hoest Oct 24 '17 at 09:37
  • Looking at the edit now it looks like you've figured it out? @GaetanL'Hoest – CD-jS Oct 24 '17 at 11:51
  • Yep, thanks to you, you took me on the right path. Thanks again – Gaetan L'Hoest Oct 25 '17 at 12:00
  • Great! Please mark the answer as correct if it helped. – CD-jS Oct 25 '17 at 12:16