I have an object like this:
The thing I want to do is to rename the services.XXX value but keep his child properties.
For example I want to rename object.services.cadvisor with object.services.new-name
How can I do that ?
You can do the following
object.services.newName = object.services.cadvisor;
delete object.services.cadvisor
Copy the object to the new property and delete the old one
let myObj = {
services: {
cadvisor : {
name: 'Cadivsor',
length: 50,
nestedObject : {
name: 'Nested'
}
},
other : {}
}
};
myObj.services['newName'] = myObj.services.cadvisor;
delete myObj.services.cadvisor;
console.log(myObj);
Related
I have a nested object like so:
var depositOptions = {
0 : {name: 'Monthly'},
1 : {name : 'Standard'},
2 : {name: 'Full' },
3 : {name: 'Low' }
};
I need to remove the object where name = 'Standard' so I'm iterating over it using Underscore.js _.each until I find it, and storing the index.
_.each(depositOptions, function(option, i) {
if (option.name === 'Standard') {
// delete the object at index i
console.log(i)
}
});
So I want to remove the option when it finds standard - what is the easiest way to do this?
1) Remove it inside the _.each loop, when standard is found? (Therefore no need for the index)
2) Store the index of the object I want to remove, and then delete it after I've finished iterating? (This I am finding difficult because how do I get the index outside of the loop?)
3) Start creating a new array as I iterate over depositOptions so that a new array is built without standard included
When I say I want to delete it, I want it completely gone. So not just undefined like using delete does.
Use _.filter or _.reject instead. It wouldn't be clear to use _.each. Notice that these return a new array.
var newArray = _.filter(depositOptions, function(option) {
return option.name !== 'Standard';
});
Also it looks like you have an object, not an array. Here is an array:
var depositOptions = [
{name: 'Monthly'},
{name : 'Standard'},
{name: 'Full' },
{name: 'Low' }
];
You can use the _.without function to eliminate the key which you don't need
var depositOptions = {
0 : {name: 'Monthly'},
1 : {name : 'Standard'},
2 : {name: 'Full' },
3 : {name: 'Low' }
};
depositOptions = _.without(depositOptions, _.findWhere(depositOptions, {
name: 'Standard'
}));
console.log(depositOptions);
Hope this helps!.
If you want to return new object with filtered properties you can use Object.keys() and reduce() in plain javascript.
var depositOptions = {
0 : {name: 'Monthly'},
1 : {name : 'Standard'},
2 : {name: 'Full' },
3 : {name: 'Low' }
};
var result = Object.keys(depositOptions).reduce(function(r, k) {
if (depositOptions[k].name != 'Standard') r[k] = depositOptions[k]
return r;
}, {})
console.log(result)
According to me the best way to do that using underscore is _reject.
Usage -
_.reject(depositOptions, function(val){ return val.name == 'Standard'; });
Option 3 is definitely not an option because you using exclusion method, where you are trying to fetch all other elements apart from the one you want & make use of the element you want. Too dirty for your implementation!
Option 2 is better than option 3 but not ideal because you have found the element & your still wasting your time iterating over others
Option 1 with a tweak is the best solution from the options given - small tweak includes add a break statement within the if statement & after you store the element. This way your just iterating till you find the element.
You have 2 options, you either mutate your original object or you create a new object without the unwanted key-value pair. All examples are in plain ES6, but you can easily use lodash methods. They will exclude all matches not just the first match.
Mutation. Uses for..of and Object.keys
const depositOptions = {
0: {
name: 'Monthly'
},
1: {
name: 'Standard'
},
2: {
name: 'Full'
},
3: {
name: 'Low'
}
};
for (let key of Object.keys(depositOptions)) {
if (depositOptions[key].name === 'Standard') {
delete depositOptions[key];
}
}
console.log(depositOptions);
Create new object without the reference to the unwanted object.
const depositOptions = {
0: {
name: 'Monthly'
},
1: {
name: 'Standard'
},
2: {
name: 'Full'
},
3: {
name: 'Low'
}
};
const depositOptionsFiltered = {};
for (let key of Object.keys(depositOptions)) {
if (depositOptions[key].name !== 'Standard') {
depositOptionsFiltered[key] = depositOptions[key];
}
}
console.log(depositOptionsFiltered);
You may even want a new object and the key-value object to be a copy of the original rather than references to them. In this case you can perform a shallow copy. Uses Object.assign
const depositOptions = {
0: {
name: 'Monthly'
},
1: {
name: 'Standard'
},
2: {
name: 'Full'
},
3: {
name: 'Low'
}
};
const depositOptionsFiltered = {};
for (let key of Object.keys(depositOptions)) {
if (depositOptions[key].name !== 'Standard') {
depositOptionsFiltered[key] = Object.assign({}, depositOptions[key]);
}
}
console.log(depositOptionsFiltered);
I have an Ember Route class defined as below;
export default Ember.Route.extend({
model: function() {
var compObj = {};
compObj.gridPara = this.get('gridPara');
return compObj;
},
gridPara: function() {
var self = this;
var returnObj = {};
returnObj.url = '/myService';
// setting some other returnObj attributes
var summaryObj = {
total: {
label: "Total 1",
value: "100"
},
additional: [{
label: 'Label 2',
value: 'val2'
}, {
label: 'Label 3',
value: 'val3'
}]
};
returnObj.summary = summaryObj;
return returnObj;
},
actions: {
dataLoaded: function(resp) {
// Here I get the service response and want to set (or overwrite) the summaryObj values
this.get('gridParams').summary.total.value = resp.numRows;
}
}
});
My template looks like
{{my-grid params=this.gridPara dataLoaded="dataLoaded"}}
Now I want to set the "summary" on returnObj
I have verified that I get "resp" inside dataLoaded callback.
But I get the following error when trying to do
this.get('gridParams').summary.total.value = resp.numRows;
Uncaught Error: Assertion Failed: You must use Ember.set() to set the value property (of [object Object]) to 100.
Also how do I set/push for "additional" array inside summaryObj
As the error states, you must use set to the the value (Im assuming you have gridParams defined somewhere?):
this.set('gridParams.summary.total.value', resp.numRows);
In order to push a new object, try this:
var additional = this.get('gridParams.additional');
additional.push({label: ..., value: ....});
this.set('gridParams.additional', additional);
not 100% sure, but give it a try:
Watch out the property names. I suppose it's a wording error to declare 'gridPara' and trying to get 'gridParams'
You should retrieve the value like this
this.get('gridParams.summary.total.value')
What you are trying with the last sentence is a setting, but like it was plain JS. In Ember you should do it this.set('gridParams.summary.total.value',resp.numRows)
Just adding to #Remi answers ,the best practice would be to use
Ember.set('gridParams.summary.total.value', resp.numRows);
To answer the question in your comment
Say you want to update additional array at index i.Just do
var updateItem = additional[i];
Ember.set(updateItem.propertyname,newValue)
//Here propertyname would be the property you want to update and new Value is the new value which you want to set to that property
Wit this example object:
obj = {
id: '123',
attr: 'something'
}
Now I want to add the attribute link in the attribute data. Sometimes data is already existing, but in this example data doesn't exist.
So if I do
obj.data.link = 'www.website.com';
I get the error TypeError: Cannot set property 'link' of undefined.
Result should be:
obj = {
id: '123',
attr: 'something',
data: {
link: 'www.website.com'
}
}
You need to create the data object first:
obj.data = {};
obj.data.link = 'www.website.com';
or you can do it all at once:
obj.data = {
link: 'www.website.com'
};
if data may or may not already by there, there's a handy shortcut that will use the existing one if it's there or create a new one if not:
obj.data = obj.data || {};
obj.data.link = 'www.website.com';
That uses the JavaScript's curiously-powerful || operator.
You need to initialize the data property. You can do something like this:
var obj = {
id: '123',
attr: 'something'
};
obj.data = {};
obj.data.link = 'www.website.com';
In the case for the property existing you can check before assigning link.
if (!obj.data) {
obj.data = {};
}
And as stated in another answer you can use the or operator which I've heard is 'curiously powerful' =]
obj.data = obj.data || {};
That basically means if this value ( obj.data ) exists use it and if it doesn't use the right operand ( {} ). This works because of short circuit evaluation.
Javascript From 1.8.5 you can use the following method:
Object.defineProperty(obj, "data", {
value: {'link' : 'www.website.com'},
writable: true,
enumerable: true,
configurable: true
});
Good luck :)
I want to create a JSON object with variables as associative variable names similar to the following:
var field = 'first';
var query = { details.field, details.field };
I would prefer if the details were a fixed value.
This is my dataset currently
{
field1: ,
group: {
first:
}
}
My question is, how would I go about creating JSON objects with variables as fields?
You can add a property to an object like so:
var query = { details: {} };
var field = 'first';
query.details[field] = "TEST";
Which will give you the object:
{ details: { first: "TEST" }}
which you can then access with query.details.first or query.details[field];
Is that what you're looking for?
A simple way to accomplish this in Javascript is using the . operator.
query.details.field = "first";
This will product an object as follows:
"query" { "details" { "field": "first"} }
Is this what your looking for?
If you want multiple details you will want to use an array.
var query = [];
query.push({"details" { "field" : "first"} });
query.push({"details" { "field" : "second"} });
This will product an object like this
"query" [
"details" { "field" : "first"},
"details" { "field" : "second"}
]
I have a nested object. here it is:
var Obj = {
a: {
state: {
started: false,
players: [],
hand: 0,
totalHand: 0,
teams: {
starter: {
name: "",
handPoints: [],
totalPoint: calc(Obj.a.state.teams.starter.handPoints)
}
}
}
}
};
Like you see , i need to use handPoints value to set totalPoint. Do i have to call that like this:
calc(Obj.a.state.teams.starter.handPoints)
is there some way about using this keyword or something else?
What if i had a more nested object? It looks like weird to me.
Thank you.
Have you tried your solution? It causes a syntax error. Obj isn't defined while you're trying to define it, and even if it was you wouldn't get the latest value of obj, because you're trying to set it as the current value of the array at runtime.
see here:
syntax error example
You want to make that property a function so that a user can get the current total when they access the function.
Like this:
totalPoint: function(){
return calc(Obj.a.state.teams.starter.handPoints)
}
working example
If you want to shorten the reference you can alias some part of it. For instance
totalPoint: function(){
var myStarter = Obj.a.state.teams.starter;
return calc(myStarter.handPoints)
}
You could instead make the variable totalPoint into a function and use this.
var Obj = {
a: {
state: {
started: false,
players: [],
hand: 0,
totalHand: 0,
teams: {
starter: {
name: "",
handPoints: [ 5,6 ],
totalPoints: function() {
return calc(this.handPoints);
}
}
}
}
}
};
Here is the jsFiddle example.