2

According to the Watson Assistant API documentation, callbacks are used for returning responses. Below is an example taken from their API Documentation:

var watson = require('watson-developer-cloud');

var assistant = new watson.AssistantV1({
  username: '{username}',
  password: '{password}',
  version: '2018-02-16'
});

var params = {
  workspace_id: '9978a49e-ea89-4493-b33d-82298d3db20d',
  intent: 'hello'
};

assistant.listExamples(params, function(err, response) {
  if (err) {
    console.error(err);
  } else {
    console.log(JSON.stringify(response, null, 2));
  }
});

I am looking to try and promisify this function so I can convert the process into a nice, tidy async/await process and get out of callback hell. I am hosting and executing this code on AWS Lambda. They recently released the node8.10 runtime on Lambda so I am eager to convert all my existing functions using async/await.

Below is my attempt (with sensitive data replaced):

var Watson = require('watson-developer-cloud');
var util = require('util');

var assistant = new Watson.AssistantV1({
    username: "username",
    password: "password",
    version: "2018-02-16"
});

var params = {
    workspace_id: "workspace_id",
    intent: "acronym"
};

var watsonPromise = util.promisify(assistant.listExamples);

exports.handler = async (event) => {
    try {
        var examples = await watsonPromise(params);
        return examples;
    } catch (err) {
        console.log(err);
        return err;
    }
}

This doesn't seem to work and I am getting the following error:

START RequestId: 4f203ed1-4181-11e8-81ec-837163404af0 Version: $LATEST
2018-04-16T14:20:27.792Z    4f203ed1-4181-11e8-81ec-837163404af0    TypeError: Cannot read property '_options' of undefined
    at AssistantV1.listExamples (/var/task/node_modules/watson-developer-cloud/assistant/v1.js:761:51)
    at internal/util.js:230:26
    at exports.handler (/var/task/index.js:21:30)
END RequestId: 4f203ed1-4181-11e8-81ec-837163404af0

After a bit of digging, it seems like my examples object is showing as undefined.

Can anyone please offer any advice? Not really sure what else I can do. It's probably something simple that I'm missing. Thanks.

blueprintchris
  • 853
  • 1
  • 14
  • 31

1 Answers1

7

You could bind function to correct context

var watsonPromise = util.promisify(assistant.listExamples.bind(assistant));

Or call promisified version with correct context

var examples = await watsonPromise.call(assisntant, params);
Yury Tarabanko
  • 39,619
  • 8
  • 73
  • 90
  • 1
    Wow, thanks. Knew it would be something simple. Seems to work :) – blueprintchris Apr 16 '18 at 15:07
  • If you could share why this works vs why mine didn't work that would be excellent. Would love to (try to) understand what's going on. – blueprintchris Apr 16 '18 at 15:10
  • 1
    @blueprintChris `AssistantV1#listExamples` and other methods are well methods so they need to be called in context of `AssistantV1` instance (so that `this` has to be the instance itself). If you save a function to variable and call it later you lose context. You could read more about `this` keyword in javascript [here](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – Yury Tarabanko Apr 16 '18 at 15:16