Using Imagecache in Ionic

Hey there,

Loads of solutions to store json files in localstorage (ng-localstorage, etc), but I was wondering if anybody has ever figured out a way to cache images locally in an Ionic project.

I was doing some digging and I found this Cordova plugin: https://github.com/chrisben/imgcache.js/tree/master

It seems to be solving the issue of storing images locally. Anybody have any experience in working with this plugin?

2 Likes

I’ve done this ‘manually’ for some time now using html5 storage in tandem with taffy (and before that Lawnchair). Sucks that this uses jQuery (which has crap performance on Android…with or without Crosswalk).

If you have a backend with some type of relational db you should be able to create POJO’s with all the properties you need (id, title, alt, local path, etc). Using the Cordova File plugin and a custom resource (factory, etc) should get you going. Things to consider: making sure your space quota is set when you bootstrap your file system, knowing the platform specifics of obtaining local path (.toURL vs .toNativeURL), and normalizing your client schema.

@coen_warmer are you trying to store the image files locally or just cache them? Simple cache can be done by using ng-src. As far as using the plugin, imagecache, I can’t really say how well it will work.

1 Like

@mhartington I’m not sure what the right term would be in Cordova land- My aim is to store external images locally that are retrieved by the app so that the next time the app starts they’ll be retrieved from the storage on the device instead of getting them through the web. This making the app more useable when there is no connection available.

When using ng-src, does the app only store them as long as the app is open? If so, then I guess I’m looking for a way to store them locally and rewrite any links to external images to use the local copies. If there are no local copies available, then download them and store them.

2 Likes

This sounds promising. In my use case I might not always know the width and height and such, so it will strictly be device driven.

I can see how storing the images by using the Cordova file system plugin might work, I’m less clear on how to set up the factory so that the app will first try to retrieve an image from the local storage, and if it isn’t available there, then get it through the connection. Gonna give it a go though. Think this would be a great feature for ionic to have.

@coen_warmer Did you figure this out?
I was also trying out to do the same stuff.

1 Like

Hey @shahidh, no not yet- other issues in my projects had to take precedence. But I’ve been following chrisben’s Imagecache plugin and it looks like he just added basic Angular support: https://github.com/chrisben/imgcache.js/pull/64

Once that matures a bit it could potentially be easy to use in an Ionic project. Right now I’m not so sure.

Okay, I managed to make it work. (Had to modify some source code). Will post the details soon

Awesome! Thanks @shahidh!

@shahidh I’m looking forward to those details. I am tackling this issue right now and would love to see how you implemented this.

1 Like

So, what I did was to make an angularjs directive which when applied over an img tag (which has a data-src attribute, not src), checks the data-src url and show cached image if the image is cached or else download, cache it and then show the cached version. Will post the code details soon. In a hurry right now

3 Likes

I’ve made this little directive that wraps the functionality of imgcache.js

(function(angular) {
    
    "use strict";
    
    var ngImgCache = angular.module('ngImgCache', []);
    
    ngImgCache.directive('ngCache', function() {
        
        return {
            restrict: 'A',
            link: function(scope, el, attrs) {
                
                attrs.$observe('ngSrc', function(src) {
                    
                    ImgCache.isCached(src, function(path, success) {
                        if (success) {
                            ImgCache.useCachedFile(el);
                        } else {
                            ImgCache.cacheFile(src, function() {
                                ImgCache.useCachedFile(el);
                            });
                        }
                    });
                    
                });
            }
        };
    });
    
})(angular);

In order to use this directive you should initialize imgcache.js as is said in the docs and then in any img tag do something like this:

<img ng-cache ng-src="..." />
7 Likes

Initializing just refers to inserting the script after angular.js right?

Hey how do I use it in a service?

I did something like this:

var ngImgCache = angular.module('ngImgCache', []);

ngImgCache.service('CacheImages', [function(){

    return {

        checkCacheStatus : function(src){

           ImgCache.isCached(src, function(path, success) {
                if (success) {
                    ;
                } else {
                    ImgCache.cacheFile(src, function() {
                        ;
                    });
                }
            });
        }
    }

}]);

And I inject the above into one of my service and did something like this

CacheImages.checkCacheStatus(src); 

It does not work. Returns a blank screen.

Hi, first of all you need is initialize imgcache.js with somethin like this, in your run function:

app.run(function(...) {
    ImgCache.options.debug = true;
    ImgCache.options.chromeQuota = 50*1024*1024;        
   
    $ionicPlatform.ready(function() {
        ImgCache.init(function() {
            console.log('ImgCache init: success!');
        }, function(){
            console.log('ImgCache init: error! Check the log for errors');
        });
    });
});

Yeah I have done that. But still I get a blank screen So I asked you.

Can you let me know if you have implemented it, then how have you done it?

I have it working on my mobile app, I forget to mention that you should add the file and filetransfer cordova plugins to your project. Do you receive any warnings or errors on your javascript console? Did you include it when you declare your app object:

angular.module('yourappname', ['ionic', 'someotherdeps', 'ngImgCache']);

and in your index.html you should include imgcache.js before ionic

Hey yeah I have already done all that basic stuff.
Take a look at my service.

SomeService.service('ServiceName', [function(){
    return{
          // Fetch some data.
          // resp.data.img whose value is "http://wwww.someSite.com/1.png"
         // Now I have to put the aboove image in the cache. How do I do it?
         
       return deferred.promise()
    }
}]);

You get my point right? I want to fetch images over the network and insert it into the cache right in the service itself. So when I obtain the image in the view i get a cached copy and not over the network.

I have initialized in my .run() and it fires a success event.

I really don’t know what you want to do :frowning:
The only advice that I could give you is read the documentation of imgcache.js is very clear and easy to follow