Search code examples
angularjsrestsymfonyangular-resourcengresource

Waiting until $resource finished to load in my controller before continuing


I'm building a rest api with fosrestbundle and I manage the frontend with angular and Twig template. One on my url address looks like this :

http://mywebsite/myroute/idContain

When I load the url in my browser, in a twig template (kind of html), I retrieve the parameter "idContain" (comming from a fosrestbundle controller) with ng-init of angularjs like this :

<div class="container-fluid" ng-init="getContainByID({{ idContain }})">
  //...lot html div with angularjs directives
</div>

And immediately, ng-init will go to my angularJS app finds getContainByID(idContain) to run it. This one looks like this :

angular.module("myApp", ["ngSanitize", 'angular.filter', 'ui.tinymce', ...])
.config(function($interpolateProvider, ...) {
    $interpolateProvider.startSymbol('{[{').endSymbol('}]}');
})
    .controller("myCtrl",function ($filter,..., myService)
{
    // lot of code...
    $scope.getContainByID = function(idContain)
    {

        $scope.currentContain = myService.getContains(idContain);
        $scope.containRoot = $scope.currentContain.contain.containRoot;
        ...

    }
    // lot of code...
}

The fact is that, myService.getContains(idContain) come from my rest service looking like this :

angular.module("MyServiceRest", ['ngResource'])

.factory("myService",  function ($rootScope, $resource) {


    var apiData = $resource(
        "/api", {},
        {
            ...
            "getContains": {method: 'GET', isArray: false, url: "mywebsite/api/myroute/:containid"}
            ...
        });

    return {

        getContains: function (idContain) {
            return apiData.getContains({containid: idContain});
        }

    }
});

Now the problem is, when I run my angularjs App, $scope.containRoot doesn't wait until myService.getContains(idContain) (coming from my asynchroeous $resource service) finished to load, and caused errors making my webapp crash.

How can I do, to force $scope.containRoot and the rest of my angular code to waiting until myService.getContains(idContain) (connected to the api resource) completly finished to load before continuing ?


Solution

  • $resource makes an asynchronous request but immediately reurns an empty object or array.

    There are numerous ways you could handle your issue.

    One would be not to worry about declaring $scope.containRoot and just using currentContain.contain.containRoot in the view. This property will get rendered after the request is received

    Another is to use the $promise that is also returned by $resource and assign the scope property in promise callback

    $scope.currentContain = myService.getContains(idContain);
    
    $scope.currentContain.$promise.then(function(){
            $scope.containRoot = $scope.currentContain.contain.containRoot;
    });
    

    Another is to use a routing resolve based on the same promise so the route( or state depending on router) is noot entered until the request is complete