0

I'm trying to implement communication with coap server by using coap package. My goal is to get response (in coap.request() response event handler) and then pass it to other variables and functions.

Event: 'response'

function (response) { }

Emitted when a response is received. response is an instance of IncomingMessage.

If the observe flag is specified, the 'response' event will return an instance of ObserveReadStream. Which represent the updates coming from the server, according to the observe spec.

I've created class someClass, which contains serverRequest() method.

Method serverRequest() takes mandatory options argument (which sets request options for coap.request()) and optional argument which sets message body if needed. Purpose of this method is to send a request to server and return response, which is instance of coap.IncomingMessage.

const coap = require('coap');

class someClass {
  constructor(someOption) {
    this.someOption = someOption;
  }

  serverRequest(options, messageBody=undefined) {
    const request = coap.request(options);
    let response;
    request.on('response', res => {
      console.log(response); // undefined
      response = res;
      console.log(response);  // valid response
    });
    if (messageBody !== undefined) {
      request.write(messageBody);
    }
    request.end();
    console.log(response);  // undefined
    return response;
  }
}

I send message and obtain response successfully, however response variable inside anonymous function seems to be unique and different from response variable inside serverRequest method.

Question: How can I pass variables from anonymous functions to other scopes?

Lycopersicum
  • 529
  • 1
  • 6
  • 17

1 Answers1

1

You can call your method inside the body of an anonymous function:

class Test 
{
  constructor(someOption) {
    this.someOption = someOption;
  }

  myMethod ( data ) {
    //.. do something
  }

  anotherMethod() {
    var data = {answer:42};
    var that = this;
    functionWithCallback( function(differentOption) {
      that.myMethod(data);
      that.someOption = differentOption;
    });
  }       
}

Edit based on comments: Using var that = this; is a common way to cheat the scope. this will always belong to the scope of a function, method or anonymous, both are still functions.

Therefore to keep a reference to the class scope, I assign the this from the class method's scope to var that so that when this changes to the anonymous' function scope, we still have access to it.

In ECMAscript 6 and above when using arrow functions, the this keyword is not re-bound and we don't have to cheat the scope.

class Test 
{
  constructor(someOption) {
    this.someOption = someOption;
  }

  myMethod ( data ) {
    //.. do something
  }

  anotherMethod() {
    var data = {answer:42};
    functionWithCallback( (differentOption) => {
      this.myMethod(data);
      this.someOption = differentOption;
    });
  }        
}

Edit made by question author:

I didn't have problems by using this keyword, script produced same results.

Lycopersicum
  • 529
  • 1
  • 6
  • 17
DarkMukke
  • 2,469
  • 1
  • 23
  • 31
  • I don't see, why you've used `that` variable, perhaps you could clarify that? I can access class methods and variables from anonymous function, problem is that after changing variable value or calling method, which sets class value variable, value stays changed only in that anonymous function, when I print class variable after receiving response, variable stays same as before receiving response. – Lycopersicum Jan 09 '18 at 12:40
  • 1
    ok I will edit the answer, your question is a bit complicated but basically you are trying to understand scopes – DarkMukke Jan 09 '18 at 12:41
  • @Lycopersicum have a look now – DarkMukke Jan 09 '18 at 12:53
  • It doesn't work still, currently I'm trying to write function with callback to show you, that it doesn't work – Lycopersicum Jan 09 '18 at 13:13
  • I've wrote my own function with callback and it worked, it worked just fine, however on my project it doesn't work. I've tried printing `this` object by typing `console.log(this);` inside two places: inside abstract function and just before `return` statement of method. Both showed me different results, in the abstract function everything seems to be as expected, however in method scope it stays same all the time, also after calling `obj.serverRequest()` `obj.variable` that I try to change in my project stays the same... – Lycopersicum Jan 09 '18 at 13:48
  • @Lycopersicum can you log right before `if (messageBody !== undefined) {` just to check out of the scope. I just want to make sure that `request.write(messageBody);` or `request.end();` don't modify the `response` variable – DarkMukke Jan 09 '18 at 16:41
  • I've resolved the problem, it was asynchronous calls of `console.log()` and other statements. Everything works as you've pointed out, the only difference is that I was checking incorrectly. – Lycopersicum Jan 09 '18 at 20:39