How do I add an object property via an argument? - javascript

function addPropertyToProduct(product, property, value) {
let tryThis = property;
product.tryThis = value;
return product;
}
The argument 'product' will be an object that looks like this:
{ type: 'Terminator 2: Judgement Day', price: '£6.99', quantity: 1 }
Given a 'property' as an argument, as well as its corresponding value, update the 'product' to include this new information. Then return the updated 'product'.
E.g. if given the 'property' 'length' and the value '2h 36m', your function should return
{ type: 'Terminator 2: Judgement Day', price: '£6.99', quantity: 1, length: '2h 36m' }
This is the answer I'm receiving:
**+ expected** *- actual*
{
**+ "length": "2h 36m"**
"price": "£6.99"
"quantity": 1
*- "tryThis": "2h 36m"*
"type": "Terminator 2: Judgement Day"
}
This returns the value correctly but names the key as the variable name, not the argument itself?

Use square brackets []:
function addPropertyToProduct(product, property, value) {
let tryThis = property;
product[tryThis] = value;
return product;
}
For more info, check: MDN Computed Property Names

function addProperty(obj,propertyName,value){
obj.propertyName = value;
return obj;
}
This function will simply create a property dynamically and add value to it.
hope it helped.

NB: you can also use the spread operator instead of assigning 'product' to a new variable inside your function. But, yes in general, "Computed Property Names" is the key as Alvaro is saying above:)
function addPropertyToProduct(product, property, value) {
return {
...product,
[property]: value
}
};

Related

Why map in js doesn't accept function argument [duplicate]

This question already has answers here:
Accessing an object property with a dynamically-computed name
(19 answers)
Closed 1 year ago.
I was calling a function and pass array of objects as first argument and second argument was object property of first argument but I don't know why map func doesn't accepting second argument property
Here code plz see it once
const myfunc = (arrObj, property) => {
const arr1 = arrObj.map(item => {
return item.property
}
return arr1:
}
const arrObj = [{
title: 'book',
body: 'hello'
},
{
title: 'cup',
body: 'hii'
}
];
// Func call
console.log(myfunc(arrObj, 'title'));
Use lowercase for const, return, console.
Return a value (an array, in this case) from your function that you can log.
Use item[property] to access the title property. There is no "property" key in those objects.
Make sure you close all of your parentheses.
function myfunc(arrObj, property) {
return arrObj.map(item => item[property]);
}
const arrObj=[{title:"book",body:"hello"},{title:"cup",body:"hii"}];
console.log(myfunc(arrObj, 'title'));
There are multiple errors in your code. First keywords like return,const,console are all case sensative. Secondly you are not returning from the function. Third since property is a variable you have to use square braces instead of dot
const myfunc = (arrObj, property) => {
return arrObj.map(item => {
return item[property]
})
}
const arrObj = [{
title: 'book',
body: 'hello'
},
{
title: 'cup',
body: 'hii'
}
];
// Func call
console.log(myfunc(arrObj, 'title'));

How to get deleted or inserted item from proxy array?

I am trying to detect changes in an array of objects using JavaScript proxies.
Problem: Any time there is a change in array like deletion or insertion, i want to get that deleted or inserted item.
Current Code
target = [{ id: 1, a: 'a' }, { id: 2, a: 'b' }];
proxy = new Proxy(target, {
get: function (target, property: string, receiver) {
if (property === 'pop') {
console.log('deleted object', target[target.length - 1]);
}
console.log('get', property);
// property is index in this case
return target[property];
},
set: function (target, property, value, receiver) {
console.log('set', property, 'to', value);
target[property] = value;
// you have to return true to accept the changes
return true;
}
});
Current Thoughts:
I did a little workaround to get the deleted item from array but it only works for pop() method because it deletes the last item from array. But i need a way to get the changes even it is made using splice method or push or pop.
Thanks.
[Update]
Solution I Found:
https://github.com/ElliotNB/observable-slim
I used this library to detect changes in array, i am able to detect changes on nested properties inside array too. This is exactly what i was looking for.
The reason i am using this library is because it's using proxies.
I recommend not to expose actual traget on getter. You can create a wrapper function to support the cutosom modifier. Check out the below example.
const target = [
{ id: 1, a: "a" },
{ id: 2, a: "b" },
];
const proxy = new Proxy(target, {
get: function (target, property, receiver) {
switch (property) {
case "push":
case "pop":
case "slice":
case "splice":
return (...arg) => target[property](...arg);
}
throw Error("Not supported yet");
},
});
proxy.push({ id: 3, a: "c" })
console.log(proxy.pop())
console.log(proxy.slice(1,2))
console.log(proxy.pop())

Why does my spread operator show this behaviour?

let schools = [
{ name: "Yorktown"},
{ name: "Stratford" },
{ name: "Washington & Lee"},
{ name: "Wakefield"}
]
let updatedSchools = editName("Stratford", "HB Woodlawn", schools)
console.log( updatedSchools[1] ) // { name: "HB Woodlawn" }
const editName = (oldName, name, arr) =>
arr.map(item => {
if (item.name === oldName) {
// what is happening below!?
return {
...item,
name
}
} else {
return item
}
})
first of all, i'm sorry if this question might be easy for you, but i'm having trouble understanding how the return statement of the snippet works and would really appreciate help.
return { ...item, name }
So i would expect updatedSchool to be (even though it's invalid syntax):
[
{name: "Yorktown"},
{ name: "Yorktown", "HB Woodlawn"},
{ name: "Washington & Lee"},
{ name: "Wakefield"}
]
why does it produce { name: "HB Woodlawn" }?
Simply desugar expression step by step
{...item, name }
First {name} is shortcut for {name: name}
Then {...obj} is the same as Object.assign({}, obj)
Combining both gives Object.assign({}, obj, {name: name})
Given obj = {name: 'Stratford'} has only one property name it will simply create new object and replace name with a new one.
You can read about Object.assign here
return { // the spread operator assigns existing properties of item
...item, // to the new returned object
name // similar to return Object.assign(item, {name: name})
}
The rest parameter can work on objects as well as arrays in browsers that support it. If you want to understand the code, it's best to walk through it.
editSchools is a function that takes an oldName, a name, and an array. It returns the result of the mapping from array to a new array. Each element in the new array is determined by the callback function that map executes. If the item's name property is equal to the oldName, then a new object is created which will take its place, {...item, name}. This is where the confusion lies.
It does something weird. The new object recieves all the keys of the item object, and then it will define (or redefine) the name property to the value of name provided to editSchools.
So in essence, this code finds the objects that have a name key whose value is oldName and replaces it with an identical new object with a changed name property to the new name value.

Convert objects present in an object to NULL value

I have the following object names $scope.parameters. When i execute console.log as shown below, i get this result
console.log($scope.parameters);
Result
Object { Name: "Diana", id: 234, Size: Object, Location: Object, Details: "none" }
Name: "Diana"
id: 234,
Size: Object
Location: Object
Details: "none"
As the result shows the elements Size and Location as Object, i want it to be replaced with null. Also, i want it to be dynamic. for e.g. if any of the above elements are Object, it should replace it to null automatically.
Can someone please let me know how to achieve this.
Test out each key of the object with its type if object make them null
if (Object.getPrototypeOf($scope.parameters.Size) === Object.prototype) {
// True if its object change it to null
$scope.parameters.Size = null;
} else {
// do nothing
}
Make a function which takes parameters to test it out and return.
angular.forEach($scope.parameters, function(value, key) {
if(typeof value === "object"){
console.log(key);
$scope.parameters[key] = null;
}
});

Accessing data within an unknown object name

Let's say I have some JSON:
{
"An unknown value": {
"some": "values",
"I": "want",
"to": "access"
}
}
As you can see, I want to access the data within an object with an unknown name. This code will run in a Node.js environment. Any help is appreciated.
https://jsfiddle.net/ygac8dgg/
var object = {
"An unknown value": {
"some": "values",
"I": "want",
"to": "access"
},
"Another":"is",
"still":"uknown"
};
for (var property in object) {
if (object.hasOwnProperty(property)) {
// do stuff
console.log("property:",property);
console.log("value:",object[property]);
}
}
For everyone's reference, here's RobG's suggestion as a fiddle:
https://jsfiddle.net/m4jgyvp0
const object = {
'An unknown value': {
'some': 'values',
'I': 'want',
'to': 'access'
},
'Another': 'is',
'still': 'unknown'
};
const keys = Object.keys(object);
const array = keys.map(key => ({ key: key, value: object[key] }));
keys can be converted to an array of key-value pairs with the .map() function, or you could iterate over keys with .forEach().
Reading my question again, it is very vague/unclear, and I can't seem to remember the context of this.
However in other situations, where I need to access an object via a dynamic key, one can use:
const key: string = "aKeyFromSomeWhere"
const value = object[key]
rather than
object.aKnownKey

Categories