Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for data in controller before link function is run in AngularJS directive

How can I ensure that data from a controller has been loaded in a directive before the link function is run?

Using psuedo-code, I could have:

<my-map id="map-canvas" class="map-canvas"></my-map> 

for my html.

In my directive I might have something like this:

app.directive('myMap', [function() {    return{     restrict: 'AE',     template: '<div></div>',     replace: true,     controller: function ($scope, PathService) {          $scope.paths = [];          PathService.getPaths().then(function(data){             $scope.paths = data;          });      },     link: function(scope, element, attrs){         console.log($scope.paths.length);      }  }   }]); 

The above won't work because console.log($scope.paths.length); will get called before the service has returned any data.

I know I can call the service from the link function but would like to know if there is a way to "wait" for the service call before firing the link function.

like image 697
James Satori-Brunet Avatar asked Dec 15 '14 14:12

James Satori-Brunet


People also ask

What is the difference between controller and link in directives in AngularJS?

The link option is just a shortcut to setting up a post-link function. controller: The directive controller can be passed to another directive linking/compiling phase. It can be injected into other directices as a mean to use in inter-directive communication.

What is Link function in AngularJS directive?

Link: The link function deals with linking scope to the DOM. Using Code for Compile. While defining a custom directive we have the option to define a link against which either we can define a function or we have the option to assign an object which will have pre & post function.

What does $compile do in AngularJS?

Compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and the template together.

Who controls the flow of data in AngularJS application?

All the AngularJS application mainly relies on the controllers to control the flow of data in that application. Basically, it controls the data of AngularJS applications and the controller is a Javascript object, created by a standard JavaScript object constructor.


2 Answers

The easiest solution would be to use ng-if since the element and directive would be rendered only when the ng-if is resolved as true

<my-map id="map-canvas" class="map-canvas" ng-if="dataHasLoaded"></my-map>  app.controller('MyCtrl', function($scope, service){   $scope.dataHasLoaded = false;    service.loadData().then(     function (data) {       //doSomethingAmazing       $scope.dataHasLoaded = true     }   ) }) 

or use promises

return {   restrict: 'AE',   template: '<div></div>',   replace: true,   controller: function ($scope, PathService) {     $scope.paths = [];     $scope.servicePromise = PathService.getPaths()   },   link: function (scope, element, attrs) {     scope.servicePromise.then(function (data) {       scope.paths = data;       console.log(scope.paths)     });   } } 
like image 192
maurycy Avatar answered Sep 24 '22 01:09

maurycy


app.directive('MyDirective', function() {     return {         controller: function() {             this.$postLink = function() {             // here will run after the link function,             // and also after the binding came in             };         },         controllerAs: 'vm'     }; }); 

check out the angular 1.5 Components have a well-defined lifecycle and it works on directives to

like image 41
Isaac Weingarten Avatar answered Sep 20 '22 01:09

Isaac Weingarten