Search code examples
javascriptscopemonacaorder-of-execution

Javascript function scope / order of execution issue


I'm having an issue with the javascript scope / order of execution. I create an empty object inside a function. Then I add some properties in a child function. The properties haven't changed in the parent function, though.

$scope.finder = function (obj) {

    var id = obj.oid;

    var crit = MC.Criteria('_ownerUserOid == ?', [id]);

    theResult = {}; // Scope should be finder function.

    database.findOne(crit) // This is a Monaca method for finding from database

    .done(function(result) {
        // Returns and empty object as expected.
        console.log(JSON.stringify(theResult));

        theResult = result;

        // Returns the search result object as again expected.
        console.log(JSON.stringify(theResult));
    });



// Here's the issue - when I log and return theResult, I get an empty object again.
// I think it has to do something with the scope.
// Also, this logs to console before either of the console.logs in the done function.

    console.log(JSON.stringify(theResult));
    return theResult;


};

Solution

  • It looks like you are performing an asynchronous request for some data. Any time you are performing asynchronous JavaScript, you will need to keep in mind that things aren't called sequentially. When an asynchronous call is made, JavaScript will carry on executing code down the stack.

    In your case, theResult will be an empty object because database.findOne(crit) has not finished executing by the time you call console.log(JSON.stringify(theResult));

    Because of this, you cannot return from $scope.finder, instead you could pass a callback into $scope.finder and execute that once database.findOne(crit) has finished executing.

    $scope.finder = function (obj, callback) {
    
        var id = obj.oid;
    
        var crit = MC.Criteria('_ownerUserOid == ?', [id]);
    
        theResult = {}; // Scope should be finder function.
    
        database.findOne(crit) // This is a Monaca method for finding from database
    
            .done(function(result) {
                // Returns and empty object as expected.
                console.log(JSON.stringify(theResult));
    
                theResult = result;
    
                callback(theResult);
    
                // Returns the search result object as again expected.
                console.log(JSON.stringify(theResult));
            });
    };
    

    Then call it like this.

    $scope.finder({some: 'data'}, function(response) {
        // response now has the values of theResult
        console.log(response)
    });