how to append based on object key - javascript

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/

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 ) ]

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

How to sort inner array and match elements in mongoose

So I am trying to do a semi-complicated query in mongoose. It is as follows:
Event.findOne({ users: { $elemMatch: { user: someUserId, going: 1 }, sort: {createTime: -1} } }
Basically what I would like to do is find a single Event that has a user in its user array that matches an Id and is attending. I have multiple user records for each user in the user array so I want to find the most recent one, to do this I would like to sort the user array by createTime. This is where the error is coming in and it just returns undefined. It works just fine when I don't include the sort function, is there any way to include that?
Here is what my Event object looks like:
{
_id: 1,
endTime: 1429060173865,
createTime: 1429051773902,
startTime: 1429052973865,
description: 'some desc',
creator: 2,
users:
[ { user: 1,
status: 1,
going: 1,
createTime: 1429051773749,
_id: 552d997d8e923847306e2c21 },
{ user: 1,
status: 1,
going: 1,
createTime: 1429051773922,
_id: 552d997d8e923847306e2c25 },
{ user: 1,
status: 9,
going: 0,
createTime: 1429051773942,
_id: 552d997d8e923847306e2c26 } ],
destroyed: 0 }
Is there any way to make this query entirely in mongoose?
As part of find, MongoDB can't sort an array field of a document. You could define a virtual of Mongoose to return the array in sorted order. You could also maintain the array in sorted order, as shown below:
> db.test.drop()
// note: not in order when inserted
> db.test.insert({ "_id" : 0, "users" : [
{ "user" : 1, "going" : 1, "created" : 22 },
{ "user" : 2, "going" : 1, "created" : 775 },
{ "user" : 1, "going" : 1, "created" : 6432 }
] })
// insert user to array and sort as part of update
> db.test.update({ "_id" : 0 },
{ "$push" : {
"users" : {
"$each" : [{ "user" : 2, "going" : 1, "created" : 5532 }],
"$sort" : { "created" : -1 }
}
} })
> > db.test.findOne()
{
"_id" : 0,
"users" : [
{ "user" : 1, "going" : 1, "created" : 6432 },
{ "user" : 2, "going" : 1, "created" : 5532 },
{ "user" : 2, "going" : 1, "created" : 775 },
{ "user" : 1, "going" : 1, "created" : 22 }
]
}
That way, when you perform your find query, the arrays in the matching documents will already be in the desired order.
Your query is not correctly written. In order to sort you should write it in third argument of find:
Event.findOne(
{ users:
{ $elemMatch: { user: someUserId, going: 1 }}
},
null,
{
sort: {createTime: -1}
},
function(err, event) {
//your event here
});

Dealing with embedded data in ember

Suppose I have a graph (tree, whatever) and the structure in plain JS is like:
var trees = [{
name : 'my tree',
nodes : [
{
id : 0,
name : 'node 0',
type : 'fruit',
connectedTo : [1,2]
},{
id : 1,
name : 'node 1',
type : 'fruit',
connectedTo : [3,4]
},{
id : 2,
name : 'node 2',
type : 'fruit',
connectedTo : []
},{
id : 3,
name : 'node 3',
type : 'non-fruit',
connectedTo : []
},{
id : 4,
name : 'node 4',
type : 'non-fruit',
connectedTo : []
}
]
}]
Now in Ember, it would require me to have a Tree, Node and maybe a type model. No biggie. However, I need the data to be parsed for a tree graph. But when I access the data, it's like a chain of get() and then() calls (relationships are async between models).
this.get('nodes').then(function(nodes){
nodes.forEach(function(node){
node.get('type').then(function(type){
console.log(type.get('type')) // OMG
});
})
});
I was hoping to access them in dot-notation, something like tree.nodes[1].type. Is that possible in Ember? I have read several posts dealing with embedded data, and all they do is normalize external data to Ember models. I don't want that. What I want is to deal with embedded data inside the app.
You could use plainJS objects in Ember without the need to use Ember Data as in this example.
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{model.name}}
{{#each item in model.nodes}}
<li>{{item.id}}</li>
{{#each connectedTo in item.connectedTo}}
{{connectedTo}}
{{/each}}
{{/each}}
</ul>
</script>
Once, you set your model data to your controller content, you could operate with your content as normal ember objects.
App.IndexRoute = Ember.Route.extend({
actions: {
changeValues: function(){
this.controller.set('content.name', 'changed');
this.controller.set('content.nodes.firstObject.id', 7);
}
},
model: function() {
return {
name : 'my tree',
nodes : [
{
id : 0,
name : 'node 0',
type : 'fruit',
connectedTo : [1,2]
},{
id : 1,
name : 'node 1',
type : 'fruit',
connectedTo : [3,4]
},{
id : 2,
name : 'node 2',
type : 'fruit',
connectedTo : []
},{
id : 3,
name : 'node 3',
type : 'non-fruit',
connectedTo : []
},{
id : 4,
name : 'node 4',
type : 'non-fruit',
connectedTo : []
}
]
};
}
});

Categories

Resources