2
votes

I'm going through a NodeJS tutorial for Google Assistant / Actions on Google https://codelabs.developers.google.com/codelabs/actions-1/#5 and have code that looks like :

app.intent('Location', (conv, {geo-city}) => {
  const luckyNumber = geo-city.length;
  // Respond with the user's lucky number and end the conversation.
  conv.close('Your lucky number is ' + luckyNumber);
});

Neither the linter in Dialogflow nor in my IDE is happy with {geo-city} but I can't find a way around it. I've tried quotes, backticks etc but no joy. I can't change the variable name since it is a Google AI system entity (https://cloud.google.com/dialogflow-enterprise/docs/reference/system-entities).

What is the correct way to handle this please?

2
geo-city is a subtraction outside of a string; this isn't just a lint problem. You can't destructure keys that aren't valid identifier names. Just do e.g. (conv, data) then data["geo-city"].jonrsharpe
Not enoughrelevant for an answer but check the ES6 string interpolation. You could just do : Your lucky number is ${luckyNumber}L. Faros
thanks both. @jonrsharpe do you mean like app.intent('Location', (conv, data) => { const luckyNumber = data["geo-city"].length; . ?Stuart Brown
Yes; you can't access that property via destructuring (or dot notation, for that matter) as it's not a valid identifier, but it is still accessible.jonrsharpe

2 Answers

2
votes

You can change the name in the Dialogflow parameter list. Although it uses a default one based on the entity type, you can change this to whatever you want.

For example, given this training phrase where it picked up on the city name in the training phrase, assigned it the type of @sys.geo-city, and gave it the default name of geo-city

enter image description here

you can click on the parameter name, edit it, and change it to `city.

enter image description here

Your code, then, just uses city as the parameter name.

app.intent('Location', (conv, {city}) => {
  const luckyNumber = city.length;
  // Respond with the user's lucky number and end the conversation.
  conv.close('Your lucky number is ' + luckyNumber);
});

If you really wanted to keep it named "geo-city", you can still just use this as a parameter name. That second parameter to the function is just an object keyed on Dialogflow parameter names, and they're using some JavaScript syntactic sugar to deconstruct it. But you don't have to. You can use code something like

app.intent('Location', (conv, params) => {
  const luckyNumber = params['geo-city'].length;
  // Respond with the user's lucky number and end the conversation.
  conv.close('Your lucky number is ' + luckyNumber);
});
2
votes

This is object destructing syntax. When you do e.g.:

const func = ({ foo }) => console.log('foo is', foo);

...you're telling JavaScript: func is going to take an object as an argument, but I'm only interested in the property of that object named foo, so please put the value of the foo property in a variable named foo and ignore the rest.

However, while geo-city is a valid property name in JavaScript, it's not a valid variable name (otherwise there'd be no way to tell if it's a variable or if you're trying to subtract city from geo). One way to resolve this is to just take the object as an argument instead:

const func = (obj) => console.log('foo is', obj.foo);

...or, applied to your code:

app.intent('Location', (conv, obj) => {
  const luckyNumber = obj['geo-city'].length;
  // ...
});

But destructuring is nice, and we have another way to make it work. When you destructure an object you can supply another name for the variable(s):

const func = ({ foo: valueOfFoo }) => console.log('foo is', valueOfFoo);

This works even with a property like geo-city, but you have to put it in quotes, like this:

app.intent('Location', (conv, {'geo-city': geoCity}) => {
  const luckyNumber = geoCity.length;
  // ...
});