Amazon Alexa - Undefined speech response - javascript

I am trying to invoke the "AskQuestion" in the "SetLanguageIntent" to construct a speech to the user, using Alexa fact skill blueprint.
'SetMyLanguageIntent': function() {
this.attributes['language'] = this.event.request.intent.slots.languages.value;
var language = this.attributes['language'];
this.response
.speak('Okay, I will ask you some questions about ' +
language + '. Here is your first question.' +
this.AskQuestion).listen(this.AskQuestion);
this.emit(':responseReady');
},
'AskQuestion': function() {
var language = this.attributes['language'];
var currentQuestion = flashcardsDictionary[this.attributes['currentFlashcardIndex']].question;
return 'In ' + language + ', ' + currentQuestion;
},
This is the server's response:
{
"version": "1.0",
"response": {
"outputSpeech": {
"ssml": "<speak> Okay, I will ask you some questions about undefined. Here is your first question.undefined </speak>",
"type": "SSML"
},
"reprompt": {
"outputSpeech": {
"ssml": "<speak> undefined </speak>",
"type": "SSML"
}
},
Alexa utters the word "undefined" in the response, Here is the dialogue: "Okay, I will ask you some questions about undefined. Here is your first question. undefined"
Why is the response "undefined"? and how to go about fixing this issue?
Here is the the whole Code:
'use strict';
var Alexa = require('alexa-sdk');
var flashcardsDictionary = [{
question: 'how do you find the length of a string?',
rubyAnswer: 'length',
pythonAnswer: 'Len',
javascriptAnswer: 'length'
},
{
question: 'how do you print to the console or terminal?',
rubyAnswer: 'puts',
pythonAnswer: 'print',
javascriptAnswer: 'console.log'
},
{
question: 'are boolean terms capitalized or not capitalized?',
rubyAnswer: 'not capitalized',
pythonAnswer: 'capitalized',
javascriptAnswer: 'not capitalized'
}
];
var DECK_LENGTH = flashcardsDictionary.length;
var handlers = {
// Open Codecademy Flashcards
'LaunchRequest': function() {
this.attributes['language'] = '';
this.attributes['numberCorrect'] = 0;
this.attributes['currentFlashcardIndex'] = 0;
this.response
.listen('Welcome to Flashcards. In this session, do you want to test' +
' your knowledge in Ruby, Python, or Javascript?').speak(
'Which language would you like to practice?');
this.emit(':responseReady');
},
'SetMyLanguageIntent': function() {
this.attributes['language'] = this.event.request.intent.slots.languages.value;
var language = this.attributes['language'];
this.response
.speak('Okay, I will ask you some questions about ' +
language + '. Here is your first question.' +
this.AskQuestion).listen(this.AskQuestion);
this.emit(':responseReady');
},
// User gives an answer
'AnswerIntent': function() {
var userAnswer = this.event.request.intent.slots.answer.value;
var language = this.attributes['language'];
var languageAnswer = language + userAnswer;
var correctAnswer = flashcardsDictionary[this.attributes['currentFlashcardIndex']][languageAnswer];
if (userAnswer === correctAnswer) {
this.attributes['numberCorrect']++;
var numberCorrect = this.attributes['numberCorrect'];
this.response
.speak('Nice job! The correct answer is ' + correctAnswer + '. You ' +
'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
language + ' questions correct.' + this.AskQuestion)
.listen(this.AskQuestion);
} else {
var numberCorrect = this.attributes['numberCorrect'];
this.response
.speak('Sorry, the correct answer is ' + correctAnswer + '. You ' +
'have gotten ' + numberCorrect + ' out of ' + DECK_LENGTH + ' ' +
language + ' questions correct. Here is your next question.' +
this.AskQuestion).listen(this.AskQuestion);
}
this.attributes['currentFlashcardIndex']++;
this.emit(':responseReady');
},
// Test my {language} knowledge
'AskQuestion': function() {
var language = this.attributes['language'];
var currentQuestion = flashcardsDictionary[this.attributes['currentFlashcardIndex']].question;
return 'In ' + language + ', ' + currentQuestion;
},
// Stop
'AMAZON.StopIntent': function() {
this.response.speak('Ok, let\'s play again soon.');
this.emit(':responseReady');
},
// Cancel
'AMAZON.CancelIntent': function() {
this.response.speak('Ok, let\'s play again soon.');
this.emit(':responseReady');
}
};
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.registerHandlers(handlers);
alexa.execute();
};

Use this.AskQuestion() instead of this.AskQuestion as AskQuestion is a function and not an object.

Related

How to use plotOptions in Highcharts?

The problem I have is that all the json we pass over come from python, and we can't send over javascript in such things. For instance', I need to include the tech from this question but obviously in the plotOptions. I'm just not sure how to do things like reference series, etc. So an example with the above series would be great. I tried the following but it didn't work since this is not what I expected it to be.
options.plotOptions = options.plotOptions || {};
options.plotOptions.series = options.plotOptions.series || {};
options.plotOptions.series.point =
options.plotOptions.series.point || {};
options.plotOptions.series.point.events =
options.plotOptions.series.point.events || {};
options.plotOptions.tooltip = {formatter: function() {
var text = '';
if(this.series.name == 'MSFT') {
text = this.x + ': ' + this.series.name +
'<br> $' + Highcharts.numberFormat(this.y, 0);
} else {
text = 'In ' + this.x + ' the median value was' + this.median +
'and the total $' + Highcharts.numberFormat(this.y, 0);
}
return text;
}
options.plotOptions.series.point.events.click = function() {
if (this.options.url){
window.open(this.options.url);
}
}

ContextMenuItem context function is not executing

I want my context menu item to be visible only if the clicked node is a link i.e. and href is either a magnet link or a torrent link. But item is visible for all the links because context function is not executing, can anybody help why context function is not executing?
Here is the code:
exports.main = function() {
var cm = require("sdk/context-menu");
var contextCode = ' self.on("context", function (node) { '+
' while(node.nodeName!="A") { node = node.parentNode; } '+
' var pat_magnet = /^magnet:/i; ' +
' var pat_torrent = /.torrent$/i; ' +
' if(pat_torrent.test(node.href) || pat_magnet.test(node.href)) { return true; } '+
' else { return false; } '+
' }); ';
var clickCode = ' self.on("click", function(node,data){ '+
' while(node.nodeName!="A") { node = node.parentNode; } '+
' var pat_hash = /[0-9abcdef]{32,40}/i; ' +
' var result = node.href.match(pat_hash); '+
' var hash = "" '
' if(result != null) { hash=result[0]; } '+
' var xhr = new XMLHttpRequest(); '+
' if(hash != "") { '+
' var apiCall = "https://www.furk.net/api/dl/add?api_key=*************&info_hash="+hash; '+
' } '+
' else{ '+
' var apiCall = "https://www.furk.net/api/dl/add?api_key=*************&url="+encodeURI(node.href); '+
' } '+
' xhr.open("GET",apiCall,true); '+
' xhr.onreadystatechange = function(){ if(xhr.readyState = 4) { if (xhr.response.status = "ok") { alert("Torrent added to Furk."); } else { alert("Torrent could not be added to Furk."); } } } '+
' xhr.send(null); '+
' });';
cm.Item({
label: "Add to Furk",
context: cm.SelectorContext("a[href]"),
contentScript: contextCode + clickCode
});
};
Please always post self-containied examples that can be directly tried in the future.
Now back to your problem: The content script actually has a syntax error.
The following line:
' var pat_torrent = /.torrent$/i ' +
lacks a semicolon, and should be:
' var pat_torrent = /.torrent$/i; ' +
The reason automatic semicolon insertion (ASI) does not work here is: The "code" is actually a string that has no newlines in it whatsoever. If there were newlines, then ASI would have worked.
Anway, another reason not to have complex content script inline. Have a look at contentScriptFile.
This error is actually logged, but the presentation sucks. In the Browser Console:
[20:57:51.707] [object Error] (expandable)
In terminal:
console.error: context-magnet:
Message: SyntaxError: missing ; before statement
Here is a fixed, reproducible sample:
var cm = require("sdk/context-menu");
var contextCode = ' self.on("context", function (node) { '+
' while(node.nodeName!="A") { node = node.parentNode; } '+
' var pat_magnet = /^magnet:/i; ' +
' var pat_torrent = /.torrent$/i; ' +
' if(pat_torrent.test(node.href) || pat_magnet.test(node.href)) { return true; } '+
' else { return false; } '+
' }); ';
cm.Item({
label: "magnet test",
context: cm.SelectorContext("a[href]"),
contentScript: contextCode
});
Edit ' var hash = "" ' has the same problem, and there are might be other such errors that I missed skimming this new code.
As I already said, please use contentScriptFile and not contentScript for long-ish scripts.
Another edit
Here is a builder using contentScriptFile, where I also fixed a couple of other errors, the most important of which are:
Use permissions so that the XHR will work.
Correctly set up the XHR to use responseType and overrideMimeType().
Use onload/onerror instead of onreadystatechange.

Can't define variable in JavaScript object literal [duplicate]

This question already has answers here:
Self-references in object literals / initializers
(30 answers)
Closed 8 years ago.
Why does this code work...
var message = {
texts: {
text1: 'Hello',
text2: 'World'
},
greet: function() {
console.log(this.texts.text1 + ' ' + this.texts.text2 + '!');
}
}
message.greet();
...but this doesn't?
var message = {
texts: {
text1: 'Hello',
text2: 'World'
},
both: this.texts.text1 + ' ' + this.texts.text2 + '!',
greet: function() {
console.log(this.both);
}
}
message.greet();
It gives me "both is not defined" error. What am I missing here? Something's wrong withthis.both? I'm total newbie when it comes to object literal
Because in second case this is still not exist when you define both. if you will turn both to method, like in this example : http://jsfiddle.net/YyWMQ/ , it will work.
both: function(){ return this.texts.text1 + ' ' + this.texts.text2 + '!'}
Imho , good question , +1
var message = {
texts: {
text1: 'Hello',
text2: 'World'
},
// here this refers to the scope where message is defined
both: this.texts.text1 + ' ' + this.texts.text2 + '!',
greet: function() {
console.log(this.both);
}
}
message.greet();
To understand it you can try as given below
this.texts = {
text1: 'Alternate Hello',
text2: 'World'
};
var message = {
texts: {
text1: 'Hello',
text2: 'World'
},
// here this refers to the scope where message is defined
both: this.texts.text1 + ' ' + this.texts.text2 + '!',
greet: function() {
console.log(this.both);
}
}
message.greet();
Your misunderstanding is at the following line:
both: this.texts.text1 + ' ' + this.texts.text2 + '!',
You could use as function and return a value like:
both: function(){ return this.texts.text1 + ' ' + this.texts.text2 + '!'; } ,
And finally
greet: function() {
console.log(this.both());
}
When calling greet, `this' will be the parent obj, message. This is not the case when you're actually constructing the message object. You could write something similar like:
var Message = function () {
this.texts = {
text1: 'Hello',
text2: 'Word'
}
this.both = this.texts.text1 + ' ' + this.texts.text2 + '!';
}
Message.prototype.greet = function () {
console.log(this.both);
}
message = new Message();
message.greet();

What is the optimal way to load form data into a string and then to localStorage?

Is this the optimal way to load form data into a string and then to localStorage ?
I came up with this on my own, and I am not good in programming. It works, for what I need, but I am not sure if it's a bulletproof code?
<script>
var sg = document.getElementById("selectedGateway");
var sd = document.getElementById("selectedDestination");
var dm = document.getElementById("departureMonth");
var dd = document.getElementById("departureDay");
var dy = document.getElementById("departureYear");
var rm = document.getElementById("returnMonth");
var rd = document.getElementById("returnDay");
var ry = document.getElementById("returnYear");
var ad = document.getElementById("adults");
var ch = document.getElementById("option2");
$("#searchRequestForm").submit(function() {
var string = 'From: ' + sg.value + ' \nTo: ' + sd.value + ' \nDeparture: ' + dm.value + '/' + dd.value + '/' + dy.value + ' \nReturn: ' + rm.value + '/' + rd.value + '/' + ry.value + ' \nNumber of adults: ' + ad.value + ' \nNumber of children: ' + ch.value;
localStorage.setItem("string", string);
});
</script>
I would use something like the following so that I could deal with an object and its properties rather than a big string. Note that other than the jQuery selectors, this is pure JavaScript.
Demo: http://jsfiddle.net/grTWc/1/
var data = {
sg: $("#selectedGateway").val(),
sd: $("#selectedDestination").val()
// items here
};
localStorage.setItem("mykey", JSON.stringify(data));
To retrieve the data:
var data = JSON.parse(localStorage["mykey"]);
alert(data.sg);
See Also:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify
http://api.jquery.com/jQuery.parseJSON/
I prefer a table driven approach so there is no repeated code (DRY):
var ids = [
"selectedGateway", "From: ",
"selectedDestination", "\nTo :",
"departureMonth", "\nDeparture: ",
"departureDay", "/",
"departureYear", "/",
"returnMonth", " \nReturn: ",
"returnDay", "/",
"returnYear", "/",
"adults", " \nNumber of adults: ",
"option2", " \nNumber of children: "];
var submitStr = "";
for (var i = 0; i < ids.length; i+=2) {
submitStr += ids[i+1] + document.getElementById(ids[i]).value;
}
localStorage.setItem("string", submitStr);
You could define a function such as the one below to directly get the values by id so then it would be simpler when you build your string.
function form(id) {
return document.getElementById(id).value;
}

How to Use Inheritance in JavaScript with Constructor Methods Returning Object Literals with Private Properties?

var Animal = function(config) {
config = config || {};
var name = config.name,
numLegs = config.numLegs,
weight = config.weight,
speed = config.speed,
sound = config.sound
return {
getName: function () {
return name;
},
getNumLegs: function () {
return numLegs;
},
getWeight: function () {
return weight;
},
getSpeed: function () {
return speed;
},
getSound: function () {
return sound;
},
run: function(distance, unit) {
unit = unit || 'miles';
return 'The ' + name + ' ran ' + distance + ' ' + unit;
},
speak: function() {
return 'The ' + name + ' says "' + sound + '"';
}
}
};
function DragonFly(config) {
var me = {},
numWings = config.numWings;
me.prototype = new Animal(config);
me.getNumWings = function() {
return numWings;
};
me.fly = function(distance, unit) {
unit = unit || 'miles';
return 'The ' + me.name + ' flew ' + distance + ' ' + unit;
}
return me;
}
var dragonFly = new DragonFly({
numWings: 2,
name: 'DragonFly',
numLegs: 6
});
Okay, coming from a PHP background, I don't understand inheritance in JavaScript one bit and I'd like some help.
Basically, here's what I'd like to be able to do with an instance of the dragonFly object:
dragonFly.getName(); // 'DragonFly'
dragonFly.fly(1, 'mile'); // 'The dragonfly flew 1 mile';
dragonFly.run(1, 'yard'); // 'The dragonfly ran 1 yard';
I'd also like to know how to override methods and call the parent of those overridden methods. What is wrong with my approach? All the examples above return undefined or throw an error. The main reason I went with the object-literal style is so I could make properties private.
the "fastest" way :
var Animal = function(config) {
config = config || {};
var name = config.name,
numLegs = config.numLegs,
weight = config.weight,
speed = config.speed,
sound = config.sound
return {
getName: function () {
return name;
},
getNumLegs: function () {
return numLegs;
},
getWeight: function () {
return weight;
},
getSpeed: function () {
return speed;
},
getSound: function () {
return sound;
},
run: function(distance, unit) {
unit = unit || 'miles';
return 'The ' + name + ' ran ' + distance + ' ' + unit;
},
speak: function() {
return 'The ' + name + ' says "' + sound + '"';
}
}
};
function DragonFly(config) {
var me = new Animal(config);
var numWings = config.numWings;
me.getNumWings = function() {
return numWings;
};
me.fly = function(distance, unit) {
unit = unit || 'miles';
return 'The ' + me.name + ' flew ' + distance + ' ' + unit;
}
return me;
}
var dragonFly = new DragonFly({
numWings: 2,
name: 'DragonFly',
numLegs: 6
});
You are mixing 2 kind of "inheritance" in your script , the "classical" inheritance and the prototypal inheritance , you cant do that unless you want to be in serious trouble. both work , both have their pros and cons. Stick to the "classical" inheritance , or object augmentation since you began with it.
An object literal doesnt have a prototype , functions have prototypes. That's why in my opinion js isnt "really" object oriented , but it can mimic object oriented langages
A good exercice now would be to try using functions and prototypes , though i'm not sure you could create private fields with that.
Edit : the me.name should be me.getName() since name is "private". i think.

Categories