I'm trying to initiate a carousel script onto the rendered elements created by my directive. It works if I feed the directive with static json, but if I use http get to get the data from an api it will not initialized properly. While the script does initialize and creates a set of elements for navigation of the carousel it seems the rendered elements are injected after this happens.
If I delay the init with 100ms it'll initialize properly, but it feels like a hacky solution. What's best practice is a situation like this?
Static data – works
angular.module('exhibitions', [])
.directive('exhibitionsCarousel', ['$timeout', function(timer) {
return {
scope: {},
link: function(scope, element, attrs) {
var initFlickity = function () {
var flkty = new Flickity( '.main-gallery', {
cellAlign: 'left',
contain: true
});
};
timer(initFlickity, 0);
},
templateUrl: '/app/themes/pomgallery/exhibitions_carousel.html',
replace: true,
controller: 'exhibitionsCarouselCtrl',
controllerAs: 'ctrl'
};
}])
.controller('exhibitionsCarouselCtrl', function($scope, $http) {
this.exhibitions = [
{title: 'Rachel', date: 'Washington', place: 'One'},
{title: 'Joshua', date: 'Foster', place: 'Two'},
{title: 'Samuel', date: 'Walker', place: 'Three'}
];
});
angular.module('PomGallery', ['exhibitions']);
Fetched data – does not work without delay
angular.module('exhibitions', [])
.directive('exhibitionsCarousel', ['$timeout', function(timer) {
return {
scope: {},
link: function(scope, element, attrs) {
var initFlickity = function () {
var flkty = new Flickity( '.main-gallery', {
cellAlign: 'left',
contain: true
});
};
timer(initFlickity, 0); // If I set it to 100 rather than 0 it'll work.
},
templateUrl: '/app/themes/pomgallery/exhibitions_carousel.html',
replace: true,
controller: 'exhibitionsCarouselCtrl',
controllerAs: 'ctrl'
};
}])
.controller('exhibitionsCarouselCtrl', function($scope, $http) {
var vm = this;
$http({
method: 'GET',
url: '/wp-json/posts',
params: {
'filter[posts_per_page]': 3
},
}).
success( function( data, status, headers, config ) {
vm.exhibitions = data;
}).
error(function(data, status, headers, config) {});
});
angular.module('PomGallery', ['exhibitions']);
You should use a promise. A promise will wait for data before displaying it but it will still run the other functions within the controller, similar to asynchronous functions in c#. Here's the link to the tutorial https://docs.angularjs.org/api/ng/service/$q