How can I fix 'Refactor this function to use "return" consistently.' from sonar js - eslint

I apply SonarJS analysis to my project.
An error 'Refactor this function to use "return" consistently' was found in the code below.
How can I fix this?
var filter1Depth = function(attr0, attr1, val){
var id;
if(val === "vAuto"){
id = "AirConditioner.Indoor.Ventilator";
val = "Auto";
}
return { // Error is generated from this line.
field : attr0,
operator: function(item, value){
if(value == "") return true;
if(!item || !item.length) return;
var i, length = item.length;
if(value == "undefined"){
for( i = 0; i < length; i++ ){
if(typeof item[i][attr1] === 'undefined'){
return true;
}
}
}else{
for(i = 0; i < length; i++){
if(item[i][attr1] == value){
if(id){
if(id === item[i]["id"]) return true;
return;
}
return true;
}
}
}
return;
},
value : val
};
};
Another example is like below.
var filter1DepthNone = function(attr0, attr1, val){
return { field : attr0, operator: function(item, value){ // error!!
if(value == "") return true;
if(!item || !item.length) return;
var length = item.length;
for(var i = 0; i < length; i++){
if(item[i][attr1] != value){
return;
}
}
return true;
}, value : val};
};
My codes where this error is generated from has similar pattern..

In some blocks, you're returning nothing (return;, so undefined) but in other blocks in the same function, you return a boolean (true/false).
You need to make sure that your returns are consistent within a function - that is, if you return a boolean somewhere, everywhere you return a value within that same function, you also return a boolean.

Related

node.js how to get data from redis database inside in middleware

I'm doing middleware module that will extract data from redis and put to req.my_session.[here]
This is function that call inside app.use();
function parse_cookies(req){
if(req.headers.cookie != null){
var result = req.headers.cookie.match(new RegExp('m:[^=]*=[^; ]*', 'ig'));
if(result != null){
for(var i = 0; i < result.length; i++){
var result1 = result[i].split('=');
req.my_session[result1[0].substr(2)] = result1[1];
// get from redis value
client.get('sess:'+result1[1], function(err, reply) {
// reply is null when the key is missing
console.log(reply);
let li = i;
req.my_session[result1[0].substr(2)] = reply;
console.log('li = ' + li);
console.log('result1.lenght= ' + result.length);
if(i == result.length){
console.log('call the next');
}
});
}
}
}
} // parse_cookies
in console i outputs always 3, how can I get all data from database using redis.get and on last data call next() function for get out from my function?
problem it's get data from database in my middleware, I can't because redis has callback function
client.get("missingkey", function(err, reply) {
// reply is null when the key is missing
console.log(reply);
});
I think the issue is becuase of async in loop you can try the following
function parse_cookies(req){
if(req.headers.cookie != null){
var result = req.headers.cookie.match(new RegExp('m:[^=]*=[^; ]*', 'ig'));
if(result != null){
var promises = [];
for(var i = 0; i < result.length; i++){
var result1 = result[i].split('=');
promises.push(getFromRd(req, result1));
}
return Promise.all(promises)
.then(() => {
return next()
})
.catch((e) => {
return next({error: e})
})
}
}
} // parse_cookies
function getFromRd(req, result1) {
req.my_session[result1[0].substr(2)] = result1[1];
// get from redis value
return client.get('sess:'+result1[1], function(err, reply) {
if (err) {
throw Error(' failed to find ' + 'sess:' + result1[1])
}
// reply is null when the key is missing
console.log(reply);
let li = i;
req.my_session[result1[0].substr(2)] = reply;
console.log('li = ' + li);
console.log('result1.lenght= ' + result.length);
return {success:true}
});
}

How to write a REST API for nodejs to return a random number?

In fallowing code which is generating a 5 digits number and I would like to make a single API to call this code and return a random number. something like:
https://sub.mydomain.com/getnumber
function getnumber() {
var code = "";
var possible = "1234567890";
for (var i = 0; i < 5; i++) {
code += possible.charAt(Math.floor(Math.random() * possible.length));
if (i == 0 && code == "0") {
code = "7"
}
}
return code;
}
I am no expert at all but as you get on comments node.js http server is your solution:
try this little one code:
const http = require('http');
http.createServer((request, response) => {
if (request.method === 'GET' && request.url === '/getnumber') {
request.pipe(response);
response.end(getnumber());
} else {
response.statusCode = 404;
response.end();
}
}).listen(8080);
function getnumber() {
var code = "";
var possible = "1234567890";
for (var i = 0; i < 5; i++) {
code += possible.charAt(Math.floor(Math.random() * possible.length));
if (i == 0 && code == "0") {
code = "7"
}
}
return code;
}
your URL should be like:
127.0.0.1:8080/getnumber

DocumentDB, How to work with continuationToken in a SP

The next SP suppose to run over the collection and keep query for the next batch of documents (10 docs every batch). but instead return the same 10 documents every time.
function sample(prefix) {
var continuations = [],
ids = [],
context = getContext(),
collection = context.getCollection(),
response = context.getResponse();
var queryOptions = { pageSize: 10, continuation: null };
for (i = 0; i < 10; i++) {
// get all user wish list actions
var query = "select * from w",
accept = collection.queryDocuments(collection.getSelfLink(), query, queryOptions, processMultiUsers);
if (!accept) throw "Unable to read user's sessions";
}
getContext().getResponse().setBody(ids);
function processMultiUsers(err, docs, options) {
if (err) throw new Error("Error: " + err.message);
if (docs == undefined || docs.length == 0) throw new Error("Warning: Users not exists");
for (j = 0; j < docs.length; j++) {
ids.push(docs[j].UserId);
}
queryOptions.continuation = options.continuation;
continuations.push(options.continuation);
}}
In the script that you wrote, the execution of the queries are done synchronously and they are queued up with the same initial continuation token, which is null. Instead, we need to take the token from the first query and then queue the next and continue.
The below sample should help achieve what you are looking for
function sample(continuationToken) {
var collection = getContext().getCollection();
var maxResult = 10;
var documentsProcessed = 0;
var ids = [];
var filterQuery = "select * from w";
tryQuery(continuationToken);
function tryQuery(nextContinuationToken) {
var responseOptions = { continuation: nextContinuationToken, pageSize: maxResult };
if (documentsProcessed >= maxResult || !query(responseOptions)) {
setBody(nextContinuationToken);
}
}
function query(responseOptions) {
return (filterQuery && filterQuery.length) ?
collection.queryDocuments(collection.getSelfLink(), filterQuery, responseOptions, onReadDocuments) :
collection.readDocuments(collection.getSelfLink(), responseOptions, onReadDocuments);
}
function onReadDocuments(err, docFeed, responseOptions) {
if (err) {
throw 'Error while reading document: ' + err;
}
documentsProcessed += docFeed.length;
for (var i = 0; i < documentsProcessed; i++) {
ids.push(docFeed[i].UserId);
}
if (responseOptions.continuation) {
tryQuery(responseOptions.continuation);
} else {
setBody(null);
}
}
function setBody(continuationToken) {
var body = { continuationToken: continuationToken, documentsProcessed: documentsProcessed, ids: ids };
getContext().getResponse().setBody(body);
}
}

What is wrong with this script?

var isEven = function(number) {
if (number%2 === 0) {
return true;
};
else if (isNaN(number) === true) {
return ("please input a number");
};
else {
return false;
};
};
Your script should not have the ; behind your closing brackets
Try this:
var isEven = function(number){
if (number%2 === 0) {
return true;
} else if (isNaN(number)===true) {
return ("please input a number");
} else {
return false;
}
}

Loop synchronous multiple async.whilst

I want to use many included loops in node.js in synchronous mode.
Example :
for (var i = 0; i < length1; i++) {
for (var j = 0; j < length2; j++) {
for (var k = 0; k < length3; k++) {
//completed 3
}
//completed 2
}
//do completed 1
}
How to do this with async? I tried this :
exports.myFunction = function (callback) {
var finalListA = new Array();
var pos = 0;
Model_A.find().populate('listOfItems')
.lean().exec(function (err, As) {
if (err) {
console.log(err);
return callback(err, null);
} else {
//For each A
var i = 0;
async.whilst(
function () {
return i < As.length;
},
function (callback1) {
var isActive = false;
//For each B into the A
var j = 0;
async.whilst(
function () {
return j < As[i].Bs.length;
},
function (callback2) {
Model_B.findById(AS[i].Bs[j]._id, function (err, B) {
if (err) {} else {
var k = 0;
// For each C in the B
async.whilst(
function () {
return k < B.Cs.length;
},
function (callback3) {
if (B.Cs[k].dateEnd >= Date.now()) {
isActive = true;
}
k++;
callback3();
},
function (err) {
console.log("3 COMPLETED");
}
);
}
});
j++;
callback2();
},
function (err) {
console.log("2 COMPLETED");
if (err) {} else {
if (isActive == true) {
finalListA[pos] = As[i];
pos = pos + 1;
}
}
}
);
i++;
callback1();
},
function (err) {
console.log("1 COMPLETED");
if (err) {} else {
return callback(null, finalListA);
}
}
);
}
});
}
The trace shows me :
COMPLETED 2
COMPLETED 2
COMPLETED 1
COMPLETED 3
COMPLETED 3
The order expected is :
COMPLETED 3
COMPLETED 3
COMPLETED 2
COMPLETED 2
COMPLETED 1
You must call the callbacks of the higher loops from the end callback of your whilst loop (like you did with the outermost callback), instead of calling them synchronously from the whilst body in which you just started the next level iteration.
Btw, I don't know what you actually want to do, but whilst does not seem the best choice for iterating arrays. Use the parallel each or the serial eachSeries (or their map or reduce equivalents).
I've recently created simpler abstraction called wait.for to call async functions in sync mode (based on Fibers). It's at an early stage but works. It is at:
https://github.com/luciotato/waitfor
Using wait.for, you can call any standard nodejs async function, as if it were a sync function.
I do not understand exactly what are you trying to do in your code. Maybe you can explain your code a little more, or give some data example.
I dont' know what Model_A or Model_B are... I'm guessing most of your code, but...
using wait.for your code migth be:
var wait=require('wait.for');
exports.myFunction = function(callback) {
//launchs a Fiber
wait.launchFiber(inAFiber,callback);
}
function inAFiber(callback) {
var finalListA = new Array();
var pos = 0;
var x= Model_A.find().populate('listOfItems').lean();
As = wait.forMethod(x,"exec");
//For each A
for(var i=0;i<As.length;i++){
var isActive = false;
//For each B into the A
for(var j=0; j < As[i].Bs.length;j++){
var B=wait.forMethod(Model_B,"findById",AS[i].Bs[j]._id);
// For each C in the B
for(var k=0; k < B.Cs.length;k++){
if(B.Cs[k].dateEnd >= Date.now()) {
isActive = true;
}
}
console.log("3 COMPLETED");
}
console.log("2 COMPLETED");
if(isActive == true) {
finalListA[pos] = As[i];
pos = pos + 1;
}
};
console.log("1 COMPLETED");
return callback(null,finalListA);
}
Also, for what I see, you should break the loops as soon as you find one item (isActive), and you don't need the var pos. Doing that your code will be:
var wait=require('wait.for');
exports.myFunction = function(callback) {
//launchs a Fiber
wait.launchFiber(inAFiber,callback);
}
function inAFiber(callback) {
var finalListA = [];
var x= Model_A.find().populate('listOfItems').lean();
As = wait.forMethod(x,"exec");
var isActive;
//For each A
for(var i=0;i<As.length;i++){
isActive = false;
//For each B into the A
for(var j=0; j < As[i].Bs.length;j++){
var B=wait.forMethod(Model_B,"findById",AS[i].Bs[j]._id);
// For each C in the B
for(var k=0; k < B.Cs.length;k++){
if(B.Cs[k].dateEnd >= Date.now()) {
isActive = true;
break;//for each C
}
} //loop for each C
console.log("3 COMPLETED");
if (isActive) break;//for each B
} //loop for each B
if (isActive) finalListA.push(As[i]);
console.log("2 COMPLETED");
} //loop for each A
console.log("1 COMPLETED");
return callback(null,finalListA);
}

Resources