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

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