I am new to Javascript and DynamoDB. I am trying to perform getitem using aws-sdk for javascript in nodejs. primary index of Dynamo table Cars is "name" a string.
var AWS = require('aws-sdk');
AWS.config.region='eu-west-1';
var db = new AWS.DynamoDB();
var params = {
TableName : 'Cars',
Key : {
"name" : {
"S" : "Volkswagen Dasher"
},
}
}
db.getItem(params, function(err, data) {
if (err) {
console.log(err); // an error occurred
}
else {
console.log(data); // successful response
}
return next();
});
On running the above .js file I am getting the following error.
ubuntu#ubuntu:~/node$ node getItem.js
{}
/home/ubuntu/node_modules/aws-sdk/lib/request.js:30
throw err;
^ ReferenceError: next is not defined
at Response.<anonymous> (/home/ubuntu/node/getItem.js:21:10)
at Request.<anonymous> (/home/ubuntu/node_modules/aws-sdk/lib/request.js:353:18)
at Request.callListeners (/home/ubuntu/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/home/ubuntu/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/home/ubuntu/node_modules/aws-sdk/lib/request.js:595:14)
at Request.transition (/home/ubuntu/node_modules/aws-sdk/lib/request.js:21:10)
at AcceptorStateMachine.runTo (/home/ubuntu/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /home/ubuntu/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/home/ubuntu/node_modules/aws-sdk/lib/request.js:37:9)
at Request.<anonymous> (/home/ubuntu/node_modules/aws-sdk/lib/request.js:597:12)
Plz help me out. Cheers!
Glad to see you're giving DynamoDB a try! I'm not really sure I understand the context of your code, but if your goal is to make a simple GetItem call, you don't need the 'return next()' statement. Given javascript's event driven nature, these callbacks are asynchronous and don't really "return" anything. Instead, you should inspect the response (data) and perform an action accordingly.
I.E.
dynamoDB.getItem(params, function(err, data) {
if (data) {
doSomethingWithItem(data.Item);
}
});
Also, if you're just starting out I would recommend taking a look at the document-js-sdk which a wrapper on top of the original SDK to allow you to use literals such as "string" instead of {S: "string"}.
Related
I am new to node, and I was working with destructuring. I wanted to get the body property from the response of an weather-api and destructure it. The code is working fine when I am connected with internet but when I disconnect the internet the code crash and throws the error.
Here is the code I have written
```const request = require('request')
const geocode = (address, callback)=>{
const url = "https://api.mapbox.com/geocoding/v5/mapbox.places/" +encodeURIComponent(address)+ ".json?access_token=theKeyHere"
request({url, json: true}, (error, {body})=>{
if(error){
callback('Uh! Oh, Unable to connect with location service', undefined )
} else if (body.features.length ===0 || body.message){
callback(`Uh! Oh, Can't find location. Try another search`, undefined)
} else {
callback(undefined, {
latitude: body.features[0].center[1],
longitude: body.features[0].center[0],
location_Name: body.features[0].place_name
})
}
})
} ```
The error which I am getting
request({url, json: true}, (error, {body={}})=>{
^
TypeError: Cannot read property 'body' of undefined
at Request._callback (F:\nodejs\weatherApp\utils\geocode.js:6:41)
at self.callback (F:\nodejs\weatherApp\node_modules\request\request.js:185:22)
at Request.emit (events.js:315:20)
at Request.onRequestError (F:\nodejs\weatherApp\node_modules\request\request.js:877:8)
at ClientRequest.emit (events.js:315:20)
at TLSSocket.socketErrorListener (_http_client.js:426:9)
at TLSSocket.emit (events.js:315:20)
at emitErrorNT (internal/streams/destroy.js:92:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
The problem is that when there's an error, you're still trying to destructure the data:
request({url, json: true}, (error, {body={}})=>{
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^
But in the error case, the data hasn't arrived, you've gotten undefined instead. You can't destructure undefined or null.
You have two options:
Use a plain parameter, and then destructure once you know you don't have an error:
request({url, json: true}, (error, response)=>{
if (error) {
// ...
return;
}
const {body = {}} = response;
// ...
});
Provide a default for the parameter as a whole, not just body:
request({url, json: true}, (error, {body={}} = {})=>{
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^
// ...
});
That way, if you're passed undefined, you'll destructure {} instead. And since you're already defaulting body if it doesn't exist on the object, that default will kick in.
the issue is, when you're not connected to the internet, or you dont get the expected response structure, the second argument of that function is undefined. so you're essentially trying to do this:
undefined.body which, of course, is wrong
you can do 2 things to fix it:
// - this will guarantee that the second argument will always default to
// an empty object. this way, you will not get an error
(error, { body={} } = {}) => {
or
(error, response) => {
let body = {};
if (response) body = response.body || {};
}
I have an API running in AWS Lambda written on Node.JS (6.10.3), using the npm package mysql (2.13.0). This is deployed and managed using Serverless.
I am Inserting a single row into a table on a MariaDB RDS instance using the following code:
var mysql = require('mysql');
var connection = mysql.createConnection({
"host": process.env.CONFIG_HOST,
"user": process.env.CONFIG_WRITE_USER,
"password": process.env.CONFIG_WRITE_PW,
"database": process.env.CONFIG_DB,
"connectionLimit": 1
});
module.exports.post = (event, context, callback) => {
var body = JSON.parse(event.body);
var params = event.someParameter;
var sql = getSql(body.name);
console.log(sql);
connection.query(sql, onQueryComplete(params, callback));
}
const onQueryComplete = function(params, callback) {
return function(error, result) {
if (error) {
console.log(error);
callback(null, 'some error response');
}
// do something else...
}
}
function getSql(name) {
return `
INSERT INTO lds_config.test_table
(
name,
name_hash
)
VALUES
(
'${name}',
MD5('${name}')
);`;
}
If I check the table, I can see that the insert has completed successfully and the new row has been added, however error is being set - meaning something has gone wrong somewhere (possibly after the insert).
The error returned by mysql (in console.log) is:
{
Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'HANDLER RESOLVED _____');
// Timeout clearing if needed
' at line 2
at Query.Sequence._packetToError (...\node_modules\mysql\lib\protocol\sequences\Sequence.js:52:14)
at Query.ErrorPacket <<stack trace continues>>)
code: 'ER_PARSE_ERROR',
errno: 1064,
sqlState: '42000',
index: 0
}
This is followed by a second error, stating that callback is not a function:
Debug: internal, implementation, error
TypeError: Uncaught error: callback is not a function
Similar code is working elsewhere in the API for selects. Thanks!
Further notes:
The table is:
CREATE TABLE lds_config.test_table(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(500), name_hash CHAR(32));
The result from console.log(sql); is:
INSERT INTO lds_config.test_table
(
name,
name_hash
)
VALUES
(
'test01',
MD5('test01')
);
Which works when I run it directly in mysql workbench.
Include the query also since the first error is regarding MySQL syntax. About callback is not a function it is not passed as a parameter in below code as far as I see.
const onQueryComplete = function(params) {
return function(error, result, callback) {
if (error) {
console.log(error);
callback(null, 'some error response');
}
// do something else...
}
}
Above is the corrected one.
I am trying to execute the following nodejs/mongoDB code:
var tickers = [];
MongoClient.connect(mongoUrl, function(err, db) {
assert.equal(null, err);
console.log("Connected correctly to server."); //ok
var cursor = db.collection('STI').find();
cursor.each(function(err, doc){
assert.equal(err, null);
console.log(doc.symbol); //executes fine
tickers.push(doc.symbol);
})
});
console.log(tickers);
The symbols are logging out fine to the console but after that the code throws an error 'TypeError: Cannot read property 'symbol' of null'.
The code seems to forget the doc.symbol by the time it gets to executing the 'tickers.push' part. How do I fix this?
Update:
I tried shifting the console.log(tickers) into the cursor.each callback and it prints out the array which each iteration, so the symbol pushing is happening. however i still get the same error
Update: full error message
/Users/kevin/Projects/yahooscrape/node_modules/mongodb/lib/utils.js:98
process.nextTick(function() { throw err; });
^
TypeError: Cannot read property 'symbol' of null
at /Users/kevin/Projects/yahooscrape/index.js:21:19
at handleCallback (/Users/kevin/Projects/yahooscrape/node_modules/mongodb/lib/utils.js:96:12)
at /Users/kevin/Projects/yahooscrape/node_modules/mongodb/lib/cursor.js:736:16
at handleCallback (/Users/kevin/Projects/yahooscrape/node_modules/mongodb/lib/utils.js:96:12)
at /Users/kevin/Projects/yahooscrape/node_modules/mongodb/lib/cursor.js:670:5
at handleCallback (/Users/kevin/Projects/yahooscrape/node_modules/mongodb-core/lib/cursor.js:154:5)
at setCursorDeadAndNotified (/Users/kevin/Projects/yahooscrape/node_modules/mongodb-core/lib/cursor.js:463:3)
at nextFunction (/Users/kevin/Projects/yahooscrape/node_modules/mongodb-core/lib/cursor.js:644:7)
at Cursor.next [as _next] (/Users/kevin/Projects/yahooscrape/node_modules/mongodb-core/lib/cursor.js:685:3)
at nextObject (/Users/kevin/Projects/yahooscrape/node_modules/mongodb/lib/cursor.js:655:8)
Use cursor.forEach() instead of cursor.each(). Cursor.forEach() is an officially implemented mongodb method that does not throw the errors shown in the question.
I am trying to perform HTTP.get on a set of URLs asynchronously using futures.
Meteor version: 0.8.3
Platform: Windows server 2012
The code is somewhat like this:
var futures = _.map(test, function(url) {
var future = new Future();
var onComplete = future.resolver();
try{
// Make async http call
var httpGet = HTTP.get(url,{followRedirects: true},function(error, result) {
if(error)
{
apiLogger.error("%s is error",error);
onComplete(error, null);
}
else
{
if(result!=null){
//operations done here
onComplete(error, JSON.stringify(object1));
}
else {
apiLogger.error('%s - User encountered an error. URL not parsed: %s',user,url);
onComplete(error, null);
}
}
});
}
catch(e)
{
apiLogger.error('%s - URsarsed: %s - %s',user,url,result.statusCode);
onComplete(error, null);
}
return future;
});
The issue I am facing is improper error handling.
I am getting the following error on some URLs:
I20140904-17:57:38.609(-4)? Exception while invoking method 'parallelAsyncJob' E
rror: failed [404] <html><head><title>Apache Tomcat/7.0.12 - Error report</title
><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color
:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;ba
ckground-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;
color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,A
rial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial
,sans-serif;color:white;background-colo...
I20140904-17:57:38.617(-4)? at packages/underscore/underscore.js:255
I20140904-17:57:38.619(-4)? at Array.map (native)
I20140904-17:57:38.621(-4)? at Function._.map._.collect (packages/underscore
/underscore.js:123)
I20140904-17:57:38.623(-4)? at Function._.invoke (packages/underscore/unders
core.js:254)
I20140904-17:57:38.626(-4)? at Meteor.methods.parallelAsyncJob (app/server/m
ethods.js:1:9355)
I20140904-17:57:38.628(-4)? at maybeAuditArgumentChecks (packages/livedata/l
ivedata_server.js:1488)
I20140904-17:57:38.631(-4)? at packages/livedata/livedata_server.js:650
I20140904-17:57:38.632(-4)? at _.extend.withValue (packages/meteor/dynamics_
nodejs.js:37)
I20140904-17:57:38.635(-4)? at packages/livedata/livedata_server.js:649
I20140904-17:57:38.644(-4)? at _.extend.withValue (packages/meteor/dynamics_
nodejs.js:37)
I20140904-17:57:38.646(-4)? - - - - -
I20140904-17:57:38.648(-4)? at makeErrorByStatus (packages/http/httpcall_com
mon.js:12)
I20140904-17:57:38.650(-4)? at Request._callback (packages/http/httpcall_ser
ver.js:99)
I20140904-17:57:38.652(-4)? at Request.self.callback (C:\Users\Administrator
\AppData\Local\.meteor\tools\edf8981bb6\lib\node_modules\request\request.js:122:
22)
I20140904-17:57:38.655(-4)? at Request.EventEmitter.emit (events.js:98:17)
I20140904-17:57:38.657(-4)? at Request.<anonymous> (C:\Users\Administrator\A
ppData\Local\.meteor\tools\edf8981bb6\lib\node_modules\request\request.js:888:14
)
I20140904-17:57:38.660(-4)? at Request.EventEmitter.emit (events.js:117:20)
I20140904-17:57:38.662(-4)? at IncomingMessage.<anonymous> (C:\Users\Adminis
trator\AppData\Local\.meteor\tools\edf8981bb6\lib\node_modules\request\request.j
s:839:12)
I20140904-17:57:38.665(-4)? at IncomingMessage.EventEmitter.emit (events.js:
117:20)
I20140904-17:57:38.668(-4)? at _stream_readable.js:920:16
I20140904-17:57:38.669(-4)? at process._tickCallback (node.js:415:13)
Am I doing something wrong? Or is it some GET issue?
Update:
I am using futures because the final operation can only be performed after getting all the URLs.
Interesting thing, I am able to open the URL via browser, and even POSTMAN and getting 200 status. But meteor get is receiving 404.
Per your error message, you’re getting a 404 error code; some of your URLs are invalid. And you say yourself that it only happens on certain URLs.
Why is your code so complicated, with all these futures? HTTP.get() itself offers an asyncCallback, and you’re already using inline callbacks in your code, so why not just strip out all the futures stuff?
_.map(test, function(url) {
try {
// Make async http call
HTTP.get(url, {followRedirects: true}, function(error, result) {
if (error) {
if (result.statusCode == 404)
apiLogger.error('Error 404, URL not found: %s', url);
else
apiLogger.error('Error %s from %s for user %s',
result.statusCode, url, user);
return false;
} else {
if (result != null) {
// operations done here
} else {
apiLogger.error('Empty or invalid result returned from %s for user %s',
url, user);
}
return false;
}
});
} catch (error) {
return false;
}
});
I need to wait for few async calls to complete before resuming execution. I tried the following code using async.
asana.getUsers(null, function(error, resp){
async.each(resp.data, function(user, cb) {
console.log("Get info for user : ", user.id);
asana.getUser(user.id, null, function(error, userResp){
console.log("user response: ", userResp.data.id);
userEmailList.push({
id : userResp.data.id,
name: userResp.data.name,
email : userResp.data.email
});
cb(null);
});
//cb(null); Should the call be here??
}, function(err){
console.log("getUsers is done now");
});
});
The log that i get is:
Get info for user : xxxxxxxxxxxx
Get info for user : yyyyyyyyyyyy
Get info for user : zzzzzzzzzzzz
Get info for user : aaaaaaaaaaaa
user response: yyyyyyyyyyyy
/Code/javaScript/NodeWorkspace/asana-api/mail.js:23
console.log("user response: ", userResp.data.id);
^
TypeError: Cannot read property 'data' of null
at /Code/javaScript/NodeWorkspace/asana-api/mail.js:23:43
at Request._callback (/Code/javaScript/NodeWorkspace/asana-api/lib/asana.js:77:13)
at Request.self.callback (/Code/javaScript/NodeWorkspace/asana-api/node_modules/request/main.js:119:22)
at Request. (/Code/javaScript/NodeWorkspace/asana-api/node_modules/request/main.js:525:16)
at Request.EventEmitter.emit (events.js:95:17)
at IncomingMessage. (/Code/javaScript/NodeWorkspace/asana-api/node_modules/request/main.js:484:14)
at IncomingMessage.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:883:14
at process._tickCallback (node.js:415:13)
I understand the first logs, but why is the console.log("user response: ", userResp.data.id); line getting called with userResp as null.
I hope its not some silly mistake. Thanks in advance.
P.S: Basically i need to get Asana users and then get info of each user and store in a var userEmailList.
The issue was that userEmailList was undefined.