I'm encountering few problems when dealing with mongoose.
I wrote the following snippet of code:
if (!usr.settings) usr.settings = {};
async.forEach(Object.keys(params), function (item, nextitem){
usr.settings[item] = params[item];
nextitem();
}, function (err) {
if (err) return callback(err);
usr.save(function(err) {
if (err) return callback(err);
return callback();
});
});
When I first use it, it works just fine, it creates all the items in the document perfectly, but when I use it the 2nd time (lets say I want to update those items) it doesn't change their values nor gives me any error.
The data stays just the same.
I tried to debug it.
if (!usr.settings) usr.settings = {};
async.forEach(Object.keys(params), function (item, nextitem){
usr.settings[item] = params[item];
nextitem();
}, function (err) {
if (err) return callback(err);
usr.save(function(err) {
console.log(usr); <------------------- [At this point it shows the updated data but for some reason it doesnt save it to the db]
if (err) return callback(err);
return callback();
});
});
Any idea why it could happen?
Thanks.
After messing with it, found the solution.
lets say you are using the following schema:
user_schema = {
settings = Object
}
you won't be able to set setting., therefore the following code:
usr.settings.something = 123;
usr.save(function(err) {
if (err) return callback(err);
return callback();
});
will do nothing and still will not result in an error.
If you want to fix the issue, apply this fix to the schema:
user_schema = {
settings = {
something : Number
something_else: Object
}
}
now you will be able to set something with a value :)
I wish it would helpful to someone
Related
I am retrieving an object with a database call, I want to access a key's value by matching that key with a variable that I have.
In my database return I get an object that looks similar to this:
{"_id":"5c840d548a7db8af2f9eefea",
"domain":"chatbotdemo.com","deliveryTime":"ba",
"emailAddress":"ab","freeDelivery":"ab","onSale":"ab"}
I have a variable:
var intent = 'emailAddress'
The variable should always exist but theres a very slight chance it may not
and it may also be null.
What I want to do is access the value from that key field that matches the var intent, or at least get the key value pair.
What I also want to do is then if it is null then call an error, my full code is below:
getClientsDialog: function (domain, intent, callback) {
MongoClient.connect('mongodb://111011001101101', function (err, client) {
if (err) throw err;
var db = client.db('10001101');
db.collection('dialog').findOne({ domain: domain}, function (err, doc) {
// here I would want to say if (!err && ****logic to check match****)
if (!err) {
callback(doc)
} else {
throw err;
callback(err)
}
client.close();
});
console.dir("Called findOne");
});
}
Any help would be greatly appreciated!
Thanks!!
Not sure if i got the problem right but in ES6 you can use a computed value as an property name. Something like this:
let serverJson = {
"_id":"5c840d548a7db8af2f9eefea",
"domain":"chatbotdemo.com","deliveryTime":"ba",
"emailAddress":"ab","freeDelivery":"ab","onSale":"ab"
};
let intent = "emailAddress";
if (serverJson[intent]!== undefined) {
}
else {
}
I'm building a program that queries MySQL databases, gets the tables, fields, field data types, and entries and returns it as a single object to be later used to view the MySQL data as a table.
This is what the built object will look like:
{
`Table_Name`: {
Title: `Table_Name`,
Fields: {
`Field Name`: `Datatype`
},
RowData: []
}
}
The query to get the tables is fine, however the query to get the row data isn't. The query function looks like this:
function getRows(){
let secondpromises = [];
secondpromises.push(
new Promise((resolve, reject) => {
for(x in Tables){
Connect_SQL(SQLcreds, w_newSconn, (conn) => {
conn.query(`SELECT * FROM ${Tables[x]}`, (err, results) => {
if(err){
console.log(err);
reject(err);
}else{
for(r in results){
Tables[`${Tables[x].Title}`].RowData.push(results[r]);
}
resolve(results);
}
});
});
if(x == Tables.length - 1){
Promise.all(secondpromises).then(() => {
if(w_newSconn){
w_newSconn.close();
w_newSconn = null;
}
console.log(Tables);
});
}
}
})
);
}
The error is coming from conn.query(). It is throwing an error stating there is an error in my SQL syntax at:
SELECT * FROM [object Object]
I understand the reason why and I'm sure there is a way to resolve this through JSON.Stringify() but there must be a simpler way. I have already tried creating a variable like so:
let objArray = Object.keys(Tables)
But it still returned [object Object], any help would be appreciated.
Tables[x] is an object. You need to get the table name from it.
conn.query(`SELECT * FROM ${Tables[x].Title}`, (err, results) => {
It also looks like the property name is the same as the title, so you can do:
conn.query(`SELECT * FROM ${x}`, (err, results) => {
I ended up creating a variable in the loop
let table = keys[x]
and that did the trick, for whatever reason ${keys[x]} was returning undefined but the variable returned the table name. Theoretically I could have changed the for loops to a
for(x in Tables)
and x would have returned the title so I may go back and rewrite it that way. Thank you.
I have a records of 15K in my collection with min 40 fields, I created a table which is generated from records. In this table i have various fileds as shown in image(from Excel sheet).
/client/main.js
Template.GetTable.helpers({
'getTotalData':function(key1,key2){
console.log("-------inside totalData()---------");
const projects1 = Template.instance().distinct1.get();
var filter1= _.map(projects1, col_8 => {
return {col_8};
});
q={};
p={};
console.log(filter1);
console.log(JSON.stringify(q));
//var queryData=test.find(q).fetch();
Meteor.call('getCountData',"all",function(err,count){
if(err)
console.log("Failed to call meteor..!");
else{
console.log(count);
return count;
}
});
},
});
/server/main.js
Meteor.methods({
'getCountData':function(type){
return test.find({"col_17" : " Query->:#####->x","col_8": { $regex: /^CQI?/i}}).count();
},
});
I was just testing for testing and i know how to get the count from DB.
My problem is after all the rendering and the helpers are called the UI will load without any count data. But when i checked in debugger i got the right counts printed using "console.log()" and the UI is not updated.
How can i resolve this issue? or is there any efficient way to solve this?
The UI problem is that you're doing a Meteor calling inside a helper and returning the result of the call to itself, not the helper.
Here's an example of what you're doing and what you SHOULD be doing.
SHOULD NOT:
Template.GetTable.helpers({
'getTotalData':function(key1,key2){
Meteor.call('getCountData',"all",function(err,count){
if(err)
console.log("Failed to call meteor..!");
else {
return count; // Being returned to this function, not helper fuction
}
});
},
});
SHOULD:
var recVar = new ReactiveVar(false);
Template.GetTable.onCreated({
Meteor.call('getCountData',"all",function(err,count){
if(err)
console.log("Failed to call meteor..!");
else {
recVar.set(count);
}
});
});
Template.GetTable.helpers({
'getTotalData':function(key1,key2){
return recVar.get();
},
});
I did a couple of projects with node.js and I'm aware of the async behaviour and that one should usually use callback functions, etc. But one thing that bothers me ist the following.
I'm developing an Alexa skill and I have a function that handles the User intent:
'MyFunction': function() {
var toSay = ""; // Holds info what Alexa says
// Lot of checks and calculations what needs to be said by Alexa (nothing special)
if(xyz) {
toSay = "XYZ";
}else if(abc) {
toSay = "ABC";
}else{
toSay = "Something";
}
// Here is the "tricky" party
if(someSpecialEvent) {
toSay += " "+askDatabaseForInput(); // Add some information from database to string
}
this.emit(':ask', toSay, this.t('REPROMT_SPEECH')); // Gives the Info to Alexa (code execution stops here)
}
As mentioned in the code, there is some code which is usually used to find out what the output to Alexa should be.
Only on rare events, "someSpecialEvent", I need to query the database and add information to the String "toSay".
Querying the DB would look something like:
function askDatabaseForInput() { // The function to query the DB
var params = {
TableName: "MyTable",
OtherValues: "..."
};
// Do the Query
docClient.query(params, function(err, data) {
// Of course here are some checks if everything worked, etc.
var item = data.Items[0];
return item; // Item SHOULD be returned
});
return infoFromDocClient; // Which is, of course not possible
}
Now I know, that in the first function "'MyFunction'" I could just pass the variable "toSay" down to the DB Function and then to the DB Query and if everything is fine, I would do the "this.emit()" in the DB Query function. But for me, this looks very dirty and not much reusable.
So is there a way I can use "askDatabaseForInput()" to return DB information and just add it to a String? This means making the asynchronous call synchronous.
Making a synchronous call wouldn't affect the user experience, as the code isn't doing anything else anyway and it just creates the String and is (maybe) waiting for DB input.
Thanks for any help.
So you could do 2 things:
Like the person who commented says you could use a callback:
function askDatabaseForInput(callback) {
var params = {
TableName: "MyTable",
OtherValues: "..."
};
docClient.query(params, function(err, data) {
if (err) {
callback(err, null)
} else {
var item = data.Items[0];
callback(null, item);
}
});
}
or you could use promises:
function askDatabaseForInput() {
var params = {
TableName: "MyTable",
OtherValues: "..."
};
return new Promise(function (resolve, reject) {
docClient.query(params, function(err, data) {
if (err) {
reject(err)
} else {
var item = data.Items[0];
resolve(item);
}
});
});
}
you can then either put a function in where you call askDatabaseForInput or do askDatabaseForInput.then(....).
In the function or the .then you would add what you retrieved from the database to the variable toSay
hope this helps
I am trying to do maths on a number within a JSON object (the price of a stock ticker).
I want it to be a variable called 'btcusd_price', that I can then use to do arithmetic with.
How do I get a variable i can work with?
https://tonicdev.com/npm/bitfinex
var Bitfinex = require('bitfinex');
var bitfinex = new Bitfinex('your_key', 'your_secret');
var btcusd_price;
btcusd_price = bitfinex.ticker("btcusd", function(err, data) {
if(err) {
console.log('Error');
return;
}
console.log(data.last_price);
return data.last_price;
});
typeof btcusd_price;
console.log(btcusd_price); //i'm trying to work with the price, but it seems to be 'undefined'?
You have to set the values when they are available, the code is async and you were using the value before it is applied to btcusd_price. Note that the proper way to use the variable is when the callback executes its code.
Please, see the working code below:
Bitfinex = require('bitfinex');
var bitfinex = new Bitfinex('your_key', 'your_secret');
var btcusd_price;
bitfinex.ticker("btcusd", function(err, data) {
if(err) {
console.log('Error');
return;
}
btcusd_price = data.last_price;
console.log(typeof btcusd_price);
console.log(btcusd_price);
});