1

My code is not running, can anybody help. Unable to speak out the text, can i return handler input response. The test function is a http call which may take tieme.

function test(url, number)
{
    return 5;
}

function speak(handlerInput) {
    return handlerInput.responseBuilder
        .getResponse();
}

const NumberFactIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'NumberFactIntent';
    },

    handle(handlerInput) {

    const theNumber = handlerInput.requestEnvelope.request.intent.slots.number.value;
    const repromptOutput = " Would you like another fact?";
    const URL = "http://numbersapi.com";

    test(URL, theNumber).then(function (data) {
             console.log("data is " + data);
             handlerInput.responseBuilder
            .speak("Test Data")
            .reprompt(repromptOutput) 

             return speak(handlerInput);
        }).catch(function (data) {

             console.log("error is " + data);
             handlerInput.responseBuilder
            .speak(`I wasn't able to find a fact for ${theNumber}` )
            .reprompt(repromptOutput)
             return speak(handlerInput);
        }); 
    }
};
  • "The test function is a http call which may take time" - How much time does the http call take. Alexa will time out after 8 seconds, so you need to be returning your response before that happens. – chearmstrong Sep 24 '19 at 09:01
  • if you're deploying your code to AWS Lambda, I'd also suggest checking your CloudWatch logs for any errors. – chearmstrong Sep 24 '19 at 09:06

2 Answers2

1

First of all your test function doesn't return a promise. I don't know if this is intentional and you just cut api calling code to make it simpler, but it should return a promise if you want to use then on it.

If it returns a promise in your full example, then what are you missing is adding a return before test. Also you should return handlerInput from inside of your promise. Code should look like this (i'll remove some of the code, that is not relevant):

const NumberFactIntentHandler = {
    canHandle(handlerInput) {},

    handle(handlerInput) {

    const repromptOutput = " Would you like another fact?";
    const URL = "http://numbersapi.com";

    return test(URL, theNumber).then(function (data) {
             return handlerInput.responseBuilder
                .speak("Test Data")
                .reprompt(repromptOutput) 
        }).catch(function (data) {
             return handlerInput.responseBuilder
                 .speak(`I wasn't able to find a fact for ${theNumber}` )
                 .reprompt(repromptOutput)
        }); 
    }
};

Now you might be wondering why do you need those return's. This is because JS functions implicitly returns undefined, so in this case you have to explicitly tell what should be returned from handle function. Same applies to inside of the promise.

R. Vait
  • 918
  • 2
  • 7
  • 20
  • 1
    "Now, if you still want to use promises, you can. In your case, what are you missing is adding a return before test." - I think you should make it more obvious that this _could_ be the answer here. I think it's kind of lost in the explanation about Promises. Also, their `test` function in the code example doesn't return a Promise so `.then` isn't going to work - maybe also make it clear that that function needs to return a Promise (adding `async` would work of course). – chearmstrong Sep 24 '19 at 09:13
  • 1
    Thanks for your feedback. I got carried away writing an answer yesterday. Looking at it with fresh eyes I see that meaning of the answer probably go lost. I updated my answer according to your remarks. – R. Vait Sep 24 '19 at 10:59
0

This Code might Help You!!

 //use request for http call
 function fun(url) {
      return new Promise((resolve, reject) => {
       request.get(url,(err, res, body) => {
       console.log("url-fetched");
       return resolve(body);
     });
   });
  }

   const NumberFactIntentHandler = {
      canHandle(handlerInput) {..
      },

 async handle(handlerInput) {

   const theNumber =handlerInput.requestEnvelope.request.intent.slots.number.value;
   const repromptOutput = " Would you like another fact?";
   const URL = "http://numbersapi.com";
   let data = await fun(url);

   return handlerInput.responseBuilder
    .speak(data)
    .reprompt('is there any thing i can do for you?')
    .withSimpleCard('Hello', speechText)
    .getResponse();
  };