1

I'm new to node.js and DialogFlow. I am using DynamoDB to store data and I'm creating skills on Google. I'm trying to write a code to retrieve a specific item on that table.

I've got it working to show all items where ID is equal = 1, but how would I make it so I can just get attribute 'name'?

My idea is a user provides an id then the code will retrieve name where id was 1 and store that as a variable and use agent.add('hello $(name)'); to display it back as speech to the user.

  function readdata(agent){
    let dbread = new aws.DynamoDB.DocumentClient();

    const id = agent.parameters.id;

    let read = function(){
        var parameters = {
            TableName:"Dynamodb",
            Key:{
                "id":id
            }
        };
        dbread.get(parameters, function(err,data){
            if(err){
                console.log("error",JSON.stringify(data,null,2));
            }else{
                console.log("success",JSON.stringify(data,null,2));
            }
        });
      agent.add(`hello ${name}`);
    };
    read();
  }
vllnv
  • 13
  • 3

1 Answers1

0

Once you have the data back from the get() call, the data object will contain an Item attribute. The value of this attribute will be another object that contains the attribute/value pairs for this record, or be empty if the record isn't found.

The debugging you have in place that shows JSON.stringify(data) should show this.

Assuming you knew all the fields were there, you could do something like

const name = data.Item.name;

a more robust way using current JavaScript would be to make sure everything was assigned, otherwise return undefined at any point. So something like this would work

const name = data && data.Item && data.Item.name;

However - you will have a problem doing this with Dialogflow

You don't show which Dialogflow library you're using, but most of them require you to return a Promise to indicate that it needs to wait for asynchronous calls (such as the call to DynamoDB) to complete. You're using get() with a callback function instead of a Promise. So you need to do one of the following:

  1. Wrap the call in a Promise

  2. Since get() returns an AWS.Request you can use the promise() method of this to get a Promise that you can return and which has then portions that generate the response - similar to how you're doing your callbacks now.

Under this scheme, your call might look something like this (untested):

    return dbread.get(parameters).promise()
      .then( data => {
        console.log("success",JSON.stringify(data,null,2));
        const name = data && data.Item && data.Item.name;
        if( name ){
          agent.add( `Hello ${name}` );
        } else {
          agent.add( "I don't know who you are." );
        }
      })
      .catch( err => {
        console.log("error",JSON.stringify(data,null,2));
        agent.add( "There was an error" );
      });
Prisoner
  • 49,922
  • 7
  • 53
  • 105