Waseem Abbas Waseem Abbas - 6 months ago 15
Node.js Question

How can I execute queries one after the other and extract value from 1st query and use it in the 2nd using expressJS?

router.post("/application_action", function(req,res){
var Employee = req.body.Employee;
var conn = new jsforce.Connection({
oauth2 : salesforce_credential.oauth2
});
var username = salesforce_credential.username;
var password = salesforce_credential.password;
conn.login(username, password, function(err, userInfo, next) {
if (err) { return console.error(err); res.json(false);}
// I want this conn.query to execute first and then conn.sobject
conn.query("SELECT id FROM SFDC_Employee__c WHERE Auth0_Id__c = '" + req.user.id + "'" , function(err, result) {
if (err) { return console.error(err); }

Employee["Id"] = result.records[0].Id;
});
//I want this to execute after the execution of above query i.e. conn.query
conn.sobject("SFDC_Emp__c").update(Employee, function(err, ret) {
if (err || !ret.success) { return console.error(err, ret);}
console.log('Updated Successfully : ' + ret.id);
});
});


I have provided my code above. I need to modify
Employee
in the
conn.query
and use it in
conn.sobject
. I need to make sure that my first query executes before 2nd because I am getting value from 1st and using in the 2nd. Please do let me know if you know how to accomplish this.

Answer

New Answer Based on Edit to Question

To execute one query based on the results of the other, you put the second query inside the completion callback of the first like this:

router.post("/application_action", function (req, res) {
    var Employee = req.body.Employee;
    var conn = new jsforce.Connection({
        oauth2: salesforce_credential.oauth2
    });
    var username = salesforce_credential.username;
    var password = salesforce_credential.password;
    conn.login(username, password, function (err, userInfo, next) {
        if (err) {
            return console.error(err);
            res.json(false);
        }
        // I want this conn.query to execute first and then conn.sobject
        conn.query("SELECT id FROM SFDC_Employee__c WHERE Auth0_Id__c = '" + req.user.id + "'", function (err, result) {
            if (err) {
                return console.error(err);
            }

            Employee["Id"] = result.records[0].Id;
            //I want this to execute after the execution of above query i.e. conn.query
            conn.sobject("SFDC_Emp__c").update(Employee, function (err, ret) {
                if (err || !ret.success) {
                    return console.error(err, ret);
                }
                console.log('Updated Successfully : ' + ret.id);
            });
        });
    });
});

The only place that the first query results are valid is inside that callback because otherwise, you have no way of knowing when those asynchronous results are actually available and valid.

Please note that your error handling is unfinished since you don't finish the response in any of the error conditions and even in the success case, you have not yet actually sent a response to finish the request.

Original Answer

First off, your code shows a route handler, not middleware. So, if you really intend to ask about middleware, you will have to show your actual middleware. Middleware that does not end the request needs to declare next as an argument and then call it when it is done with it's processing. That's how processing continues after the middleware.

Secondly, your console.log() statements are all going to show undefined because they execute BEFORE the conn.query() callback that contains the code that sets those variables.

conn.query() is an asynchronous operation. It calls its callback sometime IN THE FUTURE. Meanwhile, your console.log() statements execute immediately.

You can see the results of the console.log() by putting the statements inside the conn.query() callback, but that is probably only part of your problem. If you explain what you're really trying to accomplish, then we could probably help with a complete solution. Right now, you're just asking questions about flawed code, but not explaining the higher level problem you're trying to solve so you're making it hard for us to give you the best answer to your actual problem.

FYI:

app.locals - properties scoped to your app, available to all request handlers.

res.locals - properties scoped to a specific request, available only to middleware or request handlers involved in processing this specific request/response.

req.locals - I can't find any documentation on this in Express or HTTP module. There is discussion of this as basically serving the same purpose as res.locals, though it is not documented.

Other relevants answers:

req.locals vs. res.locals vs. res.data vs. req.data vs. app.locals in Express middleware

Express.js: app.locals vs req.locals vs req.session