0

I'm trying to save and load images from cache using ImageCache NativeScript Core module but it won't work.

<template>
 <Page>
  <StackLayout>
   <Image v-for="exampleImage in exampleImages" :src="getCachedImage(exampleImage.url)"/>
  </StackLayout>
 </Page>
</template>

<script>
 import * as imageCache from 'tns-core-modules/ui/image-cache'
 import * as imageSource from 'tns-core-modules/image-source'

 export defualt {
  data() {
   return {
    exampleImages: [
     {url: 'https://image.tmdb.org/t/p/w600_and_h900_bestv2/kY2c7wKgOfQjvbqe7yVzLTYkxJO.jpg'},
     {url: 'https://image.tmdb.org/t/p/w600_and_h900_bestv2/svIDTNUoajS8dLEo7EosxvyAsgJ.jpg'},
     {url: 'https://image.tmdb.org/t/p/w600_and_h900_bestv2/A7XkpLfNH0El2yyDLc4b0KLAKvE.jpg'},
    ]
   }
  },
  methods: {
   getCachedImage(imgUrl) {
                const cache = new imageCache.Cache();
                cache.enableDownload();

                const image = cache.get(imgUrl);
                let cachedImageSource;
                if (image) {
                    console.log('getting image from cache')
                    cachedImageSource = imageSource.fromNativeSource(image)
                } else {
                    console.log('downloading image, setting it in cache, and getting from cache')

                    cache.push({
                        key: imgUrl,
                        url: imgUrl,
                        completed: (image, key) => {
                            if (imgUrl === key) {
                                cachedImageSource = imageSource.fromNativeSource(image);
                                console.log(cachedImageSource)
                            }
                        },
                        error: () => {
                            console.log('Error')
                        }
                    });
                }
                cache.disableDownload();
                return cachedImageSource;
            }
  }
 }
</script>

But then, the output in my console is the following:

iOS:

{ ios: {} }

Android:

{ android:
    { constructor:
       { [Function]
         [length]: 0,
         [name]: '',
         [arguments]: null,
         [caller]: null,
         [prototype]: [Object],
         createBitmap: [Object],
         createScaledBitmap: [Object],
         extend: [Object],
         CREATOR: [Object],
         DENSITY_NONE: 0,
         CONTENTS_FILE_DESCRIPTOR: 1,
         PARCELABLE_WRITE_RETURN_VALUE: 1,
         null: [Circular],
         class: [Object],
         CompressFormat: [Object],
         Config: [Object] } } }

And of course is always outputing: downloading image, setting it in cache, and getting from cache and never getting image from cache. The image is never displayed, never saved in cache and never obtained from cache.

I don't know what I'm I doing wrong.

Thanks in advance.

3
  • Images are downloaded asynchronously, you can't directly return the image. Try to set it as a property in data, so it as soon you update data object the image gets synced. If you still have issues, please share the Playground sample. Commented May 1, 2019 at 20:35
  • Hey @Manoj thanks for answering! I tried saving it in a data object but still ios is returning nothing: play.nativescript.org/?template=play-vue&id=Lft4qB Also there's a better way than keeping 2 objects in data (in my case cachedImages and exampleImages?) Commented May 3, 2019 at 14:53
  • Still you are doing the same mistake with data object, you are suppose to wait for the async call to complete. Commented May 3, 2019 at 16:49

1 Answer 1

1

Image download is asynchronously, so you can not use a direct return statement. You have to wait for the complete callback and update your data with image url.

<template>
    <Page class="page">
        <ActionBar title="Home" class="action-bar" />
        <ScrollView>
            <StackLayout>
                <Image v-for="exampleImage in exampleImages" :src="exampleImage.src" />
            </StackLayout>
        </ScrollView>
    </Page>
</template>

<script>
    import * as imageCache from "tns-core-modules/ui/image-cache";
    import * as imageSource from "tns-core-modules/image-source";
    export default {
        data() {
            return {
                exampleImages: [{
                        url: "https://image.tmdb.org/t/p/w600_and_h900_bestv2/kY2c7wKgOfQjvbqe7yVzLTYkxJO.jpg",
                        src: null
                    },
                    {
                        url: "https://image.tmdb.org/t/p/w600_and_h900_bestv2/svIDTNUoajS8dLEo7EosxvyAsgJ.jpg",
                        src: null
                    },
                    {
                        url: "https://image.tmdb.org/t/p/w600_and_h900_bestv2/A7XkpLfNH0El2yyDLc4b0KLAKvE.jpg",
                        src: null
                    }
                ]
            };
        },
        methods: {
            getCachedImage(exampleImage) {
                const cache = new imageCache.Cache();
                cache.enableDownload();
                const image = cache.get(exampleImage.url);
                let cachedImageSource;
                if (image) {
                    console.log("getting image from cache");
                    exampleImage.src = imageSource.fromNativeSource(image);
                } else {
                    console.log(
                        "downloading image, setting it in cache, and getting from cache"
                    );
                    cache.push({
                        key: exampleImage.url,
                        url: exampleImage.url,
                        completed: (image, key) => {
                            exampleImage.src = imageSource.fromNativeSource(
                                image);
                        },
                        error: () => {
                            console.log("Error");
                        }
                    });
                }
                // cache.disableDownload();
            }
        },
        created() {
            for (let x in this.exampleImages) {
                this.getCachedImage(this.exampleImages[x]);
            }
        }
    };
</script>

Updated Playground

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much for the example! One more question if I destroy the component and I load another one, and then I come back to this one, the images are being download again and not served from cache (When I say destroy I'm speaking about using nativescript manual routing), its that normal?
Use a global cache, one instance of imageCache.Cache through out app.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.