1

Dear AngularJS savies,

How to set $scope.data in the controller having a promise returned from a factory. All I can do is work with the data returned in the scope of the method of the factory's object and I cannot "load" the data in a value existing in the controller's scope. How can I pass the data into controller's scope?

The code sequences as following This is the factory:

var features = {};        
        // the method returns a promise tot he controller needed to be delt with .then()
        features.getPromise = function(){
            //make a promise
            var promise = $http({method: 'GET', url: '../../LIBS/inc/getAllGeoFeatures.php'})
                .success(function(data, status, headers, config){
                    return data;
                })
                .error(function(data, status, headers, config){
                    $log.warn(data, status, headers, config);
                });
            return promise;
        };

This is the controller:

$scope.data = 'null';

        factGetFeat.getPromise().then(function(promise){

            $scope.data = promise;
            $log.info($scope.data);  //gets the object all right
           // here I can work with the data but I cannot share it with the controller
           // i.e. with the view
        });

        $log.info($scope.data); //$scope.data is still null and I need it loaded with the data

I need some counceling because I sense I go nowhere

I even tried to load $scope.data with the outcome of the method, but I only get the promsise object and not the data:

Object {then: function, catch: function, finally: function}

Please advise.

P.S. I use angular 1.2.x

Thank you very much for your time and patience.

2 Answers 2

1

It should be

factGetFeat.getPromise().then(function(promise){
   $scope.data = promise;
   $log.info($scope.data);  //gets the object all right
}).then(function(){
    // here you can see $scope.data updated with a new value
    $log.info($scope.data); 
});

as alternative:

var promise = factGetFeat.getPromise().then(function(promise){
   $scope.data = promise;
   $log.info($scope.data);  //gets the object all right
});

promise.then(function(){
    // here you can see $scope.data updated with a new value
    $log.info($scope.data); 
});

.then is evaluated when 1st promise resolved

Sign up to request clarification or add additional context in comments.

Comments

0

You are doing it almost right. You only need to return the promise from your service. If I understand you question you are concerned about $scope.data being null when you call $log.info($scope.data) on the very last page. And that is perfectly correct. $scope.data will be set later, when the HTTP call is finished successfully. If you need to do any operations only when the data arrived, you must include it success callback.

Here is how it could look like:

var app = angular.module('app',[]);

app.factory('featuresService', ['$http', '$log', function($http, $log) {

    var getPromise = function() {
        //create the promise, this will be returned from this function
        var promise = $http({method: 'GET', url: '../../LIBS/inc/getAllGeoFeatures.php'});

        //on error do some logging here
        promise.error(function(data, status, headers, config) {
            $log.warn(data, status, headers, config);
        });

        return promise;
    };  

    return {
        getPromise: getPromise;
    }

  }]);


app.controller('testCtrl', 'featuresService', function($scope, featuresService) {

    //set initial values
    $scope.data = null;
    $scope.vectorAllLibs = null;

    var init = function() {
        featuresService.getPromise().then(function(data) {
            $scope.data = data;
            $scope.vectorAllLibs = convertVectorAllLibs(data);
        };
    };

    var convertVectorAllLibs = function(data) {
        return ol.source.GeoJSON({ projection: 'EPSG:3857', object: data });
    };

    $scope.processVectorAllLibs = function() {
        if (!$scope.vectorAllLibs) {
            alert('sorry, no data yet!');
            return;
        }

        //process here
    };

    init();

});

11 Comments

So, the data will be delievered whenever the $scope.data will be used througout the controller?! Is it correct what I say? So, I should not be concerned and start working adding the code that will exploit the data in the $scope.data (delievered when and only when the $scope.data will be used?! Am I correct?
No no no, it is not correct. The data will be delivered when they are ready and it takes time to get them over network. That is why you promise's API provides the callbacks so the callbacks are run only when the data arrive, not earlier. If you display the data in HTML, it will be empty until the data are ready. And if you need to work with the data in code, then you must put the code into the callbacks so the code runs when the data are there.
It starts to make sense little by little. Hmmmmmm... So, there is no chance in the world that the controller will ever know when the data will arrive. From what I understand from your say, is that I pose the question $log.info($scope.data) too soon from the controller's point of view? The question is how to avoid putting the code exploiting the data in the callback? I need to work with it in the controller in order to bind to the view...
I ask because later in the controller I have the following sequence: var vectorAllLibs = new ol.source.GeoJSON({ projection: 'EPSG:3857', object: $scope.data }); // here nothing happens, the JSON object is not there
What you must do is to make this code to be called from the success callback. If the controller relies on the vectorAllLibs variable somewhere, it has to count with option that the value can be null too. And yes, you are right now. The controller never knows when the data arrive and it only knows that then it happens code from the success callback will be called.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.