0

i need to preload images after an $http service.

Now in my application i'm using promise/resolve method to preload data with service. here my service:

angular.module('davelab.services', [])

.factory('srvProjects', ['$http', function ($http) {
    var API = '/backend/api/';

    var sdo = {

        getProjects: function() {

            var promise = $http({ method: 'GET', url:  API + 'get_posts/' }).success(function(data, status, headers, config) {
                return data;
            });

            return promise;

        }

    };

    return sdo;


}]);
});

and here the route part:

 $routeProvider.when('/projects', {
        templateUrl: 'app/partials/list-projects.html',
        controller: 'ProjectsCtrl',
        resolve: {
                projects: function(srvProjects) {
                return srvProjects.getProjects();
            }
        }
    });

it works well with data but for the images retrieved from api request it doesn't work.

How can I preload images in cache before show the view with this method?

i have to iterate through data into success callback or somewhere else?

thanks.

DavideCariani
  • 273
  • 7
  • 21

2 Answers2

1

Take the URL's you're receiving from your original request, but instead of resolving the promise right away, create a new promise for each image. Preload the image using any method you prefer (but it needs a callback to resolve its promise) and resolve each promise after the image is loaded. You should end up with an array of image promises. and then return $q.all(imagePromises) from your resolve. Check out the docs for $q.

$q.all will return a promise that is only resolved when all promises passed into it are resolved.

I haven't tested it, but I think you might be able to just use $http on each image URL and it will cache it for you and give you a nice promise to pass into $q.all. So basically you'll have an array of $http calls.

Jonathan Rowny
  • 7,588
  • 1
  • 18
  • 26
  • can i add this to $http success callback? `var img = []; angular.forEach(data.posts, function(value, key){ img[key] = new Image(); img[key].src = value.custom_fields.projectCover; });` – DavideCariani Feb 19 '14 at 17:33
  • Just try `img = []; angular.ForEach(data.posts, function(value){ img.push($http(value.custom_fields.projectCover)); });` followed by `$q.all(img)` – Jonathan Rowny Feb 19 '14 at 17:35
  • i got this error with your advise: `TypeError: Cannot read property 'protocol' of undefined` – DavideCariani Feb 19 '14 at 17:41
  • i added 'method' and 'url' params to $http service for each image but it still doesn't work. I mean is not anymore a progressive loading but show once a time every single image when is loaded. (in order of sizes, obviously), – DavideCariani Feb 19 '14 at 17:49
  • Hard to say what it is without seeing your exact code. Sounds like the path isn't getting passed to $http properly. – Jonathan Rowny Feb 19 '14 at 18:51
  • this is the code: `var promise = $http({ method: 'GET', url: API + 'get_posts/' }).success(function(data, status, headers, config) { var img = []; angular.forEach(data.posts, function(value){ img.push($http({ method: 'GET', url: value.custom_fields.projectCover })); }); $q.all(img); return data; });` – DavideCariani Feb 20 '14 at 15:30
0

You can use like this in your controller

$scope.preloader = true

then you can use angular promise of

.then(function(result){
  //your code goes here

  $scope.preloader = false;
}

Also you have $scope.preloader= false in you error block

If you have multiple Ajax calls at a same time parallely then use

$scope.preloader = 0;

on stating the request use

$scope.preloader++;

and when done use

$scope.preloader--;

You can have more clear answer here Showing Spinner GIF during $http request in angular

Community
  • 1
  • 1
Felix
  • 245
  • 2
  • 10