Sending array data from server to client in Meteor - javascript

So I'm trying to send my data from my server code to my client code, yet it's returning undefined. Not sure what to do as I've been stuck here for a while.
I used these packages:
https://github.com/meteorhacks/npm
https://www.npmjs.com/package/wiki-infobox
Rappers = new Mongo.Collection(null)
var page = 'Tupac'
var language = 'en'
var rappers = null
var texts
var rappers2
if (Meteor.isClient) {
getGists = function getGists(user, callback) {
Meteor.call('getGists', user, callback);
}
Meteor.startup(function() {
rappers2 = []
function call(text, callback) {
Meteor.call('getWikiStuff', rappers2, function(err, result) {
console.log(result)
})
var timer = setTimeout(function() {
callback()
}, 4000)
}
function consoleit() {
console.log(rappers2)
}
call('hello', consoleit)
})
}
if (Meteor.isServer) {
Meteor.startup(function() {
Meteor.methods({
getWikiStuff: function(rappers3) {
var infobox = Meteor.npmRequire('wiki-infobox')
var bound = Meteor.bindEnvironment(function(callback) {
callback()
});
console.log("HERE")
bound(function() {
infobox(page, language, function(err, data) {
if (err) {
return
}
rappers = data.associated_acts
for (var x = 0; x < rappers.length; x++)
if (rappers[x].text != undefined) {
var yo = rappers[x].text
rappers3.push(yo)
}
for (var value of rappers3)
console.log(value)
})
})
return rappers3
}
})
})
}

Related

I want to get attachments as well that comes with the message Gmail API

Okay so with this code I am able to get the actual mail content which comes by Email but what I want is I want to get message and attachment too. what can be done in order to list out attachments and later on giving option to download the attachments gmail api.
var ifrm = document.getElementById("iframe").contentWindow.document;
ifrm.body.innerHTML = getMessageBody(message.payload);
};
let getMessageBody = (message) => {
var encodedBody = "";
if (typeof message.parts === "undefined") {
encodedBody = message.body.data;
} else {
encodedBody = getHTMLPart(message.parts);
}
return Base64.decode(encodedBody);
};
let getHTMLPart = (arr) => {
for (var x = 0; x <= arr.length; x++) {
if (typeof arr[x].parts === "undefined") {
if (arr[x].mimeType === "text/html") {
return arr[x].body.data;
}
} else {
return getHTMLPart(arr[x].parts);
}
}
return "";
};
Gmail API when I click on message.
getOneMessage = (messageId) => {
return window.gapi.client.gmail.users.messages
.get({
userId: "me",
id: messageId,
})
.then(
(response) => {
this.setState({
message: response.result,
});
},
(err) => {
console.error("getMessage error", err);
}
);
};
handleMessageClick = (e) => {
const messageId = e.currentTarget.getAttribute("id");
this.getOneMessage(messageId);
Solution
You are using the Users.messages: get endpoint. This is fine to retrieve the message body, but to retrieve attachments you will have to use the Users.messages.attachments: get. Here you can find a link to the documentation.
Proposed code editing:
getAttachments = (message, callback) => {
var parts = message.payload.parts;
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
if (part.filename && part.filename.length > 0) {
var attachId = part.body.attachmentId;
var request = gapi.client.gmail.users.messages.attachments.get({
'id': attachId,
'messageId': message.id,
'userId': userId
});
request.execute(function(attachment) {
callback(part.filename, part.mimeType, attachment);
});
}
}
}
getOneMessage = (messageId) => {
return window.gapi.client.gmail.users.messages
.get({
userId: "me",
id: messageId,
})
.then(
(response) => {
this.setState({
message: response.result,
});
// Get the attachment and do something with it
getAttachments(response.result, callback);
},
(err) => {
console.error("getMessage error", err);
}
);
};
handleMessageClick = (e) => {
const messageId = e.currentTarget.getAttribute("id");
this.getOneMessage(messageId);
Reference
Users.messages.attachments

Mysql node.js async, wait for query to complete

Been trying everything to get this to work specifically the async each method. for (const element of resultsHistory) didn't work either.
I'm trying to modify the result array from a previous query by running a foreach over it and doing a mysql query.
However this needs to wait for the query to complete.
Is there a way to access these results without the setTimeout(function() { } I put manually in order to wait for the query to finish?
function getUserLikes(params, callback) {
var usersArrayCat = [];
console.log(`length of array ${params.length}`)
// 1 here means 1 request at a time
async.eachLimit(params, 1, function (element, cb) {
element.liked = 0;
var queryLiked = `SELECT * from users_likes WHERE user_id = \"${req.body.userid}\" AND product_id = \"${element.product_id}\"`;
connectionPromise.query(queryLiked, function (err, result) {
if (!result) {
} else if (result.length == 0) {
} else {
element.liked = result[0].userlike;
usersArrayCat.push(element);
// console.log(usersArrayCat);
cb();
}
})
}, function (err) {
if (err) return callback(err);
callback(null, usersArrayCat)
});
};
getUserLikes(resultsHistory, function (e) {
console.log(e);
});
if(!res.headersSent) {
setTimeout(function() {
res.send(JSON.stringify({"status": 200 ,"error": null, "top3":resultsHistory}));
}, 150);
}
Managed to get it working like this, but still not sure if this is the right way.
async function getUserLikes(resultsHistory) {
for (const element of resultsHistory) {
element.liked = 0;
let queryLiked = `SELECT * from users_likes WHERE user_id = \"${req.body.userid}\" AND product_id = \"${element.product_id}\"`;
let liked = await conn2.query(queryLiked);
if (liked[0]) {
element.liked = liked[0].userlike;
}
}
if(!res.headersSent) {
conn2.release();
let newres = resultsHistory.sort(
firstBy(function (v1, v2) { return v2.rating - v1.rating; })
.thenBy(function (v1, v2) { return v2.dranktimes - v1.dranktimes; })
).filter( function(history) {
return history.event === eventName;
}).slice(0, 3);
res.send({"status": 200 ,"error": null, "top3":newres});
}
}
getUserLikes(resultsHistory);
See my answer:
function getUserLikes(params, callback) {
var usersArrayCat = [];
console.log(`length of array ${params.length}`)
// 1 here means 1 request at a time
async.eachLimit(params, 1, function (element, cb) {
element.liked = 0;
var queryLiked = `SELECT * from users_likes WHERE user_id = \"${req.body.userid}\" AND product_id = \"${element.product_id}\"`;
connectionPromise.query(queryLiked, function (err, result) {
if (!result) {
} else if (result.length == 0) {
} else {
element.liked = result[0].userlike;
usersArrayCat.push(element);
// console.log(usersArrayCat);
}
cb();
})
}, function (err) {
if (err) return callback(err);
callback(null, usersArrayCat)
});
};
getUserLikes(resultsHistory, function (e, usersArrayCat) {
if (e) {
console.log(e);
return res.send({status: 400, error: e}); // your error response
}
console.log(usersArrayCat); // your usersArrayCat with liked property
res.send(JSON.stringify({ // why your need return a string intead of json object ???
"status": 200,
"error": null,
"top3": usersArrayCat // I think return `usersArrayCat` is a right way
}));
});

Loop Childens Custom Mongodb

User.find({ refUser: req.params.userName }).then(function (users) {
var network_users = [];
network_users.push(users);
users.forEach(function (u) {
network_users.push(User.find({ refUser: u.toObject().userName }));
})
return Promise.all(network_users);
I have 4 users, I expected receive a json with all of childrens but I only received the first and the children of this first.
Someone can help me with this loop? Please! Thanks so much!!!!
function asyncLoop(iterations, func, callback, foo) {
var done = false;
var loop = {
next: function () {
if (done) {
return;
}
if (iterations) {
func(loop);
} else {
done = true;
if (callback) callback(foo);
}
},
isEnd: function () {
return done;
},
refresh: function (it) {
iterations = it;
},
break: function () {
done = true;
callback();
}
};
loop.next();
return loop;
}
function bfs(userName, callback) {
userName = String(userName);
var q = [], res = [];
User.findOne({ "refUser" : userName }).lean().exec(function (err, root) {
root.depth = 0;
q.push(root);
asyncLoop(q.length, function (loop) {
res.push(q[0]);
User.find({ "refUser" : q[0].userName }).lean().exec(function (err, new_nodes) {
if (err) console.log(err);
else {
var d = q[0].depth;
q.shift();
loop.refresh(new_nodes.length + q.length);
if (new_nodes.length > 0) {
new_nodes.forEach(function (new_node) {
new_node.depth = d + 1;
q.push(new_node);
});
}
loop.next();
}
});
}, function () { callback(res) });
});
}
Finishing:
bfs(req.params.userName,function(callback){
res.send(callback)
})

Push data to out side async function

I still do not handle well the asynchronous functions, I have an array of items, and I'm trying to for each item calculate some values and push to another array outside of the async function. Then I want to make some statistics calculation and send to front end. It's server side, nodejs handler, my code:
exports.register = function (plugin, options, next) {
function isInArray(value, array) {
return array.indexOf(value) > -1;
}
function statistics(values) {
var sum = math.sum(values);
var max = math.max(values);
var min = math.min(values);
var stddev = math.std(values);
var mean = math.mean(values);
var count = values.length;
}
plugin.route({
method: 'GET',
path: '/statistics/{orgId}/layout/{layoutId}',
config: {
pre: [
authorize(hasRole(['OPERATIONAL', 'STRATEGIC', 'LOP', 'TACTICAL']))
],
handler: function (request, reply) {
Category.find()
.where('organization')
.equals(request.params.orgId)
.exec(function (err, categories) {
var weight = [];
var price = [];
var volume = [];
var thisAR = [];
if (err || categories === null) {
return reply(Boom.badRequest('Categoria inexistente'));
} else {
Location.findById(request.params.layoutId)
.exec(function (err, layout) {
if(err) {
console.log(err);
}
var searchItems = function searchItems(category, next) {
Item.find()
.where('category')
.equals(category._id)
.exec(function (err, items) {
if (err) {
console.log(err);
} else {
var valuesToCalculate = [];
var itemsFiltered = [];
_.forEach(items, function(item) {
if(item.location && item.location !== null) {
if(isInArray(item.location.toString(), layout.contents)) {
itemsFiltered.push(item);
}
}
});
valuesToCalculate.push(itemsFiltered.length * category.data.weight);
valuesToCalculate.push(itemsFiltered.length * category.data.price);
valuesToCalculate.push(itemsFiltered.length * category.data.volume);
next(valuesToCalculate);
}
});
}
var onFinish = function onFinish(value, err) {
if(err) {
console.log(err);
}
console.log(value);
thisAR.push.apply(value);
}
async.each(categories, searchItems, onFinish);
console.log(thisAR);
//var arrays = [statistics(weight), statistics(price), statistics(volume)];
//return arrays;
});
}
});
}
}
});
next();
};
A few things stand out to me about this. First, you only call reply if there is an err or categories is null. Also, you are attempting to pass a non null value to an async.each callback. According to this: https://github.com/caolan/async#eacharr-iterator-callback, "if no error has occurred, the callback should be run without arguments or with an explicit null argument". I think you may misunderstand how the onFinish callback works with async.each.. it is not called for each item, it is called when all of the iterator functions have completed. So, rather than pushing items onto thisAR in onFinish, you should do so inside searchItems. I think this should work:
exports.register = function (plugin, options, next) {
function isInArray(value, array) {
return array.indexOf(value) > -1;
}
function statistics(values) {
var sum = math.sum(values);
var max = math.max(values);
var min = math.min(values);
var stddev = math.std(values);
var mean = math.mean(values);
var count = values.length;
}
plugin.route({
method: 'GET',
path: '/statistics/{orgId}/layout/{layoutId}',
config: {
pre: [
authorize(hasRole(['OPERATIONAL', 'STRATEGIC', 'LOP', 'TACTICAL']))
],
handler: function (request, reply) {
Category.find()
.where('organization')
.equals(request.params.orgId)
.exec(function (err, categories) {
var weight = [];
var price = [];
var volume = [];
var thisAR = [];
if (err || categories === null) {
return reply(Boom.badRequest('Categoria inexistente'));
} else {
Location.findById(request.params.layoutId)
.exec(function (err, layout) {
if(err) {
console.log(err);
}
var searchItems = function searchItems(category, next) {
Item.find()
.where('category')
.equals(category._id)
.exec(function (err, items) {
if (err) {
console.log(err);
} else {
var valuesToCalculate = [];
var itemsFiltered = [];
_.forEach(items, function(item) {
if(item.location && item.location !== null) {
if(isInArray(item.location.toString(), layout.contents)) {
itemsFiltered.push(item);
}
}
});
valuesToCalculate.push(itemsFiltered.length * category.data.weight);
valuesToCalculate.push(itemsFiltered.length * category.data.price);
valuesToCalculate.push(itemsFiltered.length * category.data.volume);
thisAR.push.apply(valuesToCalculate);
}
next(err);
});
}
var onFinish = function onFinish(err) {
if(err) {
console.log(err);
}
console.log(thisAR);
// call reply here
}
async.each(categories, searchItems, onFinish);
console.log(thisAR);
//var arrays = [statistics(weight), statistics(price), statistics(volume)];
//return arrays;
});
}
});
}
}
});
next();
};
I can't comment since I'm new but it seems that just removing the .apply in thisAR.push.apply(valuesToCalculate); will return a full array to your console.log.

nodeStack.getFunctionName() returns null

I have the following node.js code:
var path = require('path');
var nodeStack = require('stack-trace');
var controller = (function () {
function controller() {
}
controller.prototype.render = function (res, model, view) {
var stack = nodeStack.get();
var frame = stack[1];
var functionName = frame.getFunctionName().split(/controller\./i);
if (functionName.length < 2) {
functionName = frame.getFunctionName().split(/(controller|\./i);
}
if (!view) {
view = functionName[1];
var dotidx = view.indexOf('.');
if (dotidx > -1) {
view = view.substring(0, dotidx);
}
}
if (!model) {
model = {};
}
var base = '';
if (res.locals.basePath) {
base = res.locals.basePath;
}
var cls = functionName[0];
res.render(path.join(base, cls, view), model);
};
return controller;
})();
module.exports = controller;
The code should allow me to render a view based on the method, the matching file should be found automatically.
It works all fine, just in one case frame.getFunctionName() returns null.
The code for the subclasses look as follows:
customerController.prototype.add = function (req, res) {
var _this = this;
somepromise.then(function (provider) {
return provider.getCP();
}).then(function (cp) {
controller.prototype.render.call(_this, res, { title: 'add customer', contactpersons: cp });
}, function (err) {
controller.prototype.render.call(_this, res, { title: 'add customer' });
});
};
The one code that doesn't work.
customerController.prototype.details = function (req, res) {
var _this = this;
somepromise.then(function (provider) {
return provider.getCustomerById(req.param('id'));
}).then(function (customer) {
_super.prototype.render.call(_this, res, { title: 'customer details', customer: customer });
}, function (err) {
res.status(404).send(err);
});
};
The code works for all methods except one. Do you have an idea why?
Remarks: The code is compiled from TypeScript

Categories