0

Code is something like this.

//Extending a Nativescript module.      
var test = ImageProvider.extend({

  getImage: function(url){

    //async call to get the image from cache
    cacheService.getImage(url,  
      function(image){
         return image
      }, 
      function(error){ 
        return null 
    });
 }
});

How do i prevent the getImage function to return before image is provided ? I prefer not to use typescript or babel to solve the problem. But please advice if needed. (also tried babel,typescript without any luck) I have tried to use await and yield by setting:

"android": {"v8Flags": "--expose_gc --use_strict --harmony"} 

in the package.json file without success.

A sample giving errors using yield

"use strict" 

function onNavigationgTo(args){ 
  yield test(); 
}

function* test(){
  return 1;
}

It works without error before i add the yield keyword. Using yield gives the following. SyntaxError: Unexpected strict mode reserved word File : "unknown"

  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Alexander O'Mara Jul 25 '16 at 07:22
  • And how did your code look like when you tried to use `yield` and `await`? – t.niese Jul 25 '16 at 07:22
  • @AlexanderO'Mara : I am extending (overriding in java) a function. So i do not hav full controll over the function. Then i would have used promises or callback. I see that it is also suggested yield, await and fibers (can not find process object). I have tried them but can not get them to work as expected in Nativescript. (all give me errors). So i think the problem is related to how this should be done in Nativescript. Since it should be possible with await etc i es 6. Nativescript uses es 5 as far as i know. But hoped with the --harmony flagg it should be possible. – Stavanger75 Jul 25 '16 at 08:39
  • @t.niese I have updated with a sample using the yield. Do you see any problems in code. It looks like i am not able to use generators. – Stavanger75 Jul 25 '16 at 09:45

2 Answers2

0

You use ES6 Promises for this.

var test = ImageProvider.extend({
  getImage: function(url){
    //async call to get the image from cache
    return new Promise(function(resolve,  reject) {
        cacheService.getImage(url,  
          function(image){
             resolve(image);
          }, 
          function(error){ 
            reject(error);
        });
    });
 }
});

then use it like this

test.getImage('http://...').then(function(image) {
    // do stuff
});

Native promises are supported by all major browsers.. except IE (It is supported by edge). If you want a wider browser support, I recommend using bluebird.

Coloured Panda
  • 3,293
  • 3
  • 20
  • 30
  • Thanks for your reply. The getImage is extended from ImageProvider. It is up to the module to handle the actuall loading off the image and display it. So i don't think i can use promises in this case. (have thought about it). Please correct me if i am wrong. – Stavanger75 Jul 25 '16 at 07:34
  • @Stavanger75 This handles image loading just fine. I believe displaying it must be done manually as there are no selectors or any way for ImageProvider to know where to display the image. – Coloured Panda Jul 25 '16 at 07:43
  • Kaspars: extend means override in Java. So when getImage returns an image. The imageprovider will handle how it is displayed. https://docs.nativescript.org/runtimes/android/generator/extend-class-interface.html. – Stavanger75 Jul 25 '16 at 07:53
  • @Stavanger75 Is ImageProvider a custom class? Can you provide the source code for it? Having it handle both retrieval and displaying seems like an odd design choice. – Coloured Panda Jul 25 '16 at 07:58
  • The code provided was just for illustration (to keep it as simple at possible). You can check out TileProvider.getTile(). I have extended that in Nativescript and it is working but returning before a tile (image) is provided. https://developers.google.com/android/reference/com/google/android/gms/maps/model/TileProvider – Stavanger75 Jul 25 '16 at 08:27
0

What you want to do is probably not a good idea since it would block the UI while the program is loading something. This problem is most usually solved through either a callback or a promise/custom task implementation. Example with a callback:

getImage: function(url, callback){
    //async call to get the image from cache
    cacheService.getImage(url,  
      function(image){
         callback({ image: image, error: null });
      }, 
      function(error){ 
        callback({ image: null, error: error });
    });
 }

And the usage will then look like

ImageProvider.getImage('someurl.png', function(result) {
    if (result.image) {
        // image has successfully downloaded -- good!
    }
    else {
        // handle result.error
    }
});
Andrew Sklyarevsky
  • 2,095
  • 14
  • 17
  • I would like to use something like yield og await to not block the UI. But i am not able to get it working in Nativescript. I am using extend keyword(override in Java) and is not able to use promise or callback on the function. If their is a way to do this in Nativescript please advice. – Stavanger75 Jul 25 '16 at 08:02