Sydney Sydney - 19 days ago 6
AngularJS Question

Angular ui-router get asynchronous data with resolve

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;
}

});

Answer

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;

});