Value of map from DynamoDB is undefined in Node.js - javascript

I have a Lambda function which runs in Node.js 4.3. The input parameter of the function is a String, which is being sent from an AWS Lex bot.
I want to get an item from a DynamoDB table. In this item I have a Map-type attribute, which contains a String key and String value. I want to get a value from that map using the key String I got as a parameter at the start of the function.
The problem is that when I log the map to the console, all I see there is {}.
This is my code:
var AWS = require('aws-sdk');
AWS.config.region = 'us-east-1';
var dynamodb = new AWS.DynamoDB();
const sessionAttributes = intentRequest.sessionAttributes;
const slots = intentRequest.currentIntent.slots;
const name = slots.names;
var id = null;
if (name == "a") {
id = "00";
} else if (name == "b") {
id = "01";
}
var params = {
TableName: 'names',
Key: {
'id' : {S: 'test-id'}
}
};
var names = {};
dynamodb.getItem(params, function(err, data) {
if (err) {
console.log(err); // an error occurred
} else {
names = data.Item.names.M;
}
});
console.log(names);
var content = names[id];
callback(close(sessionAttributes, 'Fulfilled',
{'contentType': 'PlainText', 'content': content}));
As you can see, there is a console.log line at the end of the code. This line logs just {}. The final message's content is undefined.
What can I do to fix this?

dynamodb.getItem() is executing asynchronously, it has a callback function for this very reason.
console.log(names) is executing before any value is returned in the call to dynamodb.
Add a console.log() inside the getItem function and you will see that this is true.
Google "asynchronous javascript" and you'll find some good pointers.

Related

How to query parameters correctly in JS?

I'm trying to query parameters localhost:8888?title=associate&name=John and I have written the code below, but editor shows errors in if-else statement. Is the whole concept incorrect? The idea is that if there's no parameters, it would use the default values "who" and "department".
const handleRequest = (request) => {
const url = new URL(request.url);
const params = url.searchParams;
let who = "employee";
let department = "admin";
if (params.has("title") || params.has("name")) {
return new Response(`Please address your request to ${params.get("title")} called ${params.get("name")}.`);
} else {
return new Response(`Please address your request to ${who} in the ${department}.`);
}
};
URLSearchParams object provides lots of methods (like get(param), has(param)) to access the query string parameters.
const url = new URL(
'http://example.com/path/index.html?message=hello&who=world'
);
url.searchParams.get('message'); // => 'hello'
url.searchParams.get('missing'); // => null
//So you can simply use
let messageParam = url.searchParams.get("message") || "default value";
You can read more about it here
https://dmitripavlutin.com/parse-url-javascript/#31-parsing-query-string

Google spreadsheet error TypeError: Cannot read property 'filter' of undefined

I am taking data from a sheet and then converting it to json, so far all good. But when I am trying to take out specific data from arrays but it is making undefined if I get data from array, but when I use raw json data everything works fine
function doGet(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Users');
var userData = getUser(ss);
var array = userData.user.filter(function b(e) { return e.id == 11281 });
console.log(array)
}
function getUser(ss){
var usr = {};
var usrArray = [];
var data = ss.getRange(2,1,ss.getLastRow(), ss.getLastColumn()).getValues();
for (var i=0, l=data.length; i<l; i++){
var dataRow = data[i];
var record = {};
record['id'] = dataRow[1];
record['name'] = dataRow[0];
record['profession'] = dataRow[2];
usrArray.push(record);
}
usr.user = usrArray;
var result = JSON.stringify(usr);
return result;
}
ERROR: TypeError: Cannot read property 'filter' of undefined
Error picture
Sheet data picture
If I console log the result directly the it is working fine like this: Output
JSON.stringify returns a string — the getUser function returns a string. And you're trying to read the user property from it which returns undefined.
You could do a JSON.parse in doGet but it's simpler to just return the usr object from getUser.
function getUser(ss) {
const usr = {}
const usrArray = []
// populate usrArray
usr.user = usrArray
return usr
}
And there's another issue. You're setting record['id'] to dataRow[1] but it should be dataRow[0] since id is the first column (This is why the shared screenshot has the name in the id property). You could also refactor the code.
function getUser(ss) {
const data = ss
.getRange(2, 1, ss.getLastRow(), ss.getLastColumn())
.getValues()
const users = data.map((row) => ({
id: row[0],
name: row[1],
profession: row[2],
}))
return {
user: users,
}
}
I would also recommend renaming the user property to users for clarity.

Why do i receive an error message in the console that getStoredQuests.push is not a function at Object.addQuestionOnLocalStorage

Why do I receive an error message in the console that getStoredQuests.push is not a function at Object.addQuestionOnLocalStorage
class Question{
constructor(id, questionText, options, correctAnswer) {
this.id = id;
this.questionText = questionText;
this.options = options;
this.correctAnswer = correctAnswer;
}
}
let questionLocalStorage = {
setQuestionCollection: (newQuestion) => {
localStorage.setItem('questionCollection', JSON.stringify(newQuestion));
},
getQuestionCollection: () => {
return JSON.parse(localStorage.getItem('questionCollection'));
},
removeQuestionCollection: () => {
localStorage.removeItem('questionCollection');
}
}
newQuestion = new Question(questionId, newQuestText.value, optionsArr, corrAnswer);
getStoredQuests = questionLocalStorage.getQuestionCollection();
getStoredQuests.push(newQuestion);
questionLocalStorage.setQuestionCollection(getStoredQuests);
The error is because getStoredQuests is not an array. You have probably not considered if there is no question in local storage initially, then localStorage.getItem('questionCollection') will return empty string or it might be case that you have some value with key questionCollection in local storage but is not in proper format to to be parsed as JSON array object.
For the first case solution is to check if localStorage.getItem('questionCollection') is empty then return empty array from getQuestionCollection and for the second case you to need to properly format the array '(serialize the array to be stored with JSON.stringify)'.
To let your problem understand properly, open up console see if there are red lines

How does one parent a channel to a category with a discord bot?

Basically there is no errors in the output but at the same time it's not doing what I'm trying to achieve.
Ive been tinkering with the script for 5 hours straight mixing up line positioning and now I got it to where it gives me the promise (my initial issue) but I cant parent the channel.
I've tried discord.js server and site, youtube, 2 other sites i forgot the name of but i cant crack it.
function setup(arguments, message){
var server = message.guild;
var name = message.author.username;
let searchquery = arguments.join("")
let cat = server.createChannel("Important", "category");
async function Channelmaker(Sent, obj){
try {
let chan = await server.createChannel(Sent, "Text");
//console.log(obj);
return chan
} catch(prom){
var chan2 = await server.createChannel(Sent, "Text");
return new Promise(resolve => {
var chan2 = server.createChannel(Sent, "Text", parent = obj);
resolve(chan2)
});
}
}
var holding
var chan = Channelmaker("⚖️ rules ⚖️", cat).then(value => {
console.log(value)
holding = value
value.parentID = cat
chan.setParent(cat.Id)
}).catch(error => {
// s
});
console.log("holding")
console.log(holding)
}
The category is not the parent of the "⚖️ rules ⚖️" channel that is created which is the opposite of what I'm trying to achieve
In Guild.createChannel(), use the options parameter including ChannelData, like so:
await server.createChannel(Sent, {
// You can omit the 'type' property; it's 'text' by default.
parent: obj
});

How to store list of objects for each user in firebase

I'm trying to write an application using firebase. I want to store JSON search objects in searches/ and a reference to each one of them in a table belonging to the user that made the search. Here's my attempt:
var firebase = require("firebase");
firebase.initializeApp(firebaseConfig);
var database = firebase.database();
/*
* Inserts a search into the database
*/
this.addSearchToDB = function(positive, negative, neutral){
let today = new Date();
let dateCreated = today.getFullYear()+"-"+(today.getMonth()+1)+"-"+today.getDate();
var search = {
"query": searchInput,
"location": location,
"until": date,
"dateCreated": dateCreated,
"amount": tweetAmount,
"positive": positive,
"negative": negative,
"neutral": neutral
};
//setup of path to reference the data
var searchesRef = database.ref("searches");
var newSearchKey = searchesRef.push(search).key;
console.log("newSearchRef key:");
console.log(newSearchKey);
let user = firebase.auth().currentUser;
let uid = user.uid;
console.log("Curr user id: "+uid);
let userRef = database.ref("users/"+uid);
let currUserSearches;
userRef.once("value").then( (value) => {
currUserSearches = value;
});
console.log("Current user searches");
console.log(currUserSearches);
if (currUserSearches === undefined)
currUserSearches = [];
currUserSearches.push(newSearchKey);
userRef.set(currUserSearches).then( () => {
database.ref("users/"+uid).once("value").then((value)=>{
console.log(value.val());
});
});
}
On the first insert, this happens:
I get a newSearchKey (logs successfully to console)
I get the user id of the currentUser (logs successfully to console)
currUserSearches is undefined. (logs undefined to console)
In the userRef.set() callback, a list containing newSearchKey is found and printed to the console.
This is all good. It is what I would expect of the first insert. BUT, when I insert again, the exact same procedure repeats itself, meaning that currUserSearches is once again undefined. This is of course wrong. currUserSearches should contain that key that I just inserted. But it seems like it's forgotten what I inserted.
What is going on here, and how can I achieve the behaviour I want?
This is because all queries (read and write) to the Firebase database are asynchronous. The console.log #3 is executed before the userRef.once("value") returns a result.
You should chain the promises, as follow:
let userRef = database.ref("users/"+uid);
let currUserSearches;
userRef.once("value")
.then( (value) => {
currUserSearches = value;
if (currUserSearches === undefined)
currUserSearches = [];
currUserSearches.push(newSearchKey);
return userRef.set(currUserSearches);
})
.then( () => {
return database.ref("users/"+uid).once("value"); // <- Actually could be userRef.once("value")
})
.then((value)=>{
console.log(value.val());
});

Categories

Resources