I am trying to generate an object via a for loop, the problem I am having is that the property name is not being generated instead it is just inserted as the variable name.
Here is an example:
for (let key in person) {
let obj = {key : person[key] };
console.log(obj);
}
If you run this it prints
{ key : "smith" }
The desired object would be
{ name : "smith" }
any ideas on how to achieve this? thank you in advanced.
What you want is :
const person = {
age: 18,
size: '1m74',
eyeColor: 'blue',
};
for (let key in person) {
const obj = {
[key] : person[key],
};
console.log(obj);
}
Look at here for explainations
Example with Array.forEach and Object.keys
const person = {
age: 18,
size: '1m74',
eyeColor: 'blue',
};
Object.keys(person).forEach((x) => {
const obj = {
[x]: person[x],
};
console.log(obj);
});
You can achieve using
for (let key in person) {
const obj = {};
obj[key] = person[key];
console.log(obj);
}
You can do this by :
obj = {name: person[key] }
Related
I have this array list of objects.
var list = [{
'ID':1,
'name' : 'Vikas Yadav',
'mobile':8095638475,
'sent':false
},
{
'ID':2,
'name' : 'Rajat Shukla',
'mobile':7486903546,
'sent':false
},
{
'ID':3,
'name' : 'Munna Bhaiya',
'mobile':9056284550,
'sent':false
},
{
'ID':4,
'name' : 'Guddu Pandit',
'mobile':7780543209,
'sent':false
},
{
'ID':5,
'name' : 'Srivani Iyer',
'mobile':8880976501,
'sent':false
}];
Now I want to push two more datas in specific element of this array via forLoop as:
var timeAndOTPArray = {
"time" : new Date(),
"OTP": req.params.ran
}
I am retrieving the list data via cookies into one of the route.
Below is the code I am trying to push the element according to the matching condition.
var lists = req.cookies.list;
Object.keys(lists).forEach(function(item) {
if(req.params.ID == lists[item].ID){ //look for match with name
(lists[item]).push(timeAndOTPArray);
newAddedList.push(lists[item]);
console.log(item, lists[item]);
}
});
Perhaps it's not the correct way. Please help!
Wish you a happy and a prosperous Diwali.
Cheers!
You can use findIndex and append to update the object into list like this:
//List only with ID, easier to read the code
var list = [{'ID':1,},{'ID':2,}]
//your object
var timeAndOTPArray = {
"time" : new Date(),
"OTP": "otp"
}
//Index where object with ID == 2 is
var index = list.findIndex(obj => obj.ID == 2);
//Append the 'timeAndOTPArray' properties into the object itself
list[index] = {"time": timeAndOTPArray.time, "OTP":timeAndOTPArray.OTP, ...list[index]}
console.log(list)
I guess this will help
var lists = req.cookies.list;
Object.keys(lists).forEach(function(item) {
if(req.params.ID == lists[item].ID){ //look for match with ID
Object.keys(timeAndOTPArray).forEach(key=>{
lists[item][key]=timeAndOTPArray[key];
})
}
});
Good evening) I can advice you the best option is update with map
const listItems = [
{
ID: 1,
name: 'Vikas Yadav',
mobile: 8095638475,
sent: false,
},
{
ID: 2,
name: 'Rajat Shukla',
mobile: 7486903546,
sent: false,
},
{
ID: 3,
name: 'Munna Bhaiya',
mobile: 9056284550,
sent: false,
},
{
ID: 4,
name: 'Guddu Pandit',
mobile: 7780543209,
sent: false,
},
{
ID: 5,
name: 'Srivani Iyer',
mobile: 8880976501,
sent: false,
},
];
const paramId = 4;
const result = listItems.map((item) => {
if (paramId === item.ID) {
return {
...item,
time: new Date(),
OTP: 'smth',
};
}
return item;
});
console.log('result', result);
for appending, you can do this,
lists[index] = Object.assign(lists[index], timeAndOTPArray);
If you are using es6,
lists[index] = {...lists[index], timeAndOTPArray};
Here lists is an array of objects.
so lists[item] is an object, so you cant push an object to an object.
In your code timeAndOTPArray is an object.
In your lists object, initialize an empty array called timeAndOTPArray
var index = lists.findIndex(function(item){ return item.ID == req.params.ID});
lists[index].timeAndOTPArray.push(timeAndOTPArray);
So I will be constantly retrieving an object with the following format:
student: {
"student_id": "12345",
"location": "below",
},
]
},
]
Thank you and will accept answer and upvote!
Something like this should do the trick:
var students = [];
function addStudent(student) {
// Check if we already know about this student.
var existingRecord = students.find(function (s) {
return s.student_id === student.student_id;
});
var classInfo = {
class_number: student.class_number,
location: student.location
};
if (!existingRecord) {
// This is the first record for this student so we construct
// the complete record and add it.
students.push({
student_id: student.student_id,
classes: [classInfo]
});
return;
}
// Add to the existing student's classes.
existingRecord.classes.push(classInfo);
}
You would then invoke it as follows:
addStudent({
"student_id": "67890",
"class_number": "abcd",
"location": "below",
});
Runnable JSBin example available here.
More available on Array.prototype.find at MDN.
This problem can be solved using indexing by student_id. For example:
var sourceArray = [{...}, {...}, ...];
var result = {};
sourceArray.forEach(function(student){
var classInfo = {
class_number: student.class_number,
location : student.location
};
if(result[student.student_id]){
result[student.student_id].classes.push(classInfo);
} else {
result[student.student_id] = {
student_id : student.student_id,
classes : [classInfo]
}
}
});
// Strip keys: convert to plain array
var resultArray = [];
for (key in result) {
resultArray.push(result[key]);
}
You can use also result format that contains objects, indexed by student_id or plain array resultArray.
When working with nodejs, I like to use console.log to see what data is available in an object.
However, this doesn't work with inherited properties:
var Person = function () {};
Person.prototype.name = "anonymous";
var p = new Person();
console.log(['p', p]); // [ 'p', {} ]
// This doesn't even give me a hint that it's inherited from Person!
console.log(['typeof p', typeof p]); // [ 'typeof p', 'object' ]
console.log(['p.name', p.name]); // "anonymous"
Given an object, how can view all the properties I can access?
If your purpose is just for debugging, you can check the __proto__ object:
function Person() {};
Person.prototype.name = "abc";
Person.prototype.smallObj = {
name: "abc"
};
Person.prototype.deepObj = {
one: {
two: {
three: {
four: "4"
}
}
}
};
var p = new Person();
console.log(p);
// Person {}
console.log(p.__proto__);
/*
Person {
name: 'abc',
smallObj: { name: 'abc' },
deepObj: { one: { two: [Object] } }
}
*/
var util = require("util");
console.log(util.inspect(p.__proto__, {depth: null}));
/*
Person {
name: 'abc',
smallObj: { name: 'abc' },
deepObj: { one: { two: { three: { four: '4' } } } }
}
*/
On the last one, using util.inspect() with the depth option will allow you to look further into deeply nested objects.
You are assigning property to constructor function Person. It does not share properties with instances. You need to add property to Person's prototype:
Person.prototype.name = "anonymous";
To find out if your object inherited from Person you can do:
p instanceof Person; // true
You can print out all of an object's enumerable properties by performing the following:
for (var key in p) {
console.log(key);
}
Use Object.getOwnPropertyNames() to get all properties that belong to an object:
console.log(Object.getOwnPropertyNames(Person))
// [ 'length', 'name', 'arguments', 'caller', 'prototype' ]
console.log(Object.getOwnPropertyNames(Object))
// ['length','name','arguments','caller','prototype','keys','create', 'defineProperty','defineProperties','freeze','getPrototypeOf','setPrototypeOf','getOwnPropertyDescriptor','getOwnPropertyNames','is','isExtensible','isFrozen','isSealed','preventExtensions','seal','getOwnPropertySymbols','deliverChangeRecords','getNotifier','observe','unobserve','assign' ]
Also you can combine Object.getOwnPropertyNames() with walking up the prototype chain:
var getAllProperties = function (object) {
var properties = []
do {
Object.getOwnPropertyNames(object).forEach((prop) => {
if (!~properties.indexOf(prop)) {
properties.push(prop)
}
})
} while (object = Object.getPrototypeOf(object))
return properties
}
I want to add a new field with a variable name to an object in the DB : meaning, I don't know the name of the field, but it's held in a variable "newFieldName".
So what I want to do is basically this:
var newFieldName = "world";
db.bios.update(
{ _id: 3 },
{ $set: {
"hello."+newFieldName: "Amazing Grace"
}
}
)
After the update, I expect the object "hello" to have a field "world" with the value "Amazing Grace".
but this doesn't even compile, let alone work. How can I do it?
You can use an intermediary object:
var update = { $set : {} };
update.$set['hello.' + newFieldName] = 'Amazing Grace';
db.bios.update({ _id : 3 }, update, ...)
var some_object = Posts.findOne({...});
var new_value = 1337;
Posts.update(another_object._id,
{$set: {
[some_object.some_field]:new_value,
}
}
);
To answer #yossale & #robertklep, the inline version is in fact possible using an expression and the comma operator:
var newFieldName = "world", o;
db.bios.update(
{ _id: 3 },
{$set:(o = {}, o["hello."+newFieldName] = "Amazing Grace", o)}
)
Simple is that:
var newFieldName = "world";
db.bios.update(
{ _id: 3 },
{ $set: {
["hello."+newFieldName]: "Amazing Grace"
}
}
);
#Andy's answer solved my problem.
When I run mongo db I get this :
$ ./mongo db
MongoDB shell version: 2.4.2
connecting to: db
Server has startup warnings:
** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000
Mon Apr 22 19:25:54.938 [initandlisten] Index { v: 1, key: { type: "text", color: "text", category_A: "text", category_B: "text", category_C: "text" }, ns: "db.items", name: "type_text_color_text_category_A_text_category_B_text_category_C_text", sparse: false, background: false } claims to be of type 'text', which is either invalid or did not exist before v2.4. See the upgrade section: http://dochub.mongodb.org/core/upgrade-2.4
> db.adminCommand( { setParameter : 1, textSearchEnabled : true } )
{ "was" : false, "ok" : 1 }
> db.runCommand("text",{search:"le"})
{
"errmsg" : "exception: wrong type for field (text) 1 != 2",
"code" : 13111,
"ok" : 0
}
when I run the following code with nodejs I get -
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var Items = new Schema({
type : { type : String , default:""},
color : { type : [String] , default:""},
category_A : { type : String , default:""},
category_B : { type : String , default:""},
category_C : { type : String , default:""},
});
var textSearch = require("mongoose-text-search");
var ItemModel = mongoose.model('Item', Items);
Items.plugin(textSearch);
Items.index({
type :"text",
color :"text",
category_A :"text",
category_B :"text",
category_C :"text"
},
{
name: "best_match_index",
weights: {
type: 5,
color: 4,
}
}
)
ItemModel.textSearch('D', function (err, output) {
if (err)
console.log(err);
else
console.log(output)
})
running this I get :
ItemModel.textSearch('D', function (err, output) {
^
TypeError: Object function model() {
Model.apply(this, arguments);
} has no method 'textSearch'
Having a same issue here.
I resolved it by applying code from /mongoose-text-search/lib/index.js
YOURSCHEMA.statics.textSearch = function (search, o, cb) {
if ('function' == typeof o) cb = o, o = {};
if ('function' != typeof cb) {
throw new TypeError('textSearch: callback is required');
}
var model = this;
var lean = !! o.lean;
// mongodb commands require property order :(
// text must be first
var cmd = {};
cmd.text = o.text || this.collection.name;
cmd.search = search;
var keys = Object.keys(o);
var i = keys.length;
while (i--) {
var key = keys[i];
switch (key) {
case 'text':
// fall through
case 'lean':
continue;
case 'filter':
cmd.filter = model.find(o.filter).cast(model);
break;
case 'project':
// cast and apply default schema field selection
var query = model.find().select(o.project);
query._applyPaths();
var fields = query._castFields(query._fields);
if (fields instanceof Error) return cb(fields);
cmd.project = fields;
break;
default:
cmd[key] = o[key];
}
}
this.db.db.command(cmd, function (err, res) {
if (err) return cb(err, res);
if (res.errmsg) return cb(new Error(res.errmsg));
if (!lean && Array.isArray(res.results)) {
// convert results to documents
res.results.forEach(function (doc) {
if (!doc.obj) return;
var d = new model(undefined, undefined, true);
d.init(doc.obj);
doc.obj = d;
})
}
cb(err, res);
});
}
}
to my local schema file
One thing to double-check is that you're not overriding the statics property after you've applied the plugin. This is what was causing the problem for me.
mySchema.plugin(textSearch);
mySchema.index({ name: 'text' });
...
mySchema.statics = { ... }