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)});
});
2
  • I believe that this answer your question. Commented Oct 23, 2017 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). Commented Oct 23, 2017 at 15:20

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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.
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
Looking at the edit now it looks like you've figured it out? @GaetanL'Hoest
Yep, thanks to you, you took me on the right path. Thanks again
Great! Please mark the answer as correct if it helped.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.