Join the Stack Overflow Community
Stack Overflow is a community of 6.5 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I want to display a form with data corresponding to the edited item. I use ui-router for routing. I defined a state:

myapp.config(function($stateProvider) {

    $stateProvider.
    .state('layout.propertyedit', {
        url: "/properties/:propertyId",
        views : {
            "contentView@": {
                templateUrl : 'partials/content2.html', 
                controller: 'PropertyController'
            }
        }
    });

In PropertyController, I want to set $scope.property with data coming from the following call (Google Cloud Endpoints):

    gapi.client.realestate.get(propertyId).execute(function(resp) {
        console.log(resp);
    });

I don't know if I can use resolve because the data are returned asynchronously. I tried

    resolve: {
        propertyData: function() {
            return gapi.client.realestate.get(propertyId).execute(function(resp) {
                console.log(resp);
            });
        }
    }

First issue, the propertyId is undefined. How do you get the propertyId from the url: "/properties/:propertyId"?

Basically I want to set $scope.property in PropertyController to the resp object returned by the async call.

EDIT:

myapp.controller('PropertyController', function($scope, , $stateParams, $q) {

    $scope.property = {};

    $scope.create = function(property) {
    }

    $scope.update = function(property) {
    }

function loadData() {
    var deferred = $q.defer();

    gapi.client.realestate.get({'id': '11'}).execute(function(resp) {
        deferred.resolve(resp);
    });

    $scope.property = deferred.promise;
}

});
share|improve this question
1  
add a jsfiddle please. – zsong Aug 1 '13 at 21:34
up vote 50 down vote accepted

You need to read the docs for resolve. Resolve functions are injectable, and you can use $stateParams to get the correct value from your routes, like so:

resolve: {
    propertyData: function($stateParams, $q) {
        // The gapi.client.realestate object should really be wrapped in an
        // injectable service for testability...

        var deferred = $q.defer();

        gapi.client.realestate.get($stateParams.propertyId).execute(function(r) {
            deferred.resolve(r);
        });
        return deferred.promise;
    }
}

Finally, the values for resolve functions are injectable in your controller once resolved:

myapp.controller('PropertyController', function($scope, propertyData) {

    $scope.property = propertyData;

});
share|improve this answer
1  
The deferred.resolve is called but the controller is not called. It seems that the promise is stuck. If I replace my async call by deferred.resolve("resolved"), the controller is called. Any idea? – Sydney Aug 2 '13 at 22:15
    
For some reason I had to call $rootScope.$apply(); after deferred.resolve – Sydney Aug 2 '13 at 23:32
3  
It's because Angular's promise system is hooked into the scope system's digest cycle. For all of Angular's built-in APIs that leverage promises, it takes care of this for you. When you're using outside asynchronous APIs, you need to refresh the scope yourself. – Nate Abele Aug 3 '13 at 17:45

I think your controller function needs $stateParams parameter from which you can get your propertyId. Then you can use $q parameter and create promise to set $scope.property with something like this:

var deferred = $q.defer();

gapi.client.realestate.get(propertyId).execute(function(resp) {
    deferred.resolve(resp);
});

$scope.property=deferred.promise;

Here is description of using promises for handling async calls.

share|improve this answer
    
The PropertyController already exists, so by using the controller function controller: function PropertyController($scope, $stateParams), does it create a new PropertyController, or use the existing one? – Sydney Aug 1 '13 at 21:26
    
If it exists how does it look? – efan Aug 1 '13 at 21:30
    
See my edit for the current controller – Sydney Aug 1 '13 at 21:35
    
So go ahead and add $stateParams, $q to this definition: ...'ProperyController', function($scope, $stateParams, $q) { ... – efan Aug 1 '13 at 21:38
    
I edited my controller. But I don't understand how to trigger the loadData function. – Sydney Aug 1 '13 at 22:58

How about this:

function PropertyController($scope, $stateParams) {
   gapi.client.realestate.get($stateParams.propertyId).execute(function(resp) {
     $scope.property = resp;
   });
}
share|improve this answer
    
The PropertyController already exists, so by using the controller function controller: function PropertyController($scope, $stateParams), does it create a new PropertyController, or use the existing one? – Sydney Aug 1 '13 at 21:27

Try this easy way to use resolve in proper way

State code:


.state('yourstate', {
                url: '/demo/action/:id',
                templateUrl: './view/demo.html',
                resolve:{
                    actionData: function(actionData, $q, $stateParams, $http){
                       return actionData.actionDataJson($stateParams.id);
                    }
                },
                controller: "DemoController",
                controllerAs : "DemoCtrl"
            })

In the above code I am sending parameter data which I am sending in the url,For examples if i send like this /demo/action/5 this number 5 will go to actionData service that service retrieve some json data based on id.Finally that data will store into actionData You can use that in your controller directly by using that name

Following code return some JSON data based on id which iam passing at state level


(function retriveDemoJsonData(){

    angular.module('yourModuleName').factory('actionData', function ($q, $http) {

        var data={};
        data.actionDataJson = function(id){
           //The original business logic will apply based on URL Param ID 
            var defObj = $q.defer();
            $http.get('demodata.json')
                .then(function(res){
                     defObj.resolve(res.data[0]);
                });
            return defObj.promise;  
        }
        return data;
    });

})();

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.