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.
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.
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.
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.
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.
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) }); } }
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With