user1674957
user1674957

Reputation: 21

azure mobile api variable scope

I have the following Azure Mobile Services API get function. I want to set the isValidUser flag based on if there is a record for the providerKey (from the twitter authentication) in the SQLMembership table (AspNetUserLogins).

While testing, I see the following in the log file, confirming that the flag is being set. "setting isValidUser [object Object] Number of records = 1"

However, if(isValidUser) is not getting evaluated correctly. The result I get from the API is "Not a registered user." which is set from the else portion of the if(isValidUser) check.

Why is it that the value set inside the mssql.query() is not available outside of it?

exports.get = function(request, response) {
    var authenticatedUserId = request.user.userId;

    var providerName = authenticatedUserId.split(":")[0];
    var providerUserId = authenticatedUserId.split(":")[1];
    var isValidUser = false;


    console.log('providerName = ' + providerName.trim());
    console.log('providerUserId = ' + providerUserId.trim());
    request.service.mssql.query(
        "select userId from dbo.AspNetUserLogins where LoginProvider = '" + providerName + "' and ProviderKey = '" + providerUserId + "'",
           {
                success: function(results)
                {
                    console.log('inside success AspNetUserLogins. ' + results + " Number of records = " + results.length);
                    if (results.length == 1) {
                        console.log('setting isValidUser ' + results + " Number of records = " + results.length);
                        isValidUser = true;
                    }
                },
                error : function(err)
                {
                    console.log('inside error AspNetUserLogins. ' + err);
                    response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: err });
                }
            }
        );
    if (isValidUser) {
        request.service.mssql.query('select * from dbo.Church',
            {
                success: function(results)
                {
                    console.log('inside success Church' + results);
                    response.json(statusCodes.OK, results);
                },
                error : function(err)
                {
                    console.log('inside error : ' + err);
                    response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: err });
                }
            }
        );
    } else {
        response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: "Not a registered user." + isValidUser });
    }

    response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: "Unexpected end." });
};

Upvotes: 0

Views: 554

Answers (1)

carlosfigueira
carlosfigueira

Reputation: 87228

The call to mssql.query is an asynchronous function (like many other functions in node.js); when it returns the callback (either the success or the error) hasn't been executed yet, so when you check the isValidUser flag, it still has the original value (false).

What you need to do is to move that code to inside the success callback, and that should work:

exports.get = function(request, response) {
    var authenticatedUserId = request.user.userId;

    var providerName = authenticatedUserId.split(":")[0];
    var providerUserId = authenticatedUserId.split(":")[1];
    var isValidUser = false;


    console.log('providerName = ' + providerName.trim());
    console.log('providerUserId = ' + providerUserId.trim());
    var sql = "select userId from dbo.AspNetUserLogins where LoginProvider = ? and ProviderKey = ?";
    var sqlParams = [providerName, providerUserId];
    request.service.mssql.query(sql, sqlParams, {
        success: function(results)
        {
            console.log('inside success AspNetUserLogins. ' + results + " Number of records = " + results.length);
            if (results.length == 1) {
                console.log('setting isValidUser ' + results + " Number of records = " + results.length);
                isValidUser = true;
            }
            if (isValidUser) {
                request.service.mssql.query('select * from dbo.Church', {
                    success: function(results)
                    {
                        console.log('inside success Church' + results);
                        response.send(statusCodes.OK, results);
                    },
                    error : function(err)
                    {
                        console.log('inside error : ' + err);
                        response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: err });
                    }
                });
            } else {
                response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: "Not a registered user." + isValidUser });
            }
        },
        error : function(err)
        {
            console.log('inside error AspNetUserLogins. ' + err);
            response.send(statusCodes.INTERNAL_SERVER_ERROR, { error: err });
        }
    });
};

One more thing: do use parameters in the SQL (also shown above), instead of composing the query directly. In this case (you're using the user id) it shouldn't be a problem, but as a general rule you should use parameters whenever possible to prevent SQL injection attacks.

Upvotes: 1

Related Questions