Handling Null in Alexa - javascript

I submitted a skill for Alexa and I got the following error from the Amazon team:
Issue: [StateIntent] Intent, [State] slot
Steps To Reproduce:
User: "Alexa open states symbols"
Skill: "Welcome to state symbols. Give me the name of a state and I will give you symbols used by the state. You can also say random before the state to get a random symbol or ask for specific information for a symbol for a state. I have information about state dog, state flower, state motto, state song, state tree, state bird and state mineral"
User: "tell me about {}"
Skill: "There was a problem with the requested skill's response"
In other words I am not handling situations where the slot is null. I tried several different things to address null in my code but all of them came back with the same error how can I address this? This is a sample section of the code.
function handleStateResponse(intent, session, callback){
var state = intent.slots.State.value.toLowerCase( );
if (!states[state]){
var speechOutput= `I couldn't find that state would you like to ask about another state?`;
var repromptText = `Please try again`;
var header =`not found`;
}else{
var state_dog = states[state].state_dog;
speechOutput = `${capitalizeFirst(state)}'s state dog is the ${state_dog}`;
repromptText = `Would you like to learn about another state?`;
header =capitalizeFirst(state);
}
var shouldEndSession=false;
callback(session.attributes, buildSpeechletResponse(header, speechOutput, repromptText, shouldEndSession));

First things first. If you are not already logging your incoming requests you should do so. It includes valuable information to the request(ie intents, slots, IDs...). Here you can see the structure of the different request types.
Ok, back in your user scenario the user leaves the slot empty. In other words Alexa sends a request to your lambda function with an empty slot. which looks something like this.
{
"type": "IntentRequest",
"intent": {
"name": "StateIntent",
"confirmationStatus": "NONE",
"slots": {
"State": {
"name": "State",
"confirmationStatus": "NONE"
}
}
}
}
When Alexa sends a request with an empty slot it does not include a value member in your 'State'-object.
So to test for this. You only have to put one if-clause.
if (intent.slots.State.value) {
// *Here you can check if the value is right or just continue with the state_dog part*
}
else {
// *Here you can prepare the callback params for 'empty slot'*
}
I hope this helps and good luck with your certification.

Related

Ember Data creates duplicate record on model save() | ember-cli v3.19

Ember duplicates models on save.
I have two models
**bill**
export default class BillModel extends Model {
#attr("string", { defaultValue: "", uppercase: true })
vehicleNumber;
#attr("string", { defaultValue: "" })
customerName;
#attr("number", { defaultValue: "" })
customerMobileNumber;
#attr("date")
createdOn;
#hasMany("bill-item")
billItems;
#attr("number", { defaultValue: 0 })
total;
#computed(
"billItems.#each.cost"
)
get computedTotal() {
let total = 0;
this.billItems.forEach((item) => {
if (item.cost)
total += parseFloat(item.cost);
});
return parseFloat(total);
}
}
**bill-item**
export default class BillItemModel extends Model {
#attr("string", { defaultValue: "" })
itemName;
#attr("number", { defaultValue: null })
cost;
}
Then I create a new record of the "bill" model and create a "bill-item" record and add that in the billItems property of the bill model.
let bill = this.store.createRecord("bill");
bill.billItems.addObject(this.store.createRecord("bill-item"));
then when I use the save() the "bill" model, I now have two records in the billItems property.
One with id returned from the server response and one with
But I should have only one.
Below is the server response.
{
"vehicleNumber": "1231",
"customerName": "123",
"customerMobileNumber": 1231232312,
"createdOn": null,
"total": 23123,
"billItems": [
{
"itemName": "1231",
"cost": 23123,
"id": "9510"
}
],
"id": 467
}
Why does the ember store now have 2 records of "bill-item" model when I tried to save only one?
The adapter used for the models are RESTAdapter and serializer is JSONSerializer.
Ember inspector attachment for reference
Save the billItem first.
After
let bill = this.store.createRecord("bill");
bill.billItems.addObject(this.store.createRecord("bill-item"));
bill contains a billItem with only default attributes, and thus undefined id. When the API response from bill.save() comes back, ember-data accepts the response as the new state of the record it just tried to save, updating everything that is different to the model in store (i.e. your back-end could modify other attributes and they would be updated).
Apparently, your back end created a billItem record, too, upon receiving a bill that includes an embedded billItem without an id. However, since ember-data never explicitly saved this billItem, the embedded billItem is treated as a different record apparently also associated with the bill and thus added to its relation. (I do not have a good intuitive explanation why the association with the old, id-less one is still there - I guess it's because ember-data still treats it as an unsaved billItem record (green in the inspector) and still remembers its (inverse) relation with the original bill.)
Another fix might be not to serialize embedded records but only ids and retrieve the records separately, but if each billItem belongs to exactly one bill this may not be what you want.
I've run into the same problem. Since I didn't have enough time for having considerations about of it I decided to use simple workaround. Just in case of succesful save, you can invoke
foo(){
this.store.peekAll('bill-item')
.filterBy('isNew', true)
.forEach(item => this.store.deleteRecord(item));
}
And then, all records without id should have been removed from the store.
However, I'd gladly hear some explanations of that issue from more experienced ember developers.

Paylike modal amount parameter

I'm currently testing the paylike's web sdk and I can use the sandbox easy. But how can I avoid the user can change the amount on the client side? The amount parameter is required, but how can I ensure about after a success callback about the amount? Can I get it from the server side?
The following code is fine, but I have problem with the amount parameter
<script src="//sdk.paylike.io/3.js"></script>
<script>
var paylike = Paylike('your key');
paylike.popup({
currency: 'DKK',
amount: 1000,
}, function( err, res ){
if (err)
return console.log(err);
console.log(res.transaction.id);
alert('Thank you!');
});
</script>
Two steps are important regarding transactions. The first step is authorization.
Authorization is done with the code you added here, on the frontend. The user can tamper with the amount, but this is merely a reservation and is not taking funds from the payer credit card.
The second step is called capture. You can only capture the funds from the Paylike dashboard, or via your server. When you do that, you generally send the same amount that you initially wanted the user to pay, and if the authorization were less, you would get an error. You can also fetch the transaction to inspect the amount that was authorized if you want to reject an order, for example. You can also send a custom parameter that you might use to validate on the server, similar to a checksum if you want to.
You have a private key, which users are not able to get, so that makes it safe. The 2 step approach is a validation on its own, but as I mentioned, you can also inspect the transaction.
You can check the API docs here: https://github.com/paylike/api-docs, where you will also find links to client-side SDKs.
If you are using PHP, using the PHP library (which I maintain) you can do this to inspect a transaction:
$paylike = new \Paylike\Paylike($private_api_key);
$transactions = $paylike->transactions();
$transaction = $transactions->fetch($transaction_id);
The transaction variable will look like this:
{
"id":"5da8272132aad2256xxxxxxx",
"test":true,
"merchantId":"594d3c455be12d547xxxxxx",
"created":"2019-10-17T08:32:34.362Z",
"amount":35,
"refundedAmount":0,
"capturedAmount":0,
"voidedAmount":0,
"pendingAmount":35,
"disputedAmount":0,
"card":{
"id":"5da82743735e61604xxxxxxx",
"bin":"410000",
"last4":"0000",
"expiry":"2023-11-30T22:59:59.999Z",
"code":{
"present":true
},
"scheme":"visa"
},
"tds":"none",
"currency":"JPY",
"custom":{
"email":"customer#example.com",
"orderId":"Could not be determined at this point",
"products":[
[
{
"ID":"48",
"name":"Hoodie with Pocket",
"quantity":"1"
}
]
],
"customer":{
"name":"John Doe",
"email":"customer#example.com",
"phoneNo":"020 91X XXXX",
"address":"123 Main Street, New York, NY 10030",
"IP":"10.0.2.2"
},
"platform":{
"name":"WordPress",
"version":"5.2.4"
},
"ecommerce":{
"name":"WooCommerce",
"version":"3.7.1"
},
"paylikePluginVersion":"1.7.2"
},
"recurring":false,
"successful":true,
"error":false,
"descriptor":"PHP API WRAPPER TEST",
"trail":[
]
}

Angularfire - Retrieve unique ID of all objects in array

I have two different array in Firebase : The first is "General post" and the second is "The favorite post by user".
When user want put a post in favorite, I copy all data of this unique post in "General post" to "The favorite post by user" with the same ID.
The problem is when the post name is changed, he is changed only in "General post" and stay the same in "The favorite post by user".
So I try to retrieve only post name in "General post" like this :
var postRef = new Firebase("https://myapp.firebaseio.com/posts")
var userFavoriteRef = userRef.child($scope.user_id).child("favorite_posts")
$scope.favoritePosts = $firebaseArray(userFavoriteRef)
var favoritePosts = $firebaseArray(userFavoriteRef)
userFavoriteRef.once("value", function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key()
$scope.key = childSnapshot.key()
postRef.child($scope.key).child("name").once('value', function(snap) {
console.log(snap.val())
$scope.name = snap.val()
})
})
})
But I have "null" in my console log... And it's dont work ...
Maybe my logic is false ...
What do you think ? Pending read you ... Thanks !
Might be better to take a different approach to storing the data. Instead of having two copies of the data, just have one with a unique id. Then on each individual user, you can reference the unique ids of the posts they have favorited. This allows you to be able to update the data only in the one location.
For example, you could use a data structure like:
myFirebase
- users
-user1
-user2
-user3
-favorites
-unique2 (reference to post, not the actual post)
-unique4
- posts
-unique1
-unique2
-unique3
-unique4
So, you just have one copy of the data and then reference it from your user objects to retrieve what you are looking for. And changes to the post are reflected everywhere that references that post.

Best practice creating a key/value map dev/prod node.js

I have a Node.js app, APP-A, that communicates with another C# app, APP-B, using APP-B's API. APP-B has a RESTful API that returns JSON. Other than a few standard fields e.g., name, description, APP-B's keys are defined when the user creates the field in the system. The resulting JSON looks like this:
{
"name": "An example name",
"description": "Description for the example",
"cust_fields": {
"cust_123": "Joe Bloggs",
"cust_124": "Essex"
}
}
I have two instances of APP-B, a dev and prod environment, which are separate installations. As a result, the JSON from the prod environment is as above, and the JSON from the dev environment looks like this:
{
"name": "An example name",
"description": "Description for the example",
"cust_fields": {
"cust_782": "Joe Bloggs",
"cust_793": "Essex"
}
}
This is dealt with in APP-A (the Node.js app) by having a JSON map like this:
{
"name": "name",
"description": "description",
"cust_fields": {
"full_name": "cust_123",
"city": "cust_124"
}
}
Which is loaded like this:
var map;
switch(env) {
case 'dev':
map = require('../env/dev/map.json');
break;
case 'prod':
map = require('../env/prod/map.json');
break;
};
module.exports = {
name: map.name,
description: map.description,
cust_fields: {
full_name: map.cust_fields.full_name,
city: map.cust_fields.city,
}
}
So I am wondering, is there is a better way of dealing with this? I don't see a way around having to create some kind of manual relationship between the key names across prod and dev, as there is no way to find out what field corresponds to what, but it seems like a lot of work.
Thanks for reading.
Update:
I have created a jsFiddle to better illustrate my question: http://jsfiddle.net/7k9k03o6.
If the mapping is unavoidable and everything is done manually right now, the next best progression would be to automate the building of those lookup maps, through some persistent storage, i.e. a database.
The general flow would be:
When APP-B creates a new form, that field information is stored in the database with all the identifying information. You could store production and dev data in the same db (as a flag) but likely they would just be different databases. Structure might be like customerId, formId, fieldName, fieldMapping, fieldValue, isProduction --> 123, 2, 'cust_124', 'city', 'Essex', true
When APP-A needs a field listing, it queries the DB for the relevant field lists."Find mapping customer X for form Y in production" --> WHERE custId = 123 AND formId = 2 AND isProduction = true would yield a list of fields and their mapping values (which you would post process/reduce into the mapping you need).
This automated process will leave less work for you manually. You shouldn't accidentally miss or forget a mapping from the hand generated file.
This will add a tiny bit of work to the server processing, as you'll need the field mapping from the DB every time a request is processed. (You could back off a bit and do one big query each time a customer is loaded, or further back is each time the server starts . . . depends how dynamic these custom fields are). Plus you would have to map DB results into a usable listing for your purposes.
Depending how many customers and custom forms you are monitoring, an automated process for that will save you a lot of time and avoid a lot of mistakes of all things hand generated.

Trying to simplify access to private posts with Express

I'm learning Node.js with MongoDB and Express and it is going quite well.
I have my user registration working fine and every user can create posts.
Now I'm trying something more complicated, I'd like user to create private posts and only user who created it and other allowed users can see the post.
I did something and it seems to work but I think it can be done in some better way.
What I have now to get the post at this address www.mywebsite.com/post-title is this:
Post
.findOne({ permalink: req.params.permalink })
.exec(function(err, post) {
if (!post) {
req.flash('errors', { msg: 'Post not found' });
return res.redirect('/');
} else {
if (post._creator == req.user.id) {
res.render('post/home', {
title: post.name,
post: post
});
} else {
req.flash('errors', { msg: 'You are not allowed to see this post' });
res.redirect('/');
}
}
});
It works fine but if I wish to add few more options to this post and create another link like: www.mywebsite.com/post-title/tags to get that page I have to repeat the whole code posted above...
I wish to find a way to match easily the owner of the post or allowed people and a way to get the post through the permalink without useing fineOne for every get...
Is this possible?
Does it make sense?
Thanks
I might have helped you to "simplify" your question and just explain what you wanted to do. But those who take the time to read all of it would eventually see that you basically want to
" List all posts including private and allowed posts for the current user.. "
Which is basically the simplified version of the question.
So all you basically need are some fields on your "Post" document that allow the access control:
{
"title": "this is the title",
"permalink": "some/sort/of/slug",
"body": "post body here",
"creator": "Bill",
"_private": true,
"_allowed": ["Ted","Fred"]
}
So basically you are not going to care about the "_allowed" list where "private" is false, but you do want to care where this is true. So you want this logic in the query rather than evaluating it per document retrieved:
Post.find(
{
"$or": [
{ "_private": false },
{
"_private": true,
"$or": [
{ "creator": req.user.id },
{ "_allowed": req.user.id }
]
}
}
},
function(err,docs) {
So essentially your logic is based of a nested $or operation which either allows the public posts to display or otherwise where the post is private then only the "creator" $or the "_allowed" users will receive this in any query.
The logic applies to whether you are retrieving a list of posts for paging results or whether recalling an individual post for a single in depth display.

Categories

Resources