TypeError:无法读取未定义

时间:2018-03-15 08:21:58

标签: node.js amazon-web-services amazon-dynamodb es6-promise alexa

我正在开发一个Alexa技能,引用自:Alexa NodeJS Dynamodb skill,在获取这些问题的所有插槽值后,向用户询问他们想要添加的配方以及一些有关它的更多信息,它首先检查(在DynamoDB上执行get操作)是否项已存在,否则添加该项。

以下是仅一个Intent的代码段:

const alexaSDK = require('alexa-sdk');
const awsSDK = require('aws-sdk');
const {promisify} = require('es6-promisify');
const recipesTable = 'Recipes';
const docClient = new awsSDK.DynamoDB.DocumentClient();

// convert callback style functions to promises
const dbScan = promisify(docClient.scan, docClient);
const dbGet = promisify(docClient.get, docClient);
const dbPut = promisify(docClient.put, docClient);
const dbDelete = promisify(docClient.delete, docClient);
const instructions = `Welcome to Recipe Organizer<break strength="medium" />
                  The following commands are available: add recipe, get 
recipe,get all recipes, get a random recipe, and delete recipe. What would 
you like to do?`;

const handlers = {

/**
 * Triggered when the user says "Alexa, open Recipe Organizer.
 */
'LaunchRequest'() {
this.emit(':ask', instructions);
},

/**
* Adds a recipe to the current user's saved recipes.
* Slots: RecipeName, RecipeLocation, LongOrQuick
*/
'AddRecipeIntent'() {
const { userId } = this.event.session.user;
const { slots } = this.event.request.intent;

// prompt for slot values and request a confirmation for each

// RecipeName
if (!slots.RecipeName.value) {
  const slotToElicit = 'RecipeName';
  const speechOutput = 'What is the name of the recipe?';
  const repromptSpeech = 'Please tell me the name of the recipe';
  return this.emit(':elicitSlot', slotToElicit, speechOutput, repromptSpeech);
}
else if (slots.RecipeName.confirmationStatus !== 'CONFIRMED') {

  if (slots.RecipeName.confirmationStatus !== 'DENIED') {
    // slot status: unconfirmed
    const slotToConfirm = 'RecipeName';
    const speechOutput = `The name of the recipe is ${slots.RecipeName.value}, correct?`;
    const repromptSpeech = speechOutput;
    return this.emit(':confirmSlot', slotToConfirm, speechOutput, repromptSpeech);
  }

  // slot status: denied -> reprompt for slot data
  const slotToElicit = 'RecipeName';
  const speechOutput = 'What is the name of the recipe you would like to add?';
  const repromptSpeech = 'Please tell me the name of the recipe';
  return this.emit(':elicitSlot', slotToElicit, speechOutput, repromptSpeech);
}

// RecipeLocation
if (!slots.RecipeLocation.value) {
  const slotToElicit = 'RecipeLocation';
  const speechOutput = 'Where can the recipe be found?';
  const repromptSpeech = 'Please give me a location where the recipe can be found.';
  return this.emit(':elicitSlot', slotToElicit, speechOutput, repromptSpeech);
}
else if (slots.RecipeLocation.confirmationStatus !== 'CONFIRMED') {

  if (slots.RecipeLocation.confirmationStatus !== 'DENIED') {
    // slot status: unconfirmed
    const slotToConfirm = 'RecipeLocation';
    const speechOutput = `The recipe location is ${slots.RecipeLocation.value}, correct?`;
    const repromptSpeech = speechOutput;
    return this.emit(':confirmSlot', slotToConfirm, speechOutput, repromptSpeech);
  }

  // slot status: denied -> reprompt for slot data
  const slotToElicit = 'RecipeLocation';
  const speechOutput = 'Where can the recipe be found?';
  const repromptSpeech = 'Please give me a location where the recipe can be found.';
  return this.emit(':elicitSlot', slotToElicit, speechOutput, repromptSpeech);
}

// LongOrQuick
if (!slots.LongOrQuick.value) {
  const slotToElicit = 'LongOrQuick';
  const speechOutput = 'Is this a quick or long recipe to make?';
  const repromptSpeech = 'Is this a quick or long recipe to make?';
  return this.emit(':elicitSlot', slotToElicit, speechOutput, repromptSpeech);
}
else if (slots.LongOrQuick.confirmationStatus !== 'CONFIRMED') {

  if (slots.LongOrQuick.confirmationStatus !== 'DENIED') {
    // slot status: unconfirmed
    const slotToConfirm = 'LongOrQuick';
    const speechOutput = `This is a ${slots.LongOrQuick.value} recipe, correct?`;
    const repromptSpeech = speechOutput;
    return this.emit(':confirmSlot', slotToConfirm, speechOutput, repromptSpeech);
  }

  // slot status: denied -> reprompt for slot data
  const slotToElicit = 'LongOrQuick';
  const speechOutput = 'Is this a quick or long recipe to make?';
  const repromptSpeech = 'Is this a quick or long recipe to make?';
  return this.emit(':elicitSlot', slotToElicit, speechOutput, repromptSpeech);
}

// all slot values received and confirmed, now add the record to DynamoDB

const name = slots.RecipeName.value;
const location = slots.RecipeLocation.value;
const isQuick = slots.LongOrQuick.value.toLowerCase() === 'quick';
const dynamoParams = {
  TableName: recipesTable,
  Item: {
    Name: name,
    UserId: userId,
    Location: location,
    IsQuick: isQuick
  }
};

const checkIfRecipeExistsParams = {
  TableName: recipesTable,
  Key: {
    Name: name,
    UserId: userId
  }
};

console.log('Attempting to add recipe', dynamoParams);

// query DynamoDB to see if the item exists first
dbGet(checkIfRecipeExistsParams)
  .then(data => {
    console.log('Get item succeeded', data);

    const recipe = data.Item;

    if (recipe) {
      const errorMsg = `Recipe ${name} already exists!`;
      this.emit(':tell', errorMsg);
      throw new Error(errorMsg);
    }
    else {
      // no match, add the recipe
      return dbPut(dynamoParams);
    }
  })
  .then(data => {
    console.log('Add item succeeded', data);

    this.emit(':tell', `Recipe ${name} added!`);
  })
  .catch(err => {
    console.error(err);
  });
},

但是我得到 TypeError:无法读取未定义的属性'getItem'

以下是执行堆栈的完整日志: AWS Console Log

PS:我正在使用Apex将我的代码部署到AWS Lambda,并且我已经为IAM角色提供了DYNAMODBFULLACCESS。

0 个答案:

没有答案
相关问题