Query with 3 parameters to dynamodb with dynamoose - node.js

I am trying to consult a DynamoDB table with 3 parameters, but it does not work. However, with 1 parameter it works perfectly.
I'm work with NodeJs, DynamoDB, Dynamoose... and here is my code:
var params = {
TableName: "DifferentTermsPages",
KeyConditionExpression:"#providerName = :providerName and #productType = :productType and #language = :language",
ExpressionAttributeNames: {
"#providerName":"providerName",
"#productType":"productType",
"#language":"language"
},
ExpressionAttributeValues: {
":providerName":providerName,
":productType":productType,
":language":language
}
};
OcrController.getDifferencesFromDB(params)
.then(function(dataDB) {
console.log("DATA = ", dataDB);
}).catch(function(err) {
console.error(err);
});
Call to another function with a promise:
getDifferencesFromDB(params) {
return new Promise(function(resolve, reject) {
DifferentTermsPagesModel.scan(params).exec().then(function (err, data) {
if(err) {
reject(err);
}
else {
console.log("OK!!");
resolve(data);
}
});
});
}
The error that shows me...
TypeError: Cannot read property 'toDynamo' of undefined
at Scan.exec (/API/src/node_modules/dynamoose/lib/Scan.js:57:23)
at ...
Where is my error?? How can I resolve it? Or another form to make this...

As you are using the scan api, please use FilterExpression rather than KeyConditionExpression.
FilterExpression:"#providerName = :providerName AND #productType = :productType AND #language = :language",

Related

Odoo external api user check in database using Nodejs and xmlrpc

so i wrote this function to check weather the login given exists already in the odoo database, but it always returns undefined, my guess is that it returns undefined because the return line is inside the calling method,
i tried to use it as an async function but it didn't work either, i need to know how can i make the return line refrences to the global function scope and not just the calling method.(i need the calling method to get the full list of users from the odoo database). Any suggestions ??
`
function user_exist(email){
odoo.connect(function (err) {
if (err) { return console.log(err); }
console.log('Connected to Odoo server.');
var inParams = [];
inParams.push([['active', '=', true]]);
var params = [];
params.push(inParams);
// 4- Read
odoo.execute_kw('res.users', 'search', params, function (err, value) {
if (err) { return console.log(err); }
var inParams = [];
inParams.push(value); //ids
inParams.push(['login']);
var params = [];
params.push(inParams);
odoo.execute_kw('res.users', 'read', params, function (err2, value) {
if (err2) { return console.log(err2); }
for (let i = 0; i < value.length; i++) {
if (email == value[i].login){
return "User exist"
}
}
return "user doesn't exist"
});
});
});
}
`
if you are making your api you need to learn how to use postman, and in this solution we are using axios:
var axios = require('axios');
let data = JSON.stringify({
"jsonrpc": "2.0",
"method":"call",
"params": {
"service":"object",
"method":"execute",
//arg1 : your database name must be "string"
//arg2 : id of the user admin must be "int" ex:1 or 3 or 66
//arg3 : password of the user admin must be "string"
// admin:admin do like this 2:"admin"
//arg4 : object or model name ex:"res.users"
//arg5 : orm methods ex:"search,search_read..."
//"args":["arg1",'arg2',"arg3","arg4","arg5"]}
"args":["app",2,"admin","res.users","search_read",[],[]]
}
});
let config = {
method: 'get',
url: 'http://localhost:8069/jsonrpc',
headers: {'Content-Type': 'application/json'},
data : data
};
axios(config).then(response => {handleResult(response)})
function handleResult(data) {
// if you want you can remove result
console.log(JSON.stringify(data.data.result));
}
i hope this will be help you

DynamoDB returns undefined but does log data in console.log(), async issue?

I have a function that gets some data from DynamoDB using docClient.query(). I'm able to retrieve data and print it on console e.g., console.log(data)), but if I try to return data I always get undefined.
I thought that function (err,data){ ... } was a callback of the query() function and was hoping it would wait for the value to be available to before returning.
Clearly I'm new with AWS SDK and async functions, couldn't find documentation that used return in the way I needed.
I just need the aliasHasRole to return the isAuthorized JSON so I can use it elsewhere outside the function.
function aliasHasRole(an_alias, a_role) {
const params = {
TableName: 'xxxxxxx',
KeyConditionExpression: '#alias= :alias AND #Role= :Role',
ExpressionAttributeNames: {
'#alias': 'alias',
'#Role': 'Role'
},
ExpressionAttributeValues: {
':alias': an_alias,
':Role': a_role,
},
};
docClient.query(params, function (err, data) {
if (err) {
console.log("Error when attempting table query, see below:\n\n" +
JSON.stringify(err, null, 2));
return err;
} else {
var isAuthorized = data.Count === 1 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false;
console.log(1,'Access', isAuthorized ? 'Granted' : 'Denied', 'for alias "' + an_alias + '".\n');
return isAuthorized; //always returns undefined
}
})
}
console.log(aliasHasRole("fooAlias","barRole")) // returns undefined.
Surely that's the issue related to asynchronous code. If you are able to use docClient.query with async/await syntax, then you can wait for its execution and return value according to its result. You can also use Promise syntax if it's necessary to know the err value (if exists). Then you can also use resolve/reject in your function.
Solution with async/await syntax:
async function aliasHasRole(an_alias, a_role) {
const params = {
TableName: 'xxxxxxx',
KeyConditionExpression: '#alias= :alias AND #Role= :Role',
ExpressionAttributeNames: {
'#alias': 'alias',
'#Role': 'Role'
},
ExpressionAttributeValues: {
':alias': an_alias,
':Role': a_role,
}
};
const data = await docClient.query(params);
if (!data) return false;
const isAuthorized = data.Count === 1 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false;
return isAuthorized;
};
aliasHasRole("fooAlias", "barRole").then(console.log).catch(console.log);
UPDATE
What really helps is making your query a promise with .promise() . Then it can be easily executed and handled with then/catch syntax.

Getting Error Like RequestsLimitError: You just made too many request to instagram API in node js?

I am work with isntagram api in node js. i have one array and in the array store above 20k up instagram id. and then i am do foreach on that array and one by one take instagram id and go for the take bio but that time i am getting error like this RequestsLimitError: You just made too many request to instagram API. i am try every 5 call after set time out also but still i am getting same error so how can resolved this error any one know how can fix it then please let me know.
Here this is my code =>
var InstaId = ["12345687",20k more id store here in the array]
var changesessionFlage = 0;
async.each(InstaId, function (id, callback) {
async.parallel([
function (cb) {
if (id) {
setTimeout(function () {
Client.Account.getById(sess, id).then(function (bio) {
console.log("changesessionFlage" + changesessionFlage);
changesessionFlage++
//console.log("bio : ", bio._params); // here i am getting bio one by one user
if (changesessionFlage == 6) {
changesessionFlage = 0;
}
cb(null, bio._params);
})
.catch(function (err) {
console.log("get boi: ", err)
cb(null, bio._params);
})
}, (changesessionFlage == 5) ? 10000 : 0)
}
}
], function (err, results) {
if (err) {
console.log(err);
return;
}
Result = results
callback();
});
}, function (err) {
if (err) {
console.log(err);
return;
}
else {
console.log("Result=>", Result)
if (Result) {
console.log("Result[0]=>", Result[0])
var ws = XLSX.utils.json_to_sheet(Result[0]);
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "People");
var wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
res.end(wbout, 'binary');
}
}
});
any one know how can fix this issue then please help me.
Your setTimeout is use incorrectly, all API calls are made at once after 10000 delay.
Since this is a one time job, just split the 20K usernames to 4K batches and execute them every hour. This way you will be under the 5k/hr API limit

Nodejs crashes when database connection fails

While my database server is not available and any function of my node-express rest service like hiExpress is called, Nodejs crashes the node server and console of node reports
sql server connection closed
I do not want this to happen because either it should go to err function or at least it must be cautht by catch block. What could i do to avoid the crash of nodejs when database server is not available I am using following code which is absolutely fine as long as database server is available.
var sqlServer = require('seriate');
app.get('/hiExpress',function(req, res)
{
var sr = {error:'',message:''};
var sql= 'select * from table1 where id=? and name=?';
var params = {id: 5, name:'sami'};
exeDB(res,sr,sql, params);//sent only 4 parameters (not 6)
});
function exeDB(res, sr, sql, params, callback, multiple) {
try {
var obj = {};
for (p in params) {
if (params.hasOwnProperty(p)) {
obj[p] = {
type: sqlServer.VARCHAR,
val: params[p]
};
}
};
var exeOptions = {
query: sql,
params: obj
};
if (multiple) {
exeOptions.multiple = true;
}
sqlServer.execute(sqlServerConfigObject, exeOptions).then(function (results) {
sr.data = results;
if (callback)
callback(sr);
else
res.json(sr); //produces result when success
}, function (err) {
//sr.message = sql;
console.log(11);
sr.error = err.message;
res.json(sr);
});
}
catch (ex) {
console.log(21);
sr.error = ex.message;
res.json(sr);
}
}
Why I preferred to use seriate
I had not been much comfortable with node-SQL, especially when when it came to
multiple queries option even not using a transaction. It facilitates easy go to parameterized queries.
You can use transaction without seriate but with async like below
async.series([
function(callback) {db.run('begin transaction', callback)},
function(callback) {db.run( ..., callback)},
function(callback) {db.run( ..., callback)},
function(callback) {db.run( ..., callback)},
function(callback) {db.run('commit transaction', callback)},
], function(err, results){
if (err) {
db.run('rollback transaction');
return console.log(err);
}
// if some queries return rows then results[query-no] contains them
})
The code is very dirty. Pass req and res params to db-layer is not a good idea.
Try change exeDB. I'm not sure, but probably you don't set error catcher to promise
function exeDB(res, sr, sql, params, callback, multiple) {
// It will execute with no error, no doubt
var obj = {};
for (p in params) {
if (params.hasOwnProperty(p)) {
obj[p] = {
type: sqlServer.VARCHAR,
val: params[p]
};
}
};
var exeOptions = {
query: sql,
params: obj
};
if (multiple) {
exeOptions.multiple = true;
}
// Potential problem is here.
// Catch is useless because code below is asynchronous.
sqlServer.execute(sqlServerConfigObject, exeOptions).then(function (results) {
sr.data = results;
if (callback)
callback(sr);
else
res.json(sr); //produces result when success
}).error(function(err){ // !!! You must provide on-error
console.log(err);
};
}

Validating all data with DB before bulk insert mongoose/mongodb

I am trying to validate the array of objects before inserting them into the mongodb.
what i am trying to do is, lets say i have an object like below
var data= { prodDetails:
[
{ measured: 'Liters',
name: 'A',
prodCode: '713',
status: true },
{ measured: 'Liters',
name: 'B',
prodCode: '713',
status: true },
{ measured: 'Liters',
name: 'C',
prodCode: '674',
status: true }
]
};
before making a bulk insert call i want check whether the given prodCode is valid DB Code or not and name duplicated or not
i am using node bluebird promises.
i tried the following code to validate prodCode
var bulkOperations = {
bulkProdInsert: function (body) {
return new Promise(function (reslv, rej) {
if (body.prodDetails.length > 0) {
common_lg.getValueById(body, "typesProd", body.prodDetails[0].prodCode).then(bulkOperations.successCallback(reslv, rej, body)).catch(bulkOperations.errCallback(reslv, rej, body));
};
reslv();
});
},
successCallback: function (reslv, rej, body) {
return function (res) {
if (res) {
body.prodDetails.splice(0, 1);
if (body.prodDetails.length > 0) {
common_lg.getValueById(body, "typesProd", body.prodDetails[0].prodCode).then(bulkOperations.successCallback(reslv, rej, body)).catch(bulkOperations.errCallback(reslv, rej, body));
}
};
};
},
errCallback: function (reslv, rej, body) {
return function (err) {
body.prodDetails.splice(0, 1);
if (body.prodDetails.length > 0) {
common_lg.getValueById(body, "typesProd", body.prodDetails[0].prodCode).then(bulkOperations.successCallback(reslv, rej, body)).catch(bulkOperations.errCallback(reslv, rej, body));
};
};
}
};
but i want to do is insert all the objects/documents into DB when name and prodCode of all the objects/documents is validated.
how to achieve this.
thanks
It sounds like you want to check the input object and then make DB calls. I would suggest the .map method of bluebird.
var promise = require('bluebird');
var checkValues = promise.method( function(prod){
if( isValid(prod.prodCode) ){
return prod;
}
//something went wrong!
throw new Error('prodCode ' + prod.prodCode + ' is invalid');
}
promise.map( data.prodDetails, checkValues )
.then(function(){
//it worked! You can call the DB now.
})
.catch(function(error){
//something went wrong, look at that error (or pass along)
})
So long as your checkValues method is a promise, you can run it against every value in your input array, and use the success of .then to know things worked and call your DB!

Resources