Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example for image caching #2154

Open
vytautas-pranskunas- opened this issue Apr 25, 2020 · 2 comments
Open

Add example for image caching #2154

vytautas-pranskunas- opened this issue Apr 25, 2020 · 2 comments

Comments

@vytautas-pranskunas-
Copy link

@vytautas-pranskunas- vytautas-pranskunas- commented Apr 25, 2020

Hello,
I am trying to implement image caching on angular however there is no example how to do this.
In general example view model is updated however in angular there is no view model and with OnPush I need to go with observables. However the app crashes. Plus then not sure when to use enableDownload and disabled onload functions.
I asked question on stackoverflow.com but got no answer.
Question with service example can be found here : https://stackoverflow.com/questions/61418403/how-to-implement-image-caching-in-nativescript-angular

Finally I am going to do pipe not service but is its same -

  1. How to notify view about loaded images
  2. Where to use enableDownload disableDownload if I have image Cache pipe or service

It would be super cool to get answers from you guys and improve docs because I feel stuck a little bit.

@vytautas-pranskunas-
Copy link
Author

@vytautas-pranskunas- vytautas-pranskunas- commented Apr 25, 2020

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

  1. is this.cache.enableDownload(); and this.cache.disableDownload(); are in right positions
  2. 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();
                    }
                }
            });

        });
    }
}

@alexgritton
Copy link

@alexgritton alexgritton commented May 19, 2020

I'm also struggling with this. Whenever I return an observable I get this error. The method setNativeSource() expects UIImage instance.

I've simplified the transform method to this to try and pinpoint the problem.

transform(url: string): Observable<ImageSource> {
    return new Observable(observer => {
      var image = ImageSource.fromFileOrResourceSync('~/assets/images/rest-day-320.jpg');
      observer.next(image);
      observer.complete();
    });
}

If I return the ImageSource directly then it works as expected. Any help would be greatly appreciated. This is what the html looks like.

<Image [src]="day.thumbnailUrl | encodeUrl | imageCache" loadMode="async" class="card-left-image"  stretch="aspectFill">
</Image>

EDIT: I didn't know I had to add the async pipe after. After adding | async to the [src] everything works as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.