Eugene Goldberg
Eugene Goldberg

Reputation: 15524

how to properly handle variable scope in AngularJS

In my AnlgularJS controller, my first order of business is to determine if the app is running in dev, or test.

For that purpoer, I make a call to an api, an an answer back (that part is verified to work).

Depending on the environment, I need to set the value for the $scope.uploadUrl, so my file uploader directive would know which url is to target for its file uploads.

For some reason, by the time the uploader is executed, that url value is lost.

Here is the relevant part of my controller:

$scope.uploadUrl = '';

        console.log('This is FileUploadController');

        function getEnvironment (){
            $http.get('/environment').success(function(response) {
               $scope.currentEnvironment = response.environment;
                if(response.environment === 'test'){
                   $scope.uploadUrl = 'http://test_url:3001/api/files';
                }
                if(response.environment === 'dev'){
                  $scope.uploadUrl = 'http://dev_url:3000/api/files';
                }
                console.log('Current Environment is:  ' + $scope.currentEnvironment
                + '  so the uploadUrl should be:  ' + $scope.uploadUrl);
            });
        }

        getEnvironment();

        var selectedCategory;
        var selectedDataVersion;

        var uploader = $scope.uploader = new FileUploader({
            //url: 'http://dctool-lnx.cloudapp.net:3001/api/files',
            url:    $scope.uploadUrl,
            tabName: 'sheet1'
        });

What is the proper way to re-structure this code, to make the value, set within my getEnvironment function to live long enough?

Upvotes: 1

Views: 39

Answers (2)

alexandergs
alexandergs

Reputation: 192

I don't think your problem has to do with the life time. The problem I see there is that, when you create your uploader, the AJAX call has not returned yet.

Try this:

    $scope.uploadUrl = '';
    $scope.uploader;

    var selectedCategory;
    var selectedDataVersion;
    var uploader;

    console.log('This is FileUploadController');

    function initUploader()
    {
       uploader = $scope.uploader = new FileUploader({
            //url: 'http://dctool-lnx.cloudapp.net:3001/api/files',
            url:    $scope.uploadUrl,
            tabName: 'sheet1'
        });
    }
    function getEnvironment (){
        $http.get('/environment').success(function(response) {
           $scope.currentEnvironment = response.environment;
            if(response.environment === 'test'){
               $scope.uploadUrl = 'http://test_url:3001/api/files';
            }
            if(response.environment === 'dev'){
              $scope.uploadUrl = 'http://dev_url:3000/api/files';
            }
            initUploader();
            console.log('Current Environment is:  ' + $scope.currentEnvironment
            + '  so the uploadUrl should be:  ' + $scope.uploadUrl);
        });
    }

    getEnvironment();

Upvotes: 1

PSL
PSL

Reputation: 123739

For some reason, by the time the uploader is executed, that url value is lost.

Not really, actual reason is by the time uploaded is executed, url value has not been assigned yet because the operation that assigns the value is async (AsycJAX) in nature.

So basically you need to wait for that operation to complete, you can do so by utilizing the promise returned by the operation.

    //return promise from the function
    function getEnvironment (){
      return  $http.get('/environment')....
    }

    //Make a call chain it through and register runUploader
    getEnvironment().then(runUploader);

    var selectedCategory;
    var selectedDataVersion;

    function runUploader(){
       var uploader = $scope.uploader = new FileUploader({
         //url: 'http://dctool-lnx.cloudapp.net:3001/api/files',
         url:    $scope.uploadUrl,
         tabName: 'sheet1'
       });
    }

Upvotes: 2

Related Questions