Node JS Memory Leak? - node.js

I have a Node app (v0.8.26) running on Express (v3.4.8). In that app I have a route that sends an array of objects in the response body. What I'm finding is that doing so immediately begins spinning up the Node memory usage and before long everything shuts down. I'm getting a little desperate so I'm hoping someone can help (quickly).
Here's my route:
get_products: function(req, res) {
var san = req.params.san;
// Authenticate and then retrieve
client.login(datasources.api.auth.sourceId, datasources.api.auth.password, function(err, authToken) {
if (err) {
return res.send(401, err);
}
client.getProducts(token, san, function(err, products) {
if (err) {
var httpStatus = err.httpStatus || 500;
if (httpStatus === 500) {
console.trace(err);
}
return res.send(httpStatus, err.message);
}
if (products) {
return products.length > 0
? res.send(200, products) // <--- ERROR OCCURS HERE
: res.send(200, []);
}
else {
return res.send(403, 'Purchase is not allowed at this time.');
}
});
});
},
And the array being returned looks like this:
[ { PRODUCTID: '7',
PRODUCTNAME: 'Token 1',
QTY: '500',
PRICE: '5',
AVAILABLE: '1',
PRODUCTTYPE: '1',
BILLINGDEALNAME: 'Token 1' },
{ PRODUCTID: '8',
PRODUCTNAME: 'Token 2',
QTY: '1000',
PRICE: '9',
AVAILABLE: '1',
PRODUCTTYPE: '1',
BILLINGDEALNAME: 'Token 2' },
{ PRODUCTID: '9',
PRODUCTNAME: 'Token 3',
QTY: '2000',
PRICE: '16',
AVAILABLE: '1',
PRODUCTTYPE: '1',
BILLINGDEALNAME: 'Token 3' },
{ PRODUCTID: '5',
PRODUCTNAME: 'Token - Free',
QTY: '500',
PRICE: '0',
AVAILABLE: '0',
PRODUCTTYPE: '0',
BILLINGDEALNAME: 'Token - Free Token Use' },
{ PRODUCTID: '6',
PRODUCTNAME: 'Token - Prepaid',
QTY: '500',
PRICE: '0',
AVAILABLE: '0',
PRODUCTTYPE: '0',
BILLINGDEALNAME: 'Token - Prepaid Token Use' } ]
I know it's not a ton of information, but it's all I have. If I force the route to return an empty array in the response, there's no problem. I don't know where else to look.
Help?!
UPDATE
I've tweaked the code slightly for debugging. The ternary operator has been ditched:
if (products.length > 0) {
//return res.send(200, []);
console.error('RETURNING PRODUCTS');
console.error(products);
// return res.send(200, []);
return res.send(200, products);
}
else {
return res.send(200, []);
}

The key to this, for my specific problem, at least, was to downgrade Express.js from 3.4.x to 3.3.x. Because this is a production system, I wasn't able to play with it in order to gain a more sophisticated understanding of what was happening and I've never been able to reproduce this in my downstream environments.
Just wanted to close this out for anyone who may be searching later.

try recent version of nodejs - 0.10.26 - i have similiar issues in nodejs of 0.8.x versions

probably you can use streaming in response
if (products.length > 0) {
res.statusCode = 200;
products.map(res.write);
res.end();
}
else {
return res.send(200, []);
}

Related

How to access specific items in array? [nodejs]

I'm having trouble getting specific items in this array.
[
{
"averages":[
{
"STATUS":"0",
"TYPE":"AAA",
},
{
"STATUS":"0",
"TYPE":"ABC",
},
{
"STATUS":"1",
"TYPE":"ESD",
},
{
"STATUS":"1",
"TYPE":"AAA",
},
]
},
{
"averages":[
{
"STATUS":"0",
"TYPE":"CCC",
},
{
"STATUS":"0",
"TYPE":"AAA",
},
{
"STATUS":"1",
"TYPE":"ESD",
},
{
"STATUS":"1",
"TYPE":"XXX",
},
]
},
{
"averages":[
{
"STATUS":"1",
"TIPO":"XXX",
},
{
"STATUS":"1",
"TYPE":"LLL",
},
{
"STATUS":"1",
"TYPE":"AAA",
},
{
"STATUS":"1",
"TYPE":"NU",
},
{
"STATUS":"0",
"TYPE":"XXX",
},
{
"STATUS":"1",
"TYPE":"AAA",
}
]
},
]
I'm trying to separate status from type AAA
[0, 1, 0, 1, 1, 1]
I get the array like this:
var quality = solicitacoes[0].produtor.dados[0].apiLaticinio[0].qualidade[0]
var qualityjson = JSON.parse(quality)
console.log(JSON.stringify(qualityjson));
I tried to use this material, but without success: enter link description here
What nodejs resource can I access the items in the way I mentioned?
Thanks if anyone can help me!
UPDATE:
I used this method to try to solve my problem.
function getStatus(arr) {
let results = [];
arr.forEach(avg => {
avg.averages.forEach(element => {
if (element["TYPE"] === 'AAA') {
results.push(element["STATUS"])
}
})
})
return results;
}
const results = getStatus(quality)
But I'm getting the following result:
TypeError: arr.forEach is not a function
To get all the status from the given array you can just use Array.map() inside Array.map() like below:
const getItems = (array = items) => {
return array.map((arItem, _) => {
return arItem.averages.map((nestItem, _) => {
return nestItem.STATUS
})
})
}
console.log([].concat(...getItems()))
//Output:
//[
// '0', '0', '1', '1',
// '0', '0', '1', '1',
// '1', '1', '1', '1',
// '0', '1'
//]
However if you are trying to get the items with TYPE='AAA', then you can use the following code:
const getTypeAAAItems = (array = items) => {
return array.map((arItem, _) => {
return arItem.averages.filter((nestItem) => {
return nestItem.TYPE === 'AAA'
})
})
}
//Output:
//[
// { STATUS: '0', TYPE: 'AAA' },
// { STATUS: '1', TYPE: 'AAA' },
// { STATUS: '0', TYPE: 'AAA' },
// { STATUS: '1', TYPE: 'AAA' },
// { STATUS: '1', TYPE: 'AAA' }
//]
I believe you're saying that you want to turn an array of objects with a STATUS field into an array of numbers. Let's say you have a single item from your above array:
{
"averages":[
{
"STATUS":"0",
"TYPE":"AAA",
},
{
"STATUS":"0",
"TYPE":"ABC",
},
{
"STATUS":"1",
"TYPE":"ESD",
},
{
"STATUS":"1",
"TYPE":"AAA",
},
]
},
Assuming the above is parsed and stored as item:
const statuses = item.averages.map(i => i.STATUS);
Array.prototype.map will let you manipulate each element of an array in the same way and return the new array (which will have the same number of elements as the old one).
In this case, we take an object with a STATUS and TYPE field, and instead return only the value of the STATUS field. So we end up with an array of numbers; [0, 0, 1, 1].

How does admin. messaging. AndroidNotification need to be configured for localization?

In the firebase documentation I found that admin. messaging. AndroidNotification has properties to provide localization to your notifications. Or at least that is what I understand from it.
https://firebase.google.com/docs/reference/admin/node/admin.messaging.AndroidNotification
In the docs they have bodyLocArgs and bodyLocKey to localize the body and titleLocArgs and titleLocKey. How do these need to be configured in order to localize my notification?
So let's say my client (the android device) is using en_US as his current language. Is my clients locale used to localize the notification?
This is what my current message
const translator = deviceData.language !== 'nl' ? languages.en : languages.nl;
const title = `${translator['messageTitle' as keyof typeof translator]} ${group.displayName}`;
const body = `${sender.displayName} ${translator[type as keyof typeof translator]}`;
const systemTrayNotification: TokenMessage = {
token: deviceData.cloudMessagingToken,
notification: {
title: title,
body: body,
},
data: {
title: title,
body: body,
senderId: sender.id,
senderDisplayName: sender.displayName,
groupId: group.id,
type: 'groupMessage',
messageType: type,
sentAt: new Date().toISOString(),
},
android: {
priority: 'high',
notification: {
priority: 'max',
channelId: '59054',
clickAction: 'FLUTTER_NOTIFICATION_CLICK',
tag: 'groupMessage',
defaultSound: true,
defaultVibrateTimings: true,
bodyLocArgs: //what do I do here?,
bodyLocKey: //what do I do here?
titleLocArgs: //what do I do here?,
titleLocKey: //what do I do here?
}
},
apns: {
payload: {
aps: {
category: 'groupMessage',
headers:{
"apns-priority":"10"
},
alert: {
title: title,
body: body,
},
aps: {
sound: 'default',
},
customData: {
title: title,
body: body,
senderId: sender.id,
senderDisplayName: sender.displayName,
groupId: group.id,
type: 'groupMessage',
messageType: type,
sentAt: new Date().toISOString(),
}
}
},
}
}
Use like this.
body: jsonEncode({
'notification': <String, dynamic>{
'title_loc_key': 'BOOKING_RECEIVED_PUSH_SUBTITLE',
'title_loc_args': [booking.shopName],
'body_loc_key': 'BOOKING_RECEIVED_PUSH_BODY',
'body_loc_args': [
customerName,
'',
bookingStart
], //, bookingDate, bookingStart]),
'sound': 'true',
'mutable_content': 'true',
'content_available': 'true'
},
'priority': 'high',
'data': <String, dynamic>{
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done'
},
'to': customerFCMToken
})).whenComplete(() {
print('sendBookingReceived(): message sent');
}).catchError((e) {
print('sendBookingReceived() error: $e');
});
try this and let me know if it is working or not.

how to fetch payload from quick replies in botpress

i am new to botpress and trying to make simple order bot with botpress. but not using messenger,etc just trying to make simple question answer bot. in available example on github uses content.yml but it gives error
[Renderer] Renderer not defined (#welcome)
at /Applications/MAMP/htdocs/botpress-pro-nightly-2018-12-24-darwin-x64/pizza/node_modules/botpress/src/renderers/index.js:163:13
index.js
module.exports = bp => {
Object.keys(renderers).forEach(name => {
bp.renderers.register(name, renderers[name])
})
bp.hear(/GET_STARTED|hello|hi|test|hey|holla/i, (event, next) => {
console.log(event);
event.reply('#welcome')
var yes=event.welcome.quick_replies[0].payload;
bp.logger.info('answer:', yes);
})
}
so i use this type of code in renderers.js it works but not able to fetch reply
module.exports = {
text: data => {
return {text: data.text, typing: !!data.typing}
},
'#welcome': data => ({
typing: true,
text: 'Hey there! Would you like to order?',
quick_replies: [
{
content_type: 'text',
title: 'Yes',
payload: 'Y'
},
{
content_type: 'text',
title: 'No',
payload: 'N'
}
],
}) ,
'#askLocation': data => ({
typing: true,
text: 'Please click this button for me to know where you are!',
quick_replies: [
{
content_type: 'location',
title: 'location',
payload: 'location'
}
],
})
}

How to get data in sequelize using Noje js

This is code i have used, fetched the all data in database, but i have not getting in value. I'm new for sequelize.
Project.findAll({ raw: true}).then(function (users) {
console.log(users);
console.log(users.dataValues);
}).catch(function (err) {
console.log('Oops! something went wrong, : ', err);
});
This is Output:
This is console.log(users);
[ DAO {
dataValues:
{ idProject: 1,
projectName: 'Symfony',
isActive: '1',
createdAt: 2018-10-23T06:32:43.000Z,
modifiedAt: 2018-10-23T06:32:43.000Z },
_previousDataValues:
{ idProject: 1,
projectName: 'Symfony',
isActive: '1',
createdAt: 2018-10-23T06:32:43.000Z,
modifiedAt: 2018-10-23T06:32:43.000Z },
options: { isNewRecord: false, isDirty: false, raw: true },
hasPrimaryKeys: true,
selectedValues:
RowDataPacket {
idProject: 1,
projectName: 'Symfony',
isActive: '1',
createdAt: 2018-10-23T06:32:43.000Z,
modifiedAt: 2018-10-23T06:32:43.000Z },
__eagerlyLoadedAssociations: [],
isNewRecord: false }.....
This is console.log(users.dataValues);
undefined
How is it possible?
When you use findAll, it returns an array, as you can see here in the documentation:
http://docs.sequelizejs.com/class/lib/model.js~Model.html#static-method-findAll
so you should iterate over this array, like so:
Project.findAll({ raw: true})
.then(projects => {
projects.forEach(project => {
console.log(project);
console.log('project name', project.projectName);
})
}).catch(function (err) {
console.log('Oops! something went wrong: ', err);
});
Optionally you could use Async/Await for a cleaner code:
try {
const projects = await Project.findAll({ raw: true});
projects.forEach(project => {
console.log('project name ', project.projectName);
})
} catch(err) {
console.log('Oops! something went wrong: ', err);
}

Strange behavior for update an entry in mongodb

I like to update an entry in mongodb. But lodash only update one value in the array. I send this object to my node.js server:
{ _id: 5593df7c087e59a00c04cda3,
name: 'blueberry',
uuid: 'b9407f30-f5f8-466e-aff9-25556b57fe6d',
major: '12345',
minor: '12345',
position: 'Kantine',
__v: 18,
messages:
[ { _id: 5593df7c087e59a00c04cda4,
timeRange: [Object],
url: '',
message: 'j',
title: 'jv',
messageType: 'text' },
{ _id: 5593df7c087e59a00c04cda4,
timeRange: [Object],
url: '',
message: 'j',
title: 'jv',
messageType: 'text' } ] }
Here is the code for the update of the mongodb-entry:
// Updates an existing ibeacons in the DB.
exports.update = function(req, res) {
Ibeacons.findById(req.params.id, function (err, ibeacons) {
if (err) { return handleError(res, err); }
if(!ibeacons) { return res.send(404); }
var updated = _.merge(ibeacons, req.body);
updated.save(function (err) {
if (err) { return handleError(res, err); }
return res.json(200, ibeacons);
});
});
};
But I get this as result:
{ _id: 5593df7c087e59a00c04cda3,
name: 'blueberry',
uuid: 'b9407f30-f5f8-466e-aff9-25556b57fe6d',
major: '12345',
minor: '12345',
position: 'Kantine',
__v: 18,
messages:
[ { _id: 5593df7c087e59a00c04cda4,
timeRange: [Object],
url: '',
message: 'j',
title: 'jv',
messageType: 'text' },
{ _id: 5593df7c087e59a00c04cda4,
timeRange: [Object],
url: '',
message: 'j',
title: 'jv',
messageType: 'text' } ] }
Maybe someone can help me.
Ok I get it. the version of lodash was on 2.4.1 now I updated it to 3.1.0 and it works. :D

Resources