How to compare and push field to sub array in object - javascript

I have an object which contain name and id. Second object has some fields and that id field from first object.
For Example:
FirstObj = [{
_id: '48765465f42424',
Name : 'Sample'
},{
_id: '48765465f654654',
Name : 'Sample1'
}]
secondObj = [{
Field1 : 5464,
subarray : [{
Field2 : 14654,
Field3 : { IsActive : true,
FirstObjid : '48765465f42424'
},
Field4 : { IsActive : true,
FirstObjid : '48765465f654654'
}
}]
},
{
Field1 : 2145,
subarray : [{
Field2 : 544644,
Field3 : { IsActive : true,
FirstObjid : '48765465f654654'
},
Field4 : { IsActive : true,
FirstObjid : '48765465f42424'
},
}]
}]
Now I need to compare both and push that name from first object to secondobj's subobj beside FirstObjid field .
Expected Output is :
secondObj = [{
Field1 : 5464,
subarray : [{
Field2 : 14654,
Field3 : { IsActive : true,
FirstObjid : '48765465f42424',
Name : 'Sample'
},
Field4 : { IsActive : true,
FirstObjid : '48765465f654654',
Name : 'Sample1'
}
}]
},
{
Field1 : 2145,
subarray : [{
Field2 : 544644,
Field3 : { IsActive : true,
FirstObjid : '48765465f654654',
Name : 'Sample1'
},
Field4 : { IsActive : true,
FirstObjid : '48765465f42424',
Name : 'Sample'
},
}]
}]
How can I achieve it.

Try this
secondObj.subarray.forEach(function(item){
if(item.FirstObjid==FirstObj._id)
item.Name = FirstObj.Name
})

Use map function and compare the object ids like this
var secondObj = [{
Field1 : 5464,
subarray : [{
Field2 : 14654,
Field3 : 'sfsadf',
FirstObjid : '48765465f42424'
}]
},
{
Field1 : 2145,
subarray : [{
Field2 : 544644,
Field3 : 'awrfsa',
FirstObjid : '48765465f654654'
}]
}]
var FirstObj = [{
_id: '48765465f42424',
Name : 'Sample'
},{
_id: '48765465f654654',
Name : 'Sample1'
}]
secondObj.subarray = secondObj.map(o => o.subarray.map(k=> FirstObj.map(l=> {
if(l._id == k.FirstObjid){
k.Name = l.Name
}
return o;
})))
console.log(secondObj)

Related

How to add attribute to all documents in a collection, with same data of another attribute in MongoDB?

I've seen this question and it could be useful, but I need some extra steps.
I have a collection of Sites filled with name, data and a field called infoBox that is an object.
infoBox: {
coordX: {
type: Number,
},
coordY: {
type: Number,
},
type: {
type: Number,
enum: [InfoBoxType.line, InfoBoxType.horizontal, InfoBoxType.vertical],
},
midPoint: {
coordX: {
type: Number,
},
coordY: {
type: Number,
},
},
So, I need to add another attibute to all infoboxes of the sites called "levels" that is an array, and this field must contains two objects like InfoBox, with the same values, but with empty 'levels'. (both infobox 1 & 2 with same values).This is to initialize the DB, later these values will be editted by the users.
Trying to be clear, I actually have:
Site
data
name
infobox
coordx
coordy
midpoint
coordx
coordy
and I need
Site
data
name
infobox
coordx
coordy
midpoint
coordx
coordy
levels
infobox1
coordx
coordy
midpoint
coordx
coordy
levels(empty)
infobox2
coordx
coordy
midpoint
coordx
coordy
levels(empty)
How can I accomplish this?
Extra info:
Mongo version 4.2
EDIT
I am trying to make it with something like this, but with no luck yet:
let sites = await this.siteModel.find({});
const firstZoom = site.infoBox;
const secondZoom = site.infoBox;
const levelss = [
firstZoom,
secondZoom,
];
await this.siteModel.update({ _id: site._id }, { $set: { 'infoBox.levels.$': levelss } });
On MongoDB v4.2 which supports aggregation pipeline in update operations, you can try this (you can use .updateMany() as well) :
this.siteModel.update({},
[{
$set: {
'infobox.levels': [{ infobox1: { $mergeObjects: ['$infobox', { 'levels': [] }] } },
{ infobox2: { $mergeObjects: ['$infobox', { 'levels': [] }] } }]
}
}], { multi: true })
Ref : .update()
Collection Data :
/* 1 */
{
"_id" : ObjectId("5e4dba9e7f8bc30a75c658fc"),
"data" : 1,
"name" : "noName",
"infobox" : {
"coordx" : 2,
"coordy" : 2,
"midpoint" : {
"coordx" : 1,
"coordy" : 1
}
}
}
/* 2 */
{
"_id" : ObjectId("5e4dbab07f8bc30a75c65ab1"),
"data" : 2,
"name" : "yesName",
"infobox" : {
"coordx" : 4,
"coordy" : 4,
"midpoint" : {
"coordx" : 2,
"coordy" : 2
}
}
}
Docs in DB after update operation :
/* 1 */
{
"_id" : ObjectId("5e4dba9e7f8bc30a75c658fc"),
"data" : 1,
"name" : "noName",
"infobox" : {
"coordx" : 2,
"coordy" : 2,
"midpoint" : {
"coordx" : 1,
"coordy" : 1
},
"levels" : [
{
"infobox1" : {
"coordx" : 2,
"coordy" : 2,
"midpoint" : {
"coordx" : 1,
"coordy" : 1
},
"levels" : []
}
},
{
"infobox2" : {
"coordx" : 2,
"coordy" : 2,
"midpoint" : {
"coordx" : 1,
"coordy" : 1
},
"levels" : []
}
}
]
}
}
/* 2 */
{
"_id" : ObjectId("5e4dbab07f8bc30a75c65ab1"),
"data" : 2,
"name" : "yesName",
"infobox" : {
"coordx" : 4,
"coordy" : 4,
"midpoint" : {
"coordx" : 2,
"coordy" : 2
},
"levels" : [
{
"infobox1" : {
"coordx" : 4,
"coordy" : 4,
"midpoint" : {
"coordx" : 2,
"coordy" : 2
},
"levels" : []
}
},
{
"infobox2" : {
"coordx" : 4,
"coordy" : 4,
"midpoint" : {
"coordx" : 2,
"coordy" : 2
},
"levels" : []
}
}
]
}
}
Just use . to create a new object key.
Site.levels = {}
Site.levels.infobox1 = Site.infobox
Site.levels.infobox2 = Site.infobox

Array missing in react redux reducer

i am trying to check my inner array id same as dispatched id, table example
{
_id :1,
name: sagar elias jacky
Amenities :[{ id: 100, title : hi },{ id: 101, title : hallo } ]
}
checking dispatched id exit or not using map,
return { ...state,
items : {...state.items,
Amenities : { ...state.items.Amenities
.map(x=> x._id === action.dispatchedID ? {...x,deleting: true} : x ) }}}
but it will return with non array Amenities, like
Amenities:
0: { id: 100, title : hi },
1: { id: 101, title : hallo }
i want this to
Amenities:Array(2)
0: { id: 100, title : hi },
1: { id: 101, title : hallo }
When you spread an array inside {}, it creates an object with indexes of array as keys
const array = [{a:1}, {a:2}]
console.log({...array})
So, change
Amenities : { ...state.items.Amenities
.map(x=> x._id === action.dispatchedID ? {...x,deleting: true} : x ) }
to:
Amenities : [ ...state.items.Amenities
.map(x=> x._id === action.dispatchedID ? {...x,deleting: true} : x ) ]

mongoose duplicated key error with empty string

I have a schema like this:
const MemberSchema = mongoose.Schema({
name: {
type: String,
},
email: {
type: String,
unique: true
},
phone: {
type: String,
unique: true
}
})
and of course email and phone needs to be unique but the thing is either email or phone is optional so they can be empty string.
and when you set them as unique index I get this error
E11000 duplicate key error collection: model.members index: email_1 dup key: { : "" }'
Is there any way to add exception to unique?
Edit
I changed my code like below but still doesn't work.
email: {
type: String,
trim: true, index: true, unique: true, sparse: true
},
\
'E11000 duplicate key error collection: email-collector.members index: email_1 dup key:{ : null }'
when I run getIndexes, I get
> db.members.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "email-collector.members"
},
{
"v" : 2,
"unique" : true,
"key" : {
"email" : 1
},
"name" : "email_1",
"ns" : "email-collector.members",
"sparse" : true,
"background" : true
},
{
"v" : 2,
"unique" : true,
"key" : {
"email" : 1,
"phone" : 1
},
"name" : "email_1_phone_1",
"ns" : "email-collector.members",
"sparse" : true
}
]

how to append based on object key

I have an object like this :
Object
section : array (1)
0 : {id : 1, name: 'foo'}
unit : array(2)
0 : {id : 1, name: 'bar'}
1 : {id : 2, name: 'bar2'}
but how to detect if the object has a section key or not ?
my code like this :
$.each(data, function(key,row){
if (row.section) {
$.each(row.section, function(key, val){
$('.select-section').append("<option value='"+val.id+"'>"+val.name+"</option>");
});
}else{
$('.select-section').html("<option value='-'>-</option>");
}
});
but my when i have an object like that above, the results is just replace the section option value with else condition (-)
i create this because sometimes an Object doesn't have a section key, so i create a default option when the section key is unavailable
any help will be appreciated
I changed two things in your JS code:
if (key=="section") instead of if (row.section) to check if the key is section or not;
$('.select-section').append instead of $('.select-section').html cause whatever you could append the html() function will replace the whole html inside the select tag to <option value='-'>-</option>, then you'll never have other option then this one.
Please check this demo for a better understanding:
var object={
section : {
0 : {id : 1, name: 'foo'}
},
unit : {
0 : {id : 1, name: 'bar'},
1 : {id : 2, name: 'bar2'}
}
};
$.each(object, function(key,row){
if (key=="section") {
$.each(row, function(key, val){
var opt="<option value='"+val.id+"'>"+val.name+"</option>";
$(".select-section").append(opt);
});
}else{
$('.select-section').append("<option value='-'>-</option>");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="select-section"></select>
This solution still not perfect because I believe that if you'll have another key that is not section the code above will append one more the selection tag with -;
var object={
section : {
0 : {id : 1, name: 'foo'}
},
unit : {
0 : {id : 1, name: 'bar'},
1 : {id : 2, name: 'bar2'}
},
unit2 : {
0 : {id : 1, name: 'bar'},
1 : {id : 2, name: 'bar2'}
}
};
$.each(object, function(key,row){
if (key=="section") {
$.each(row, function(key, val){
var opt="<option value='"+val.id+"'>"+val.name+"</option>";
$(".select-section").append(opt);
});
}else{
$('.select-section').append("<option value='-'>-</option>");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="select-section"></select>
So I suggest that you append the select tag at the beginning, then there is no need to check if the key is not section. Here is another and better demo :
var object={
section : {
0 : {id : 1, name: 'foo'}
},
unit : {
0 : {id : 1, name: 'bar'},
1 : {id : 2, name: 'bar2'}
},
unit2 : {
0 : {id : 1, name: 'bar'},
1 : {id : 2, name: 'bar2'}
}
};
$('.select-section').append("<option value='-'>-</option>");//APPEND It HERE
$.each(object, function(key,row){
if (key=="section") {
$.each(row, function(key, val){
var opt="<option value='"+val.id+"'>"+val.name+"</option>";
$(".select-section").append(opt);
});
}//NO NEED TO CHECK If It's NOT "SECTION"
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="select-section"></select>
you can just do:
var data = {
section: [{
id: 1,
name: 'foo'
}],
unit: [{
id: 1,
name: 'bar'
}, {
id: 2,
name: 'bar2'
}]
};
if (data.section && data.section.length > 0) {
$.each(data.section, function(key, val){
$('.select-section').append("<option value='"+val.id+"'>"+val.name+"</option>");
});
} else {
$('.select-section').html("<option value='-'>-</option>");
}
plnkr: http://embed.plnkr.co/dxzbHir4x0RjQwQAfse1/

Need clarification angularJs's forEach method

I am new to angular js, and I was trying to get unique values using ng-repeat. I went through many sites for the example , one of them is enter link description here
which I got from stackoverflow only.
var app = angular.module('app', []);
app.filter('unique', function() {
return function(collection, keyname) {
var output = [],
keys = [];
angular.forEach(collection, function(item) {
var key = item[keyname];
if(keys.indexOf(key) === -1) {
keys.push(key);
output.push(item);
}
});
return output;
};
});
app.controller('MyCtrl', function ($scope) {
$scope.items = [
{ id : 1,column : "col1", comment : "col1-label1",
text1 : "col1-label1-text1",
checked: false,
},
{
id : 2,
column : "col1",
comment : "col1-label2",
text1 : "col1-label2-text1",
checked: false,
},
{
id : 3,
column : "col2",
comment : "col2-label1",
text1 : "col2-label1-text1",
checked: false,
},
{
id : 4,
column : "col2",
comment : "col2-label2",
text1 : "col2-label2-text1",
checked: false,
},
{
id : 5,
column : "col3",
comment : "col3-label1",
text1 : "col3-label1-text1",
checked: false,
},
{
id : 6,
column : "col3",
comment : "col3-label2",
text1 : "col3-label2-text1",
checked: false,
},
{
id : 7,
column : "col4",
comment : "col4-label1",
text1 : "col4-label1-text1",
checked: false,
},
{
id : 8,
column : "col4",
comment : "col4-label2",
text1 : "col4-label2-text1",
checked: false,
}
];
});
But I am having problem to understand at one point that I have spent hours on but still couldn't understand.
**angular.forEach(collection, function(item) {
var key = item[keyname];**
In forEach method in the function we pass value , index and then the object itself that we are iterating over, In the above example we are only passing the value as "item" , then in the next line we are using as object/array. I am really confused, what is it? what are they trrying to do

Categories

Resources