Wait for data in controller before link function is run in AngularJS directive
26,195
Solution 1
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)
});
}
}
Solution 2
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
Author by
James Satori-Brunet
Updated on January 27, 2022Comments
-
James Satori-Brunet over 2 years
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.
-
maurycy over 9 yearsThe directive and controller would not be created if used with falsy
ng-if
but if the data you are loading is used by the directive and not required in controller it would make sense to use itlink
/controller
of the directive -
James Satori-Brunet over 9 yearsThis is not working. The ng-if statement is removing the my-map tag from the dom and the controller is never firing.
-
James Satori-Brunet over 9 yearsI tried using a controller that was not based in the directive and it still is not working. This must be a solution for <1.2.0.
-
maurycy over 9 yearsJames as I said if you use ng-if then directive and controller will not be created, but if you are using the data only in this directive you can omit
ng-if
and load data inside directive's controller -
James Satori-Brunet over 9 yearsOk, I see. I'll mark it as correct as it is close enough to what I need. Thank you for your help.
-
Undefitied over 7 yearsNote that ng-if runs on each scope digest