question

CodeKat avatar image
CodeKat asked

Alexa's "this" is undefined

I'm currently developing some code using node.js. I'm looking to save the state of something in the attributes of the "this" item or "session" within the index.js. Here's how the code looks:

function getAlexaState(){
 if(typeof this.attributes == 'undefined'){
        
        // Completely new instance
        this.attributes = { AlexaState : '' };
        this.attributes.AlexaState = <somestring>; 
        return this.attributes.AlexaState;
    }
    else{
        return  this.attributes.AlexaState;
    }
};

Whenever I call to "this" or use "this.session" it tells me that it is undefined (specifically "this" is undefined, not it's properties), as I'm trying to follow the example code's use of this here (https://github.com/alexa/skill-sample-nodejs-highlowgame/blob/master/src/index.js). I'm tempted to just save these values to DynamoDb and retrieve it constantly whenever I have an intent triggered. This happened both locally and on my Lambda instance (Using the "Alexa Start Session" as the testing config).

What could be the issue?

intentsnode_js
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

GadgetChannel avatar image
GadgetChannel answered

If your function is declared outside of the session or intent handler classes it will likely not have access to "this". If you are calling this from one of your handlers, the easiest way around this is to call change the function so it looks like this:

function getAlexaState(alexa) {
	if(typeof alexa.attributes =='undefined') {
		// Completely new instance
		alexa.attributes = {AlexaState : ''};
		alexa.attributes.AlexaState = <somestring>;
		return alexa.attributes.AlexaState;
	}
	else {
		return alexa.attributes.AlexaState;
	}
};

and then call it from the handler like follows:

getAlexaState(this);

That will pass the relevant object to the function and allow it to access it.

1 comment
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

CodeKat avatar image CodeKat commented ·

This was the issue! Seems that "this" is not global. Updated the code and it's working great. Thanks!

0 Likes 0 ·
ppollmanns avatar image
ppollmanns answered

this is tricky (pun intended). i think it is absolutely impossible to decide from your code snippet what went wrong and where. are you using the 'getAlexaState' function inside of some of the statehandlers?

like:

var startGameHandlers = Alexa.CreateStateHandler(states.STARTMODE, {
                'NewSession': getAlexaState,
		'Unhandled': function() {
 	                       console.log("UNHANDLED");
       	   	               var message = 'Say yes or no.'; 
                               this.emit(':ask', message, message);
                             }
});    

(note that your method comes without parentheses after the methodname because it not yet the method invocation)

if so, the "this" should be accessible.

2 comments
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

CodeKat avatar image CodeKat commented ·

Oh, sorry about that! Yes the function is behind called from an intent. For example:

var handlers= {
    
    'AMAZON.HelpIntent' : function(){
        getAlexaState();
        }
    },


0 Likes 0 ·
ppollmanns avatar image ppollmanns CodeKat commented ·

i see you've solved the issue already but another take on this issue would be to change your handlers declaration to:

var handlers= {
       'AMAZON.HelpIntent' :  getAlexaState
     };

0 Likes 0 ·