简体   繁体   中英

Encapsulating API.ai call into an external javascript function is not working

This code works fine:

var apiai = require('apiai');
var app = apiai(<token>);

var request = app.textRequest('jacket', {
  'sessionId': 123456
});

request.on('response', function(response) {
  console.log(response);
  console.log(response.result.fulfillment.speech);
  console.log(response.result.metadata.intentName);
});

request.on('error', function(error) {
  console.log(error);
});

request.end();

And it produces the following console output:

{ id: '2865abde-ac8f-4ac3-816e-483c68f709d0',
  timestamp: '2016-11-08T22:38:56.461Z',
  result:
   { source: 'agent',
     resolvedQuery: 'jacket',
     action: '',
     actionIncomplete: false,
     parameters: {},
     contexts: [ [Object] ],
     metadata:
      { intentId: '357af94f-00b3-4016-a661-732419ddafd6',
        webhookUsed: 'false',
        intentName: 'clothing' },
     fulfillment: { speech: 'clothing2', messages: [Object] },
     score: 0.6 },
  status: { code: 200, errorType: 'success' },
  sessionId: '123456' }
clothing2
clothing

However, when I try to break this apart into a function call, things don't work so well:

File: main.js

 var apiai = require('apiai');
 var app3 = apiai(<token>);

exports.getresponse = function(inputstring){
  var request = app3.textRequest(inputstring, {'sessionId': 123456});
  request.on('response', function(response) {
    return(response);
});
  request.on('error', function(error) {
    return(error);
});
  request.end();
};

File: moda.js

var express = require("express");
var app = express();
var joe = require('./main.js');
console.log(joe.getresponse('jacket'));
app.listen(3000);

When I run moda.js (node moda.js), I get only

undefined

as the console output.

What am I doing wrong here?

Thanks so much!

joe.getresponse() doesn't have an explicit return, thus it has an implicit return undefined;

That's why you are seeing undefined in your console output.

The reason is a bit complicated, and fundamental to javascript programming, but it has to do with Callbacks, and asynchronous execution of javascript.

With this line here, you are actually adding an anonymous function as a callback. That function doesn't actually get executed until it is invoked (typically in response to an event).

  request.on('response', function(response) {
    return(response);
});

So while you are returning the response, the scope of that return is not inside the getresponse() outer function, but instead inside the response event emitter.

Instead, you'll need to capture the Response value in a way you can determinisitcally access it. By supplying your own callback to the getresponse() method, that callback will have access to the response object.

It would looks something like this:

main.js

var apiai = require('apiai');
var app3 = apiai(<token>);

exports.getresponse = function(inputstring,callback){
  var request = app3.textRequest(inputstring, {'sessionId': 123456});
  request.on('response', function(response) {
    callback(null,response);
});
  request.on('error', function(error) {
    callback(error,null);
});
  request.end();
};

moda.js

var express = require("express");
var app = express();
var joe = require('./main.js');
joe.getresponse('jacket', function(error,response) {
     if(error) { console.error(error); }
     console.log(response);
 });
app.listen(3000);

Instead of returning the response value, I am invoking a caller supplied callback, which then handles the response (calls console.log).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM