Vytautas Pranskunas
Vytautas Pranskunas

Reputation: 890

How to implement image caching in nativescript angular

I am implementing Nativescript app with angular and want to do image caching. Nativescript documentation only shows how to work with view but not angular. I have found this topic: how do i cache images in nativescript angular but answer does not look very promising because 1) Local functions 2) feels like it has no OnPush strategy

with all metnioned above i think that Observables should be way to go. So i do have some ImageCahceService

import { Cache } from 'tns-core-modules/ui/image-cache';
import { ImageSource, fromNativeSource } from 'tns-core-modules/image-source';
import { Injectable } from '@angular/core';
import { Observable } from 'apollo-link';

@Injectable({ providedIn: 'root' })
export class ImageCacheService {
    private cache: Cache;

    constructor() {
        this.cache = new Cache();
        this.cache.placeholder = ImageSource.fromFileSync('~/assets/images/temp-icon.jpg');
        this.cache.maxRequests = 10;
    }

    get(url: string): Observable<any> {
        this.cache.enableDownload();

        return new Observable(observer => {

            const imageFromCache = this.cache.get(url);

            if (imageFromCache) {
                observer.next(imageFromCache);
                observer.complete();
                this.cache.disableDownload();
                return;
            }

            this.cache.push({
                key: url,
                url,
                completed: (image: any, key: string) => {
                    if (url === key) {
                        observer.next(new ImageSource(image));
                        observer.complete();
                        this.cache.disableDownload();
                    }
                }
            });

        });
    }
}

and consumtion would be but with this code app freezes and crashes.

If i do without observables first time it does not show images but on second visit it does - and thats clear why - because image is trightly available in cache.

So can anyone help me with that?

p.s. bonus question - if Observables are way to go where to put cache.disableDownload() ?

Thanks

Upvotes: 0

Views: 617

Answers (1)

Vytautas Pranskunas
Vytautas Pranskunas

Reputation: 890

finally i was able to do image caching with observables but but there are some questions left:

is this.cache.enableDownload(); and this.cache.disableDownload(); are in right positions for some reason, images are shown with big delay (after some random dom rerender), if i am not adding cd.detectChanges(); here is my pipe:

import { Pipe, PipeTransform, ChangeDetectorRef } from '@angular/core';
import { Cache } from 'tns-core-modules/ui/image-cache';
import { ImageSource, fromNativeSource } from 'tns-core-modules/image-source';
import { Observable } from 'rxjs';

@Pipe({
    name: 'fromCache',
    pure: true,
})
export class ImageCachePipe implements PipeTransform {
private cache: Cache;

constructor(private cd: ChangeDetectorRef) {
    this.cache = new Cache();
    this.cache.placeholder = ImageSource.fromFileSync('~/assets/images/temp-icon.jpg');
        this.cache.maxRequests = 10;
    }

    transform(url: string): any {
        this.cache.enableDownload();

        return new Observable(observer => {

            const imageFromCache = this.cache.get(url);

            if (imageFromCache) {
                observer.next(imageFromCache);
                observer.complete();
                this.cache.disableDownload();
                return;
            }

            observer.next(this.cache.placeholder);

            this.cache.push({
                key: url,
                url,
                completed: (image: any, key: string) => {
                    if (url === key) {
                        observer.next(new ImageSource(image));
                        observer.complete();
                        this.cache.disableDownload();
                        this.cd.detectChanges();
                    }
                }
            });

        });
    }
}

Upvotes: 1

Related Questions