Code Monkey home page Code Monkey logo

Comments (18)

jerolimov avatar jerolimov commented on June 15, 2024 5

The keyword this is bounded to the last function scope, which is in your case the request callback block.

Instead of writing function (error, response, body) { .. } you should write (error, response, body) => { ... }. This does not re-bind the this-scope, so that this is still the "alexasdk" callback.

Hope this helps you @ferventgeek and @bjm88.

Complete fix for the original issue on top:

const Alexa = require('alexa-sdk');
const https = require('https');

const handlers = {
    'GoGetRESTfoo': function () {
        console.log("GoGetRESTfoo called");
        promisedRESTrequest('Some foo bar url').then((response) => {
            console.log("Success!", response); // Yea, REST all the things
            this.emit(':tell', 'ok');
        }, (error) => {
            console.error("Failure!", response); // Boo, bad feels 
            this.emit(':tell', 'Hmm.. that didn\'t work.  Check the CloudWatch Luke.');
        });
    },

    // lots more handlers..
}

exports.handler = (event, context) => {
    const alexa = Alexa.handler(event, context);
    alexa.APP_ID = APP_ID;
    alexa.registerHandlers(handlers);
    alexa.execute();
};

from alexa-skills-kit-sdk-for-nodejs.

JeremyBYU avatar JeremyBYU commented on June 15, 2024 1

I got it to work using async functions. Here is my code

import * as Alexa from 'alexa-sdk'

const handlers = {
    GiveNoteAsync() {
      setTimeout(() => {
        this.emit(':tell', 'Hello Async')
      }, 500)
    },
    GiveNoteSync() {
       this.emit(':tell', "Hello Sync")
    )
}

export function handler(event, context, callback) {
  const alexa = Alexa.handler(event, context)
  alexa.registerHandlers(handlers)
  alexa.execute()
}

I tested this and it worked just fine. Hope this helps.

from alexa-skills-kit-sdk-for-nodejs.

schaze avatar schaze commented on June 15, 2024 1

I am having the same issue. Asynchronous actions with callback works, however when using Promises, it does not work. My 'then' is never called and when I test using a 'reject' I am getting an error about an unhandled promise rejection (even though I have a valid catch there).
How do we move forward with this? Should I create a new issue for this since the title of this does not specifically mention promises and async callbacks actually work?
I would really like doing alexa skills without callback hell using promises.

from alexa-skills-kit-sdk-for-nodejs.

schaze avatar schaze commented on June 15, 2024 1

So, for some reason it now started to work for me using Promises. To be honest I do not really know why or what I did (or what I missed before).

Here is an example of a simple Intent that will start my TV through my FHEM server via a Logitech Harmony Hub (it uses a PHP REST API I put in front of FHEM called bridgeAPI).

'activityFernsehen': function () {
    var that=this;
    bridgeAPI.fhemSetFieldValue("WZ.harmony","activity", "Fernsehen")
      .then(function(){  
         that.emit(':tell', utils.getRandomOKResponse());
    }); 
}, 

Can someone try a similar Intent setup using any arbitrary Promise call?

from alexa-skills-kit-sdk-for-nodejs.

ventz avatar ventz commented on June 15, 2024

@JeremyBYU - Thank you! Works like a charm.

from alexa-skills-kit-sdk-for-nodejs.

runtimeware avatar runtimeware commented on June 15, 2024

Are there any alternatives to doing it this way (using setTimeout)? I can't seem to get it to work for whatever reason anyhow!

from alexa-skills-kit-sdk-for-nodejs.

selvakn avatar selvakn commented on June 15, 2024

@runtimeware : I also got stuck on this issue. You dont really need the setTimeout.
As long as the correct context for emit is maintained (either using another variable to capture this, or es 6 fat arrow) in the callback of the async flow, it works.

The caveat is by default, the maximum default time for any lambda function is 1 sec. And if it takes longer than that, an invalid response is automatically returned and this is not logged. Try increasing it, based on your usecase

from alexa-skills-kit-sdk-for-nodejs.

JeremyBYU avatar JeremyBYU commented on June 15, 2024

The setTimeout was only there to demonstrate that asynchronous functions do work inside this package (alexa-skil-kit-sdk). You can use any other async function that you need.

As for the maximum time of a lambda function, I'm pretty sure that its actually 5 minutes. Link

As for how long the Alexa service will wait for a response from you, that I'm not sure about.

from alexa-skills-kit-sdk-for-nodejs.

ventz avatar ventz commented on June 15, 2024

I think there is a bug somewhere, because I am also getting some very mixed responses. Stuff that works, only works 1/3 or at best 2/4 times.

I looked up setting a proper return, but that also fails on some stuff.

If anyone has a complete real example (abstract the API/REST call as a function) -- that would be great.

I also think there is a bug in the SDK somewhere btw, because if you take the sample stuff "as is" and add your REST calls, it produces an issue in regards to the return/timeout. (even when the APIs take 1-2 seconds)

from alexa-skills-kit-sdk-for-nodejs.

JeremyBYU avatar JeremyBYU commented on June 15, 2024

Im doing asynchronous DB calls and it's working everytime for me. But the max time it's been taking for DB (dynamodb) calls is less than a sec, so I can't speak for timeout issues occuring on long asynchronous calls.

from alexa-skills-kit-sdk-for-nodejs.

ammulder avatar ammulder commented on June 15, 2024

FYI if you create a then function as displayed in the original post, probably the "this.emit" will not work because "this" points to the wrong thing.

However if you create a then function as displayed in the timeout solution, it should work because it preserves "this". So you may need your code to look like this:

somePromise.then(
  (result) => {... this.emit ...},
  (error) => {... this.emit ...}
);

from alexa-skills-kit-sdk-for-nodejs.

ventz avatar ventz commented on June 15, 2024

@schaze - I agree -- this is frustrating. If you haven't already, please open a separate issue. I am also running into this with every skillset that has an API call. Even when successfully returning/emit-ing to properly "close" the connection with Alexa, it does the right thing in some case (and others it does not because it times out), and then still fails.

Also - it would be great to get a working example of something with an API call.

from alexa-skills-kit-sdk-for-nodejs.

bjm88 avatar bjm88 commented on June 15, 2024

I also had to propogate "this" to a variable so its available in the callback
var alexasdk = this;
request('http://www.google.com', function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode);
alexasdk.emit(':tellWithCard'......
});
after the response from request lib, the this.emit is lost. Perhaps a more elegant way, do authors of AlexaSDK suggest anything?

from alexa-skills-kit-sdk-for-nodejs.

ferventgeek avatar ferventgeek commented on June 15, 2024

this. <meta/>

Thx!

from alexa-skills-kit-sdk-for-nodejs.

 avatar commented on June 15, 2024

resolved by @jerolimov

closing

from alexa-skills-kit-sdk-for-nodejs.

djb61 avatar djb61 commented on June 15, 2024

@jerolimov Have you made your example work correctly when the Promise is rejected?
I'm trying this now and I can fulfill the promise fine using arrow notation but if the promise is rejected I always get UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'type' of null
This is the same issue @schaze mentioned earlier in this thread and I think not related to the binding of this.
Has anyone successfully rejected a promise in a skill handler?

from alexa-skills-kit-sdk-for-nodejs.

djb61 avatar djb61 commented on June 15, 2024

To follow up on my earlier post, this was an issue in my code.

I had a catch handler something like this:

}).catch(() => {
    this.emit(':tell', Messages.ERROR);
});

What was actually happening is that I had forgotten to export ERROR and this was getting passed as a null. This threw an error inside the SDK which the promise then caught as an unhandled rejection. I found this article on Promises and EventEmitters which explained it quite well https://qubyte.codes/blog/promises-and-nodejs-event-emitters-dont-mix

Once I fixed the underlying error the promise rejection started working fine. In case anyone else comes across this I found using setImmediate() was a nice way to get the actual error to be logged in cloudwatch instead of the unhandled rejection so adding this temporarily is quite useful to aid debugging. For example:

}).catch(() => {
    setImmediate(() => {
        this.emit(':tell', Messages.ERROR);
    });
});

from alexa-skills-kit-sdk-for-nodejs.

pawan-mittal avatar pawan-mittal commented on June 15, 2024

@jerolimov Thanks a lot.

from alexa-skills-kit-sdk-for-nodejs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.