async function get_info(compName) {
let company = {
name:""
, activityNumber:""
, siret :""
, adresse :""
, tva :""
, logo:0
};
buff = await db.all("SELECT * FROM company WHERE name = ?", [compName], (err, rows) => {
if (err) {
console.log(err)
return err;
}
rows.forEach(element => {
console.log(element.name) // WORK
company.name = element.name;
company.activityNumber = element.activityNumber;
company.adresse = element.adresse;
company.logo = element.logo;
company.siret = element.siret;
company.tva = element.tva;
});
});
console.log(" ... " + company.name) // DOSENT WORK
return company;
}
I'm trying to get company fill and get data out of my database.
The first console.log() is good but not the second one, it's empty, and the object it returns have defaults values, there will be only one element who will match "WHERE name = ?" so I don't worry about erasing the value.
Related
This question already has answers here:
Using async/await with a forEach loop
(33 answers)
Closed 1 year ago.
I know this has been asking thousands of times, but I still haven't been able to find an answer. I have a forEach loop that I am using to loop through a list of users and retrieving specific location data for each. Inside the forEach the first function call gets the branch then the second gets information on that branch.
The problem is that the forEach loop is not completing prior to returning data from the function, which is causing all sorts of issues.
Here is my code:
//getAllUserData() - this is the function which returns prematurely
const getAllUserData = async () => {
const sequelize = DB.GetDB('mcaintranet');
const userDB = MCAIntranet.initModels(sequelize);
userDB.tblUsers.belongsTo(userDB.tblSMSSent, { foreignKey: 'collector', targetKey: 'user' });
userDB.tblSMSSent.hasMany(userDB.tblUsers);
let users = await userDB.tblUsers.findAll({
attributes: ['collector', 'id'],
include: {
model: userDB.tblSMSSent,
attributes: [[sequelize.fn('COUNT', 'tblSMSSent.id'), 'numMessages']]
},
raw: true,
group: ['collector', 'tblUsers.id'],
})
//return list of all users and texts sent
//UserName, User Province Code, # Messages Sent, user Number
try {
await users.forEach(async user => {
const branch = await Users.getUserBranch(user);
const province = getKey(branch);
user.province = province;
// console.log("User: ", [user, branch])
//clean up JSON from join results
user.numMessages = user["tblSMSSent.numMessages"];
delete user["tblSMSSent.numMessages"];
})
const obj = { 'users': users };
console.log("DONE: ", obj)
return obj;
}
catch (ex) {
console.log("ERROR: ", ex)
const msg = ex.Message;
return { results: "False", message: "SMS.js 61" + msg }; //is user allowed to use SMS page)
}
}
//getUserBranch() - accessor function to return branch number
const getUserBranch = async (user) => {
// console.log("Branch User: ", user)
let branch = getUserProps(user.collector ? user.collector : user, 'branch');
// console.log(props)
if (!branch) branch = 0;
return branch;
}
//getUserProps - pulls all user properties from database and filters as necessary
const getUserProps = async (user, propName = null) => {
let ret = {};
if (user.collector) user = user.collector;
user = user.trim();
let filter = {
collector: user
}
if (propName) {
filter.propertyName = propName
}
// console.log("Filter: ", filter)
const sequelize = DB.GetDB('MCAIntranet');
const propsDB = MCAIntranet.initModels(sequelize);
//get all values contained for user
let props = await propsDB.tblUserProperties.findAll({
attributes: ['id', 'propertyName', 'propertyValue', 'updated'],
where: filter,
order: [['updated', 'DESC']],
})
// console.log("Props: ", props);
let distinctProps = await propsDB.tblUserProperties.findAll({
attributes: ['propertyName'],
DISTINCT: true,
where: filter,
})
//the SMS Credits item is sometimes added as a second row
//so loop through all potential value rows for user
distinctProps.forEach(dr => {
// console.log(dr);
var name = dr.propertyName.toLowerCase();
// console.log("name: ", name)
try {
//get individual values for each property user possesses
let tmpRows = props.filter(row => row.propertyName.toLowerCase() == name);
// console.log("tmpRows: ", tmpRows)
//get the most recent value
let row = tmpRows[tmpRows.length - 1];
var item = row.propertyName.trim();
var value = row.propertyValue.trim();
//add to returned JSON
ret[item] = value;
} catch (ex) {
console.log("USERS.js 157 " + ex.message);
return ({ error: "USERS.js 158" + ex.Message });
}
})
// console.log("Ret: ", ret)
return ret;
}
//getKey() - returns necessary data about the user province
const getKey = (data) => {
let branch;
try {
branch = data.branch ? data.branch : data;
}
catch (ex) {
console.log(data)
console.log(ex)
}
branch = parseInt(branch);
// console.log(branch)
try {
let acctKey = "";
let province = "";
let abbr = "";
// console.log("Branch: ", branch)
switch (branch) {
case 4: //vancouver
case '4':
abbr = "BC";
acctKey = key["BC"];
province = "British Columbia";
break;
case 7: //Montreal
case '7':
abbr = "QC";
acctKey = key["QC"];
province = "Quebec";
break;
case 9: //Toronto
case '9':
abbr = "ON";
acctKey = key["ON"];
province = "Ontario";
break;
default: //Edmonton
abbr = "AB";
acctKey = key["AB"];
province = "Alberta";
break;
}
return { key: acctKey, province: province, abbr: abbr };
}
catch (ex) {
throw ex;
}
}
Somewhere in this conglomeration of awaits and asyncs something is lacking causing the getAllData() function to return user names without the location data. How can I block execution until I have all the data? Please ignore the extraneous awaits I have put in while endeavoring to solve this problem.
Thanks.
Instead of forEach, you want this:
await Promise.all(users.map(async (user) => {...}))
map returns the promise for each inner operation, and await-ing Promise.all waits until all of those promises are finished
This is the code in nodejs:
//Insert an employee
app.post('/employees', (req, res) => {
let emp = req.body;
var sql = "SET #EmpID = ?; SET #Name = ?; SET #EmpCode = ?; SET #Salary = ?; \
CALL EmployeeAddOrEdit(#EmpID,#Name,#EmpCode,#Salary);";
mysqlConnection.query(sql,[emp.EmpID, emp.Name, emp.EmpCode, emp.Salary],(err, rows, fields) => {
if (!err)
rows.forEach(element => {
if (element.constructor == Array)
res.send('Inserted employee id : ' + element[0].EmpID);
});
else
console.log(err);
})
});
I don't know if you will be able to see the image.
In the postman it keeps giving me this message:
Inserted employee id : null
Not getting the id number. In mysql workbench created the db with all the data proper settings, had 4 names, the delete process with postman was successful, but can't simply insert the data
You cannot return more than one response. So you can't use res.send in a loop.
But you can create an array and add all the ids to the array and present them in the response.
//Insert an employee
app.post('/employees', (req, res) => {
let emp = req.body;
var sql = "SET #EmpID = ?; SET #Name = ?; SET #EmpCode = ?; SET #Salary = ?; \
CALL EmployeeAddOrEdit(#EmpID,#Name,#EmpCode,#Salary);";
const container = []; //Create an empty array
mysqlConnection.query(sql, [emp.EmpID, emp.Name, emp.EmpCode, emp.Salary], (err, rows, fields) => {
if (!err) {
rows.forEach(element => {
if (element.constructor == Array)
container.push(row.insertedId); //Push the ids to the array
});
res.send('Inserted employee ids : ' + container.join());
}
else
console.log(err);
})
});
I'm new to Javascript and I have to solve a task for my Homework.
I have to get specific data (album titles and the album IDs) from a Database in one class, return this Data to another class and format it with template literals there.
getAlbums: function (db) {
sql = `SELECT DISTINCT Title, AlbumId FROM albums`;
let title = [], id = [];
db.all(sql, [], (err, rows) => {
if (err) throw err;
rows.forEach((row)=>{
title.push(row.Title);
id.push(row.AlbumId);
});
});
return [title, id];
}
this is the function where I get the data from the database. When I put a console.log(title) inside the db.all function, the titles array is filled correctly. But it does not return this array to the other class, I get an error:
TypeError: Cannot read property 'forEach' of undefined.
If I put a console.log(title) outside the db.all function, it returns an empty array and I don't get an error. The output is just undefined.
The method call in my other class:
showAlbum: function (db) {
let albumID = model.getAlbums(db);
//let album = "";
//let albId = "";
albumID.forEach((element) => {
//album = element.title;
//albId = element.id;
console.log(`Albumtitle: ${element.title} AlbumID: ${element.id}\n`);
});
}
How can I transfer the arrays correctly?
Try changing your JS code to the following.
getAlbums: function (data) {
sql = `SELECT DISTINCT Title, AlbumId FROM albums`;
let title = [], id = [];
data.data.all(sql, [], (err, rows) => {
if (err) throw err;
rows.forEach((row)=>{
title.push(row.Title);
id.push(row.AlbumId);
});
});
return [title, id];
}
then
showAlbum: function (data) {
let albumID = model.getAlbums(data.data);
//let album = "";
//let albId = "";
albumID.forEach((element) => {
//album = element.title;
//albId = element.id;
console.log(`Albumtitle: ${element.title} AlbumID: ${element.id}\n`);
});
}
I have a utility function which pass parameters 'name page callback' to the function. Why not work as i tried so many times?
PLUS: seems 'query.tag_id = name' work for me but why query[name] = name did not work so that i can pass whatever name i like;That's, i want to pass the variable /name/ as the property name so that i can use whatever name i like. For example, i can find posts by user_id when i pass user_id variable as the name value. Also i can find posts by its tag_id when i pass tag_id variable as the name value so it's much more flexible than when i use 'query.user_id = name' to do it ,where the name can only be user_id variable or value
NO LIBRARY USED EXCEPT EXPRESS AND NODEJS WITH CONNECT-FLESH, MONGOOSE ETC.
// post_proxy/post.js
"use strict";
let moment = require('moment'),
Post = require('../models/Post'),
User = require('../models/User'),
Comment = require('../models/Comment'),
postProxy = require('../db_proxy/post'),
tagProxy = require('../db_proxy/tag');
module.exports = {
getTen: (name,page,callback)=>{
var query = {};
//name = query;
if(name){
query[name] = name;
console.log('query[name] is'+ Object.keys(query));
}
Post.count(query, ( err, count)=>{
if (err) {
return callback(err);
}else{
console.log( `Number of posts: ${count} . query is ${query}` );
Post.find(query).skip((page-1)*10).limit(10).sort({created_at: -1}).exec((err,posts)=>{
if (err) {
return callback(err);
}
console.log('Posts inthe getTen function is: '+posts);
const modifiedPosts = posts.map(post=>{
return post.processPost(post);
});
console.log('modifiedPosts: '+modifiedPosts);
callback(null, modifiedPosts, count);//provide the params(caluated values),and what to do? you need to figure it out yourself
});
}
});
}
// controller/post.js:
"use strict";
let moment = require('moment'),
Post = require('../models/Post'),
User = require('../models/User'),
Comment = require('../models/Comment'),
postProxy = require('../db_proxy/post'),
tagProxy = require('../db_proxy/tag');
module.exports = {
getTagsPost: (req,res)=>{
const tag_id = req.params.tag_id;
const page = req.query.p ? parseInt(req.query.p) : 1;
//let loginedUser;
console.log('entering into the tagpost');
postProxy.getTen(tag_id, page, (err, posts, count)=> {
if (err) {
console.log('some error with getting the 10 posts:'+ err);
//next(err);
posts = [];
}
// if(req.user){
// loginedUser = req.user.processUser(req.user);
// }
//userProxy.getUserById(user_id, theuser=>{
console.log('tag posts for'+ tag_id +posts);
res.render('post/tagPosts', {
title: 'specific tag page',
user: req.user ? req.user.processUser(req.user) : req.user,
//postUser: req.user ? (req.user._id == user_id ? loginedUser : theuser) : theuser,
posts: posts,
page: page,
isFirstPage: (page - 1) == 0,
isLastPage: ((page - 1) * 10 + posts.length) == count,
messages: {
error: req.flash('error'),
success: req.flash('success'),
info: req.flash('info'),
}, // get the user out of session and pass to template
});
});
},
...
}
//route:
router.get('/tag/:tag_id', post.getTagsPost);
UPDATE:
Did not find an answer so i change it to the following and solve the problems:
getTen: (name,tag_id,user_id,page,callback)=>{
var query = {};
if(name){
if(user_id){
query.user_id = name;
}else{
query.tag_id = name;
}
console.log('query[name] is'+ Object.keys(query));
}
...
}
UPDATE: Did not find an answer so i change it to the following and solve the problems:
getTen: (name,tag_id,user_id,page,callback)=>{
var query = {};
if(name){
if(user_id){
query.user_id = name;
}else{
query.tag_id = name;
}
console.log('query[name] is'+ Object.keys(query));
}
...
}
I'm trying to $push an item into my record in MongoDB built on Node (using MongoJS), like so:
exports.saveToUser = function (req, res) {
console.log("IN");
var user = req.params.user;
var param = req.params.param; // equals "foo"
var value = req.params.value; // equals "bar"
console.log("Saving Data to User");
console.log(util.inspect(param, false, null));
db.users.update({"_id": ObjectId(user)}, {$push: {param:value}}, function (err, record) {
if (err) {
console.log("Lookup Error: " + err);
} else{
console.log("Updated " + user + " with " + param);
}
});
};
This works, except the function is pushing "param: bar" instead of "foo: bar" to my record (see comments above for what this refers to).
I've tried doing $push: {eval(param):value} which was a bit of a shot in the dark but didn't work anyway. What's the best way to make this happen?
var ob = {};
ob[param] = value;
db.users.update({"_id": ObjectId(user)}, { $push: ob }, function (err, record) {
// etc..
});