Cannot see a field added on a JSON document with Nodejs and Mongoose - json

if I query MongoDB with a simple query like this using mongoose:
User
.find()
.where('address.loc').near({ center: [lat,lng], maxDistance: 1 })
.exec(function(err, result) {
if (err) {
request.log(['server', 'database', 'error'], 'An error occured during the execution of the query');
}else{
for(var i=0;i<result.length;++i){
result[i]["distance"] = 5;
}
console.log(result[0].distance);
console.log(result[0])
}
});
The first console.log prints : 5
But the second one prints :
{ address: { loc: [ 37.0814402, 15.287517 ], value: 'viale tica' },
tags: [ 'Primi', 'Secondi' ],
__v: 0,
cap: 96100,
ad_number: 15,
business_email: 'prova#provbhifbvvyvg',
_id: 571b3b78249a2e160b4eee3f }
Why this document and the others in the result array are without the field distance?

Because result[0] is a mongoose document object. And when you call console.log(result[0]) the result is converted to the string (with mongoose document toString function). But mongoose document doesn't contain distance field.
To do what you want, you should convert each document to object:
var objects = results.forEach(results, function(res) {
res = res.toObject();
res["distance"] = 5;
return res;
});
console.log(objects[0].distance);
console.log(objects[0]);
http://mongoosejs.com/docs/api.html#document_Document-toObject

Related

How to get data from database in array format using node js and MySql

I am using node.js as server language and Mysql as database so I am running query and getting data from database but is is showing in format like this
[ BinaryRow { name: 'Dheeraj', amount: '77.0000' },
BinaryRow { name: 'Raju', amount: '255.0000' } ]
What I want is
['Dheeraj', 77.0000],
['Raju', 66255.000030],
This what I am doing in my backend (node.js):
My model:
static getChartData(phoneNo, userType) {
let sql = 'select businessname as name,sum(billamt) amount from cashbackdispdets where consphoneno =' + phoneNo + ' group by businessid order by tstime desc limit 10'
return db.execute(sql, [phoneNo]);
My controller:
exports.getColumnChart = function(req, res) {
const phoneNo = req.body.userId
const userType = req.body.userType
console.log(phoneNo)
dashboardModule.getChartData(phoneNo, userType)
.then(([rows]) => {
if (rows.length > 0) {
console.log(rows)
return res.json(rows)
} else {
console.log("error")
return res.status(404).json({ error: 'Phone No. already taken' })
}
})
.catch((error) => {
console.log(error)
return res.status(404).json({ error: 'Something went wrong !!' })
})
}
I am sending this data to Ui and when I am receiving it on UI it is in the form of object inside array which is not the required data type I want
axios().post('/api/v1/Dashboard/DashboardColumnChart',this.form)
.then(res=>{
console.log(res.data)
debugger
this.chartData= res.data
})
The above code consoles on browser like
I am not getting any idea how o do it should I do it with backend or with front end and how
Nodejs will send you a JSON response if you want to change it. It is better to change or maniuplate it in a Front end framework. But if you want to change it in backend as you have asked Make sure that the rows is in the format that you want to recive.
let data = [
{ "name": "Dheeraj", "amount": "77.0000" },
{ "name": "Raju", "amount": "255.0000" }
]
// empty array to store the data
let testData = [];
data.forEach(element => {
testData.push(element.name)
});
You can format it using array.map and Object.values. map functions loops over each element and returns a modified element according to the callback provided. Object.values simply returns all the values of an object in an array.
const data = [ { "name": "Dheeraj", "amount": "77.0000" }, { "name": "Raju", "amount": "255.0000" } ];
const formattedData = data.map(obj => Object.values(obj));
console.log("Initial Data: ", data);
console.log("Formatted Data: ", formattedData);
// Map function example
const a = [1,2,3]
const mappedA = a.map(e => e * 2)
console.log(a, " mapped to: ", mappedA);
// Object.values example
const b = { firstName: 'John', lastName: 'Doe', number: '120120' }
console.log(Object.values(b));

Destructuring array and accessing the first element

I made and API call using fetch to get JSON data. That data is then passed to my function displayCartTotal, which accepts a parameter that uses de-structuring to obtain results.
In displayCartTotal, I want to de-structure the first item into the results array, into a data variable. Next, use object de-structuring to obtain the itemsInCart and buyerCountry properties of the data.
I have tried de-structuring the array, but is not working, also when i do typeof() on the data I receive, I get "object".
Here is format of the JSON data
{
results: [{
itemsInCart: [{
name: "Jolof Rice",
price: 80,
qty: 2
}, {
name: "Jolof Rice",
price: 80,
qty: 2
}],
buyerCountry: "Uganda"
}],
info: {
seed: "85e0e8ca0e095f74",
results: "1",
page: "1",
version: "0.1",
time: {
instruct: 11,
generate: 5
}
}
}
Code:
const displayCartTotal = ({results}) => {
const [data] = results;
const [itemsInCart,buyerCountry] = data;
return results;
};
const fetchBill = () => {
const api = 'https://randomapi.com/api/006b08a801d82d0c9824dcfdfdfa3b3c';
fetch(api)
.then(response => response.json())
.then(data => displayCartTotal(data))
.catch(error => console.error(error));
};
I expect to de-structure the first item in the results array into a data variable. And also to use object de-structuring to obtain the itemsInCart and buyerCountry properties of data.
Have you tried placing the nth position of the object
const displayCartTotal= ({results})=>{
const {0: data} = results;
const {itemsInCart, buyerCountry} = data;
}

MongooseError: Cast to ObjectID failed for value on reading json for db seed

I have a model scheme with a reference field like this:
const UserSchema = new mongoose.Schema({
// ...
uf:{
type: mongoose.Schema.Types.ObjectId, ref: 'UF', index: true
},
});
And my test db seed code is consuming data from json files, like this:
[
{ "_id": 91283,
"name":"Test user",
"uf": 124411923,
"version": 2
}
]
During in the seed process, after the model save method, I’m getting this error:
ValidationError: User validation failed: uf: Cast to ObjectID failed for value "124411923" at path "uf"
errors:
{ uf:
{ MongooseError: Cast to ObjectID failed for value "124411923" at path "uf"
This is code responsible for loading the jsons and saving to the database, I've sorted the seed list so that UF is inserted first:
function seed() {
console.log('Starting db seed...');
return Promise.each(initialData, (data) => {
// path to mongo model js file
let Model = require(data.model);
removeModel(Model)
.then(() => {
console.log('[' + data.name + '] model removed. ');
return saveModel(data, Model);
}).then(() => {
console.log('[' + data.name + '] model saved');
}).catch( (err) => {
console.error('Error seeding db', err);
});
});
}
/**
* Saves model to the database
* #param {*} data
* #param {*} Model
*/
function saveModel(data, Model) {
// path to json data file
let seedList = require(data.seed);
return Promise.map(seedList, function(seed) {
let newItem = new Model(seed);
return newItem.save({});
});
}
Can anyone help?
In your user document, you are not including a valid ObjectId, hence the error when you try to store as type ObjectId.
Refs can only defence the _id field from other collections.
Therefore, in your user document, you will need to include a reference to the _id field from the UF collection:
[
{
"_id": 91283,
"name":"Test user",
"uf": [_id from UF here],
"version": 2
}
]
NOTE: If you have explicitly defined the _id field in your UF schema as type Number, then you can reference that from your user schema by matching types:
const UserSchema = new mongoose.Schema({
// ...
uf: {
type: Number, ref: 'UF', index: true
},
});
It seems you don't have a valid ObjectId string. Try using 123456789012 as it's a 12 bytes string.

mongodb + nodejs to find and return specific fields in documents

I'm trying to extract specific document fields from a mongodb collection (v 3.0.8 at MongoLab). The returned documents must fall within a date range. My goal is to extract specific fields from these documents. My nodejs code,
var query = {}, operator1 = {}, operator2 = {}, operator3 = {} ;
operator1.$gte = +startDate;
operator2.$lte = +endDate;
operator3.$ne = 'move';
query['xid'] = 1; // Problem here?
query['date'] = Object.assign(operator1, operator2);
query['type'] = operator3;
console.log(query);
MongoClient.connect(connection, function(err, db) {
if(err){
res.send(err);
} else {
db.collection('jbone')
.find(query)
.toArray(function(err, result){
console.log(err);
res.json(result);
});
};
});
If I opt to return all fields in the date range, the query works fine. If I select only field xid I get no results. My query object looks sensible according to the docs. console.log(err) gives:
{ xid: 1,
date: { '$gte': 20160101, '$lte': 20160107 },
type: { '$ne': 'move' } }
null
null is the err.
Can anyone help me understand what I'm doing wrong?
Or point me to another similar SO questions with an answer?
Thanks
To select the specific field could be done as below
.find(
{date: { '$gte': 20160101, '$lte': 20160107 }, type: { '$ne': 'move' }},
{ xid: 1} )
Sample codes as following.
query['date'] = Object.assign(operator1, operator2);
query['type'] = operator3;
db.collection('jbone')
.find(query, {xid: 1})
.toArray(function(err, result){
console.log(err);
res.json(result);
});

Parsing doubly nested JSON object to MongoDB

Schema for my MongoDB model:
var resultsSchema = new mongoose.Schema({
start_date: String,
end_date: String,
matches:[{
id:Number,
match_date:String,
status:String,
timer:Number,
time:String,
hometeam_id:Number,
hometeam_name:String,
hometeam_score:Number,
awayteam_id:Number,
awayteam_name:String,
awayteam_score:Number,
ht_score:String,
ft_score:String,
et_score:String,
match_events:[{
id:Number,
type:String,
minute:Number,
team:String,
player_name:String,
player_id:Number,
result:String
}]
}]
});
Example of JSON data coming from the server:
"matches":
[
{
"match_id":"1234"
"match_date":"Aug 30"
...
...
"match_events":
[
{
"event_id":"234",
"event_minute":"38",
...,
...
},
{
"event_id":"2334",
"event_minute":"40",
...,
...
}
],
{
"match_id":"454222"
"match_date":"Aug 3"
...
...
"match_events":
[
{
"event_id":"234",
"event_minute":"38",
...,
...
},
....
My current implementation works for parsing just the matches (i.e the first array). But I can't seem to access the inner array properly.
async.waterfall([
function(callback) {
request.get('http://football-api.com/api/?Action=fixtures&APIKey=' + apiKey + '&comp_id=' + compId +
'&&from_date=' + lastWeek_string + '&&to_date=' + today_string, function(error, response, body) {
if (error) return next(error);
var parsedJSON = JSON.parse(body);
var matches = parsedJSON.matches;
var events = parsedJSON.matches.match_events;
var results = new Results({
start_date: lastWeek_string,
end_date: today_string,
matches:[]
});
_.each(matches, function(match) {
results.matches.push({
id: match.match_id,
match_date: match.match_formatted_date,
status:match.match_status,
timer:match.match_timer,
hometeam_id:match.match_localteam_id,
hometeam_name:match.match_localteam_name,
hometeam_score:match.match_localteam_score,
awayteam_id:match.match_visitorteam_id,
awayteam_name:match.match_visitorteam_name,
awayteam_score:match.match_visitorteam_score,
ht_score:match.match_ht_score,
ft_score:match.match_ft_score,
et_score:match.match_et_score,
match_events:[]
});
});
_.each(events, function(event) {
results.matches.match_events.push({
id:event.event_id,
type:event.event_type,
minute:event.event_minute,
team:event.event_team,
player_name:event.event_player,
player_id:event.event_player_id,
result:event.event_result
});
});
I understand that the second _.each loop should be iterating for every match, since very match has it's own events subarray. I'm just not sure how to structure this and have been struggling with it for a while.
I tried nesting that loop inside the _.each(matches, function(match) { loop but that didn't work.
Thank you.
Edit: How could I get this to work?
var results = new Results({
start_date: lastWeek_string,
end_date: today_string,
matches:[
match_events: []
]
});
Because then as #zangw says I could construct the match_events array first, append it to matches, and so on.