-1
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.

2 Answers2

1

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

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • I agree with you and I know that this is the problem but don't know how to solve it. Okay. Thanks. I need that value of Id because I need to make another `conn.query()` right after it. I know it is asynchronous. How can I make it work? I have tried putting whole first conn query in the "if" statement but it still doesn't work. @jfriend00 – Waseem Abbas May 22 '16 at 08:11
  • @WaseemAbbas - If you're trying to do a second `conn.query()` using the results of the first, then please state that in your question. As I've said, we can only help you best when you tell us the REAL problem you're trying to solve. The only way to do that is to put the second `conn.query()` inside the callback of the first. That's the only place the results of the first one are valid. – jfriend00 May 22 '16 at 08:13
  • Okay. I will do it right now. What should be the heading of the question in your opinion? – Waseem Abbas May 22 '16 at 08:14
  • @WaseemAbbas - I still don't really know what your question is about until you edit it to state your actual problem. If it's about doing sequential asynchronous operations, then make the title something about that. – jfriend00 May 22 '16 at 08:30
  • @jsfriend00 I have edited the question, let me know if it makes sense to you this time. – Waseem Abbas May 22 '16 at 08:34
  • @WaseemAbbas - New answer added at the top of my answer. – jfriend00 May 22 '16 at 08:39
  • @jsfriend00 - I tried the same thing myself several times honestly. Indeed I was doing it like this the first time. But It didn't work. What you wrote here makes perfect sense and it should work. But I still wonder why it wasn't working for me earlier. Anyhow its working now and thanks a lot my friend. You were very helpful. I have accepted your answer and upvoted it. – Waseem Abbas May 22 '16 at 08:48
  • @WaseemAbbas - There was just probably some coding mistake in your first attempt. The nesting of requests is subtle. A little wrong bracing and you don't get what you expect. And, wrong indentation can mislead you too (which is why I asked for the code you posted to be properly indented). – jfriend00 May 22 '16 at 08:51
  • @jsfriend00 - And if you think that my current edited question is fine, then please cancel the downvote, otherwise it will deprive me of my ability to ask more questions. – Waseem Abbas May 22 '16 at 08:51
  • @WaseemAbbas - It was never my downvote. Someone else. – jfriend00 May 22 '16 at 08:52
0

You miss the basics of the asynchronous flow in javascript. All the callbacks are set to the end of event loop, so the callback of the conn.query will be executed after console.logs from the outside. Here is a good article where the the basic concepts of asynchronous programming in JavaScript are explained.

Alexandr Lazarev
  • 12,554
  • 4
  • 38
  • 47