Angularjs bootstrap carousel dynamically adds sliders after loading images, causing a repeated error

So I have a carousel that looks like this:

<div class="jumbotron-carousel" carousel interval="controller.jumbotronInterval" no-pause="true" no-transition="true">
    <div class="slide" slide ng-repeat="slide in controller.jumbotron" active="slide.active" style="background-image: url({{ slide.image }});">

    </div>
</div>

and my controller looks like this (simplified for brevity)

.controller('HomeController', ['preloader', function (preloader) {
    var self = this;

    // Set up our main carousel
    self.jumbotronInterval = 2000;
    self.jumbotron = [];

    // Private function to create the main slider slides
    var createSlides = function () {

        // Create an array of our images
        var slides = [{
            image: '/assets/images/carousel/jumbotron/_MG_0629.jpg'
        }, {
            image: '/assets/images/carousel/jumbotron/_J5Y6128.jpg'
        }, {
            image: '/assets/images/carousel/jumbotron/_J5Y6588.jpg'
        }, {
            image: '/assets/images/carousel/jumbotron/_J5Y6779.jpg'
        }, {
            image: '/assets/images/carousel/jumbotron/_J5Y6929.jpg'
        }, {
            image: '/assets/images/carousel/jumbotron/_J5Y7157.jpg'
        }, {
            image: '/assets/images/carousel/jumbotron/_J5Y7286.jpg'
        }, {
            image: '/assets/images/carousel/jumbotron/_MG_0151.jpg'
        }, {
            image: '/assets/images/carousel/jumbotron/_MG_0337.jpg'
        }, {
            image: '/assets/images/carousel/jumbotron/_MG_0417.jpg'
        }, {
            image: '/assets/images/carousel/jumbotron/_MG_1300.jpg'
        }];

        // For each slide
        for (var i = 0; i < slides.length; i++) {

            // Get our slide
            var slide = slides[i];

            // If our image has loaded
            preloader(slide.image).then(function () {

                // Add to our jumbotron
                self.jumbotron.push(slide);

                console.log(self.jumbotron);
            });
        }
    };

    // Create your slides
    createSlides();
}]);

So basically what is happening is my preloader, which waits for the image to load, and then moves the slider to my array. Here's what my service looks like (pretty simple):

.factory('preloader', ['$q', function ($q) {
    return function (url) {

        // Create our deferred promise and create an image object
        var deffered = $q.defer(),
            image = new Image();

        // Assign the url to the image
        image.src = url;

        // If the image has finished loading
        if (image.complete) {

            // Resolve the promise
            deffered.resolve();

            // Otherwise it hasn't completed
        } else {

            // Add an event listener to the load event
            image.addEventListener('load', function () {

                // Resolve the promise when the image loads
                deffered.resolve();
            });

            // Add an event listener to the load event
            image.addEventListener('error', function () {

                // Reject the promise
                deffered.reject();
            });
        }

        // Return our promise
        return deffered.promise;
    }
}])

The problem is that when I click a slide on a slide array, I get an error message in angular:

Error: [ngRepeat: dupes]

I made a console log after completing each image download, and then the application complains. I “could” wait until all the images were loaded, but I would prefer to add them sequentially. Does anyone know how I can do this?

+4

All Articles