I am using angular 4 for one of my projects and i am in a situation where i have to replace all the {data} with {{data}}. ie if i have an object like this
{
key: {
key1: {
key2: "This is data {someData}",
key3: "This is data2 {someData2}"
}
},
key2: "This is data3 {someData3}"
}
the result should be
{
key: {
key1: {
key2: "This is data {{someData}}",
key3: "This is data2 {{someData2}}"
}
},
key2: "This is data3 {{someData3}}"
}
I am not so comfortable with recursion as on how it works . So i am not able to show anything that i have tried. Please help. Any help would be appreciated.
Hopefully you can try something like this.
var orgObj = {
key: {
key1: {
key2: "This is data {someData}",
key3: "This is data2 {someData2}"
}
},
key2: "This is data3 {someData3}"
}
function changeValue(obj) {
if (typeof obj === 'object') {
// iterating over the object using for..in
for (var keys in obj) {
//checking if the current value is an object itself
if (typeof obj[keys] === 'object') {
// if so then again calling the same function
changeValue(obj[keys])
} else {
// else getting the value and replacing single { with {{ and so on
let keyValue = obj[keys].replace('{', '{{').replace('}', '}}');
obj[keys] = keyValue;
}
}
}
return obj;
}
console.log(changeValue(orgObj))
Answer by @brk is good but it is mutates the input object. If someone is working with a library like React where it is important to not mutate props, then we will have to do some additional things. We can either create new reference for all the objects that we find during recursive traversal. For this, we have to take care of null
values since typeof null
is also object
//typeof null is also object. But we cannot destructure it. So check that object is not null
const isValidObject = (obj) => typeof obj === 'object' && obj !== null
function changeValue(objFromProp) {
let obj = objFromProp;
if (isValidObject(objFromProp)) {
//desctructure the object to create new reference
obj = { ...objFromProp }
// iterating over the object using for..in
for (var keys in obj) {
//checking if the current value is an object itself
if (isValidObject(obj[keys])) {
// if so then again calling the same function
obj[keys] = changeValue(obj[keys])
} else {
// else getting the value and replacing single { with {{ and so on
let keyValue = obj[keys].replace('{', '{{').replace('}', '}}');
obj[keys] = keyValue;
}
}
}
return obj;
}
Or if we are replacing values conditionally and if we want to preserve object's reference if none of the values in an object is changed, then we can use another library like immer. Immer will change reference of only those objects whose at-least one field is changed. This will be a useful optimization. For this method, we should use version of changeValue
provided by @brk. Immer will identify mutations and change necessary references.
import { produce } from 'immer';
const nextState = produce(objFromProp, draftState => {
changeValue(draftState)
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With