-2

I want to use "data" outside of this function. Please can some one show me how?

    resemble('/Users/User/Documents/dev/engineerappcopy/VGimages/'+deviceName+'.png')
             .compareTo('/Users/User/Documents/dev/engineerappcopy/VGimages/'+"nexUpdate"+'.png')
             .ignoreColors().onComplete(function(data) {
                 browser.sleep(5000)
                 console.log(data);
                 data.getDiffImage().pack().
                 pipe(fs.createWriteStream('/Users/User/Documents/dev/engineerappcopy/VGimages/'+deviceName+'VG.png'));

                         });

I am aware that this is asynchronous, however I am struggling with this.

  • you want to use the data variable in some other file? One way is to add it as a global variable. you can use event emitters to pass data aswell. please tell where you want to use this data variable so i can advice accordingly – Asif Saeed Jan 21 '17 at 19:23
  • Possible dupe of https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron – JohnnyHK Jan 21 '17 at 19:28
  • @Asif Saeed I just want to use it in another function...It cannot just be a global variable because this is not synchronous – iHateNodeJS Jan 21 '17 at 19:31
  • yes define a global variable and pass the data variable to it e.g. global.dataVar = data; when data is recieved and use it in other function but tht function should be called after this – Asif Saeed Jan 21 '17 at 19:34
  • @iHateNodeJS If this is an asynchronous you can envelop the above function in a promise, then you can use the resolve "data" to the "then" function of promise. – Amitesh Jan 21 '17 at 19:34
  • @JohnnyHK Can someone please write it for me, I have tried to do this all day I cannot make sense of it – iHateNodeJS Jan 21 '17 at 19:40
  • @Amitesh can you please write that, it makes no sense to me unless i see it as code – iHateNodeJS Jan 21 '17 at 19:41
  • 1
    @iHateNodeJS Just Go through the JohnnyHK link, it has explained how to create a promise and then use the data. – Amitesh Jan 21 '17 at 19:44
  • @Amitesh if you understand it please answer my question... – iHateNodeJS Jan 21 '17 at 19:51
  • I cannot use a call back!!!!!!!!!!!!!!!!!!!!!!!!!!! ok – iHateNodeJS Jan 21 '17 at 20:03
  • 1
    @iHateNodeJS why can't you use a callback? – Paul Jan 21 '17 at 21:45
  • 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) – Quentin Jan 22 '17 at 09:28

2 Answers2

1

I would suggest you to use EventEmitters. You can use this if at all you want to indicate if any action is finished and optionally you can pass the data as well.

Create a new javscript file 'my-emitter.js'

my-emitter.js (ES6 version)

const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

module.exports = myEmitter;

OR

my-emitter.js (Javascript version)

var EventEmitter = require('events').EventEmitter;
var util = require('util');

function MyEmitter(){
    EventEmitter.call(this);    
}

util.inherits(MyEmitter,EventEmitter);
myEmitter = new MyEmitter();

module.exports = myEmitter;

Your code snippet:
(Check the comments in the code). Emit an event saying that data is available after the async operation is complete myEmitter.emit('img-op-complete',data);

var myEmitter = require('./my-emitter.js'); //Get your emitter from the module
resemble('/Users/User/Documents/dev/engineerappcopy/VGimages/'+deviceName+'.png')
             .compareTo('/Users/User/Documents/dev/engineerappcopy/VGimages/'+"nexUpdate"+'.png')
             .ignoreColors().onComplete(function(data) {
                 browser.sleep(5000)
                 //Emit the event that data is available and pass the data
                 myEmitter.emit('img-op-complete',data);
                 console.log(data);
                 data.getDiffImage().pack().
                 pipe(fs.createWriteStream('/Users/User/Documents/dev/engineerappcopy/VGimages/'+deviceName+'VG.png'));

                         });

othermodule.js
Where ever you want the data (if in other module), use the below piece of code

var myEmitter = require('./my-emitter.js'); //Get your emitter from the module
myEmitter.on('img-op-complete', function(data){
   console.log(data); //You'll get your data here after op is done
})

Fore more info on events, https://nodejs.org/dist/latest-v6.x/docs/api/events.html

NOTE: Promises is also nice solution, but if you use promises good design if data is needed within the same module. But events present a good design pattern in node.js

manikawnth
  • 2,739
  • 1
  • 25
  • 39
0

I would suggest go with promises, you would be able to use this promise across module also if you export it.

There are some really nice articles about how to use promises like Promise.

Coming to how to approach the above issue via promises,

function foo(){
    return new Promise(function(resolve,reject){
        resemble(<yourPath>)
         .compareTo(<yourPath>)
         .ignoreColors().onComplete(function(data) {
             //for best practice do handle errors 
             if(err<anyError>){
                reject(err);
             } else{
               resolve(data);
             }
        });
    })
}

Now You can use the above promise where you want to use the data variable :

foo().then(function(<data>){
    //do whatever you wish to do with the data
}).catch(function(<err>){
    //handle the error
});
Amitesh
  • 992
  • 7
  • 11
  • hi amitesh, thank you very much for you answer. I am trying to implement it, you say in the arguments of "foo.then", what should data be? sorry if this sounds stupid this is the first time I have ever used nodeJS – iHateNodeJS Jan 22 '17 at 13:50
  • @iHateNodeJS can you show the modifications that you made, and data is the value you wanted to return. – Amitesh Jan 22 '17 at 14:20
  • function foo(p1,p2){ return new Promise(function(resolve,reject){ resemble('/Users/User/Documents/dev/engineerappcopy/VGimages/'+deviceName+'.png') .compareTo('/Users/User/Documents/dev/engineerappcopy/VGimages/'+"nexUpdate"+'.png') .ignoreColors().onComplete(function(data) { //for best practice do handle errors //console.log(data); resolve(data); }); }) } – iHateNodeJS Jan 22 '17 at 14:26
  • foo().then(function(data){ console.log(data.toString()); }).catch(function(err){ console.log(err.toString()); }); – iHateNodeJS Jan 22 '17 at 14:27
  • im just testing it using console.log, but it just log "Object object" – iHateNodeJS Jan 22 '17 at 14:28
  • @iHateNodeJS you don't need a toString() javascript provides native support to display object structure when you try to print it, http://stackoverflow.com/questions/5612787/converting-an-object-to-a-string – Amitesh Jan 22 '17 at 15:29