Dynamically create angular object with key, value from angular.forEach() - javascript

if ($scope.data) {
$formData = [];
angular.forEach($scope.data, function(value, key){
console.log(key); // o/p: 'fruitname'
var k = key;
var value = value || 'Not Available';
console.log(value); // o/p: 'apple'
var parts = {k : value};
console.log(parts); // o/p: Object {k: "apple"}
$formData.push(parts);
});
}
Why i cannot able to populate key, while creating parts object. or how can i do the same.

What you need to do is parts[k] = value;
Actually when you assign parts = { k : value }; , This goes something like this :
parts["k"] = value;
So you see instead of taking the value of k, it takes k as string and assign a value to this string as key field.

it works when i try to do like this.
if ($scope.data) {
$formData = [];
angular.forEach($scope.data, function(value, key){
console.log(key); // o/p: 'fruitname'
var value = value || 'Not Available';
console.log(value); // o/p: 'apple'
var parts = {};
parts[key] = value;
console.log(parts); // o/p: Object {"fruitname": "apple"}
$formData.push(parts);
});
}

Related

Assign object value as array in javascript

How to assign the value to array in object value? It may has multiple input coming in and expected the input appended to array.
Code:
var ob = {};
$.each( input, function( key, value ) {
var v = [];
ob[key] = v.push(value);
console.log( v );
console.log( "obj: " + ob );
console.log( key + ": " + value );
});
Input:
First input- {A: "34",B: "2"}
Second input- {A: "21",B: "11"}
Expected:
ob = {A: ["34","21"] ,B: ["2","11"]}
Hope this helps,
var ob = {};
$.each(input, function(key, value) {
if (!ob[key]) {
ob[key] = []; // Creates a new Array for the key, if no array is there
}
ob[key].push(value); // Pushes the value to the array of the particular key
});
Create a function and an object variable. Check if the key exist in that object. If it does not exist they create the key and push the values
let input1 = {
A: "34",
B: "2"
}
let input2 = {
A: "21",
B: "11"
}
// a object which will hold the key and value
let finalObj = {};
// create a function which will be called o add key an value property to object
function createObj(obj) {
// iterate the object
for (let keys in obj) {
// check if final object has the relevent key
if (finalObj.hasOwnProperty(keys)) {
// if it has that key then push the value according to the key
finalObj[keys].push(obj[keys])
} else {
finalObj[keys] = [obj[keys]]
}
}
}
createObj(input1)
createObj(input2)
console.log(finalObj)
The problem is v empties on each iteration, because of this line:
var v = [];
Try doing this instead:
$.each(input, (key, val) => {
if (ob[key]) {
ob[key].push(val);
} else {
ob[key] = [val];
}
});

How to use string as a key to update object

I am trying to create a function that accepts the path in an object and makes that the key.
for example, if I wanted to update the city, which is is a child object of a company, which is a child object of a property I could do something like this:
originalObj['property']['company']['city'] = test
Here is my code so far:
function updateObj(path, value){
let valuePath = path.split(',')
let key=''
for(let i=0; i<valuePath.length ; i++){
key = key+`[valuePath[${i}]]`
}
//key = [valuePath[0]] [valuePath[1]] [valuePath[2]]
originalObj[key] = value
}
setObj('property,company,city', test)
You could save the last key of the path and use a temporary object for getting the final object for assigning the value.
function updateObj(path, value) {
var valuePath = path.split(','),
last = valuePath.pop(),
temp = object;
for (let i = 0; i < valuePath.length; i++) {
temp = temp[valuePath[i]];
}
temp[last] = value;
}
var object = { property: { company: { city: 'London' } } };
updateObj('property,company,city', 'New York');
console.log(object);
With Array#reduce
function updateObj(path, value) {
var valuePath = path.split(','),
last = valuePath.pop();
valuePath.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
}
var object = {};
updateObj('property,company,city', 'New York');
console.log(object);
function updateObj(obj, path, value){
path.split(",").slice(0,-1).reduce((obj, key) => obj[key] || (obj[key] = {}), obj)[path.split(",").pop()] = value;
}
Try this:
function setObj(originalObj, path, value){
var parts = path.split(',');
var lastKey = parts.pop();
var obj = originalObj;
parts.forEach(
function(key) {
key = key.trim();
obj[key] = obj[key] || {};
obj = obj[key];
}
);
obj[lastKey] = value;
}
var originalObj = {};
var test = "This is a test";
setObj(originalObj, 'property,company,city', test)
console.log(JSON.stringify(originalObj,0,2));
It walks through your list and creates sub objects for all but the last. It then uses the last as the key to store the value.
The advantage to this code is that you don't assume the original Object variable name. And, if you wanted it to be pure and not to affect the original object structure then you could make these minor changes:
function setObj(originalObj, path, value){
var parts = path.split(',');
var lastKey = parts.pop();
var newObj = Object.assign({}, originalObj);
var obj = newObj;
parts.forEach(
function(key) {
obj[key] = Object.assign({}, obj[key] || {});
obj = obj[key];
}
);
obj[lastKey] = value;
return newObj;
}
var originalObj = {animals: {dog:"bark",cat:"meow"},property:{company:{name:"Fred's Things"}}};
var test = "This is a test";
var result = setObj(originalObj, 'property,company,city', test)
console.log(JSON.stringify(originalObj,0,2));
console.log(JSON.stringify(result,0,2));

Replace key in an array of object

I have an array of objects :
arrayOfObject = [{'key1': [1,2]} , {'key2': [1,2,3]} , {'key3': [1,2,4]}]
I have the name of the key I want to replace in my array :
var keyString = 'key1';
And I have the new name the key should take :
var newKey = 'newKey'
How to make my array this :
arrayOfObject = [{'newKey': [1,2]} , {'key2': [1,2,3]} , {'key3': [1,2,4]}]
JavaScript: Object Rename Key this can help me to rename the key but the thing is how to access the object first in my array that has the key1 key.
Note that keyString is random. So it's pointless to get it like arrayOfObject[0]
https://jsfiddle.net/tcatsx6e/
Check this solution:
var arrayOfObject = [{'key1': [1,2]} , {'key2': [1,2,3]} , {'key3': [1,2,4]}];
var keyString = 'key1';
var newKey = 'newKey';
var newArray = arrayOfObject.map(function(item) {
if (keyString in item) {
var mem = item[keyString];
delete item[keyString];
item[newKey] = mem;
}
});
Please check this jsbin for a complete example.
This will return the index of the object you want to modify.
function(arr, keyString) {
for (var i = 0; i < arr.length; ++i) {
if (arr[i][keyString] !== undefined) {
return i;
}
}
}

Splitting dots into separate objects javascript

I have an object like this:
var data = {"prop.health": 1, "prop.cost":1, "prop.time":1}
I want to change it into an object like this:
{
"prop": {
"health": 1,
"cost":1,
"time":1
}
}
Here's my code:
_.each(data, function (value, key) {
var split = key.split('.')
if (split.length > 1) {
data[split[0]] = data[split[0]] || {}
data[split[0]][split[1]] = value
delete data[key]
}
})
But this only works for 1 level of nesting. How would you write it to ensure it works for as deeply nested properties as you need?
You can use a combination of _.transform and _.set, for example
data = _.transform(data, function(transformed, val, key) {
_.set(transformed, key, val);
});
Results in
{"prop":{"health":1,"cost":1,"time":1}}
Without a library it would be something like this:
(function(){
var data = {"prop.health": 1, "prop.cost":1, "prop.time":1, "prop.test.fun" : 1, "prop.test.sun" : 1};
var obj = {}; //will hold the object all parsed out
Object.keys(data).forEach( function (key) { //loop through the keys in the object
var val = data[key]; //grab the value of this key
var step = obj; //reference the object that holds the values
key.split(".").forEach(function(part, index, arr){ //split the parts and loop
if(index===arr.length-1){ //If we are at the last index, than we set the value
step[part] = val;
} else if(step[part]===undefined) { //If we have not seen this key before, create an object
step[part] = {};
}
step = step[part]; //Step up the object we are referencing
});
} );
console.log(obj);
}());
Or the double reduce loop
(function(){
var data = {"prop.health": 1, "prop.cost":1, "prop.time":1, "prop.test.fun" : 1, "prop.test.sun" : 1};
var result = Object.keys(data).reduce( function (obj, key) { //loop through the keys in the object
var val = data[key]; //grab the value of this key
key.split(".").reduce(function(step, part, index, arr){ //split the parts and loop
if(index===arr.length-1){ //If we are at the last index, than we set the value
step[part] = val;
} else if(step[part]===undefined) { //If we have not seen this key before, create an object
step[part] = {};
}
return step[part]; //Step up the object we are referencing
}, obj);
return obj;
}, {});
console.log(result);
}());
Depending on a number of factors (e.g. if the original object always has keys you want to delete, etc.) you may be able to use _.set:
var data = {"prop.health": 1, "prop.cost":1, "prop.time":1};
_.each(data, function (value, key) {
delete data[key];
_.set(data, key, value);
});
_.set will create the path if it doesn't exist. The above results in:
{"prop":{"health":1,"cost":1,"time":1}}
And {"prop.health": 1, "prop.cost.food":1, "prop.time":1} will result in:
{"prop":{"health":1,"cost":{"food":1},"time":1}}

String to object in JS

I have a string as
string = "firstName:name1, lastName:last1";
now I need one object obj such that
obj = {firstName:name1, lastName:last1}
How can I do this in JS?
Actually, the best solution is using JSON:
Documentation
JSON.parse(text[, reviver]);
Examples:
1)
var myobj = JSON.parse('{ "hello":"world" }');
alert(myobj.hello); // 'world'
2)
var myobj = JSON.parse(JSON.stringify({
hello: "world"
});
alert(myobj.hello); // 'world'
3)
Passing a function to JSON
var obj = {
hello: "World",
sayHello: (function() {
console.log("I say Hello!");
}).toString()
};
var myobj = JSON.parse(JSON.stringify(obj));
myobj.sayHello = new Function("return ("+myobj.sayHello+")")();
myobj.sayHello();
Your string looks like a JSON string without the curly braces.
This should work then:
obj = eval('({' + str + '})');
WARNING: this introduces significant security holes such as XSS with untrusted data (data that is entered by the users of your application.)
If I'm understanding correctly:
var properties = string.split(', ');
var obj = {};
properties.forEach(function(property) {
var tup = property.split(':');
obj[tup[0]] = tup[1];
});
I'm assuming that the property name is to the left of the colon and the string value that it takes on is to the right.
Note that Array.forEach is JavaScript 1.6 -- you may want to use a toolkit for maximum compatibility.
This simple way...
var string = "{firstName:'name1', lastName:'last1'}";
eval('var obj='+string);
alert(obj.firstName);
output
name1
Since JSON.parse() method requires the Object keys to be enclosed within quotes for it to work correctly, we would first have to convert the string into a JSON formatted string before calling JSON.parse() method.
var obj = '{ firstName:"John", lastName:"Doe" }';
var jsonStr = obj.replace(/(\w+:)|(\w+ :)/g, function(matchedStr) {
return '"' + matchedStr.substring(0, matchedStr.length - 1) + '":';
});
obj = JSON.parse(jsonStr); //converts to a regular object
console.log(obj.firstName); // expected output: John
console.log(obj.lastName); // expected output: Doe
This would work even if the string has a complex object (like the following) and it would still convert correctly. Just make sure that the string itself is enclosed within single quotes.
var strObj = '{ name:"John Doe", age:33, favorites:{ sports:["hoops", "baseball"], movies:["star wars", "taxi driver"] }}';
var jsonStr = strObj.replace(/(\w+:)|(\w+ :)/g, function(s) {
return '"' + s.substring(0, s.length-1) + '":';
});
var obj = JSON.parse(jsonStr);
console.log(obj.favorites.movies[0]); // expected output: star wars
If you have a string like foo: 1, bar: 2 you can convert it to a valid obj with:
str
.split(',')
.map(x => x.split(':').map(y => y.trim()))
.reduce((a, x) => {
a[x[0]] = x[1];
return a;
}, {});
Thanks to niggler in #javascript for that.
Update with explanations:
const obj = 'foo: 1, bar: 2'
.split(',') // split into ['foo: 1', 'bar: 2']
.map(keyVal => { // go over each keyVal value in that array
return keyVal
.split(':') // split into ['foo', '1'] and on the next loop ['bar', '2']
.map(_ => _.trim()) // loop over each value in each array and make sure it doesn't have trailing whitespace, the _ is irrelavent because i'm too lazy to think of a good var name for this
})
.reduce((accumulator, currentValue) => { // reduce() takes a func and a beginning object, we're making a fresh object
accumulator[currentValue[0]] = currentValue[1]
// accumulator starts at the beginning obj, in our case {}, and "accumulates" values to it
// since reduce() works like map() in the sense it iterates over an array, and it can be chained upon things like map(),
// first time through it would say "okay accumulator, accumulate currentValue[0] (which is 'foo') = currentValue[1] (which is '1')
// so first time reduce runs, it starts with empty object {} and assigns {foo: '1'} to it
// second time through, it "accumulates" {bar: '2'} to it. so now we have {foo: '1', bar: '2'}
return accumulator
}, {}) // when there are no more things in the array to iterate over, it returns the accumulated stuff
console.log(obj)
Confusing MDN docs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Demo: http://jsbin.com/hiduhijevu/edit?js,console
Function:
const str2obj = str => {
return str
.split(',')
.map(keyVal => {
return keyVal
.split(':')
.map(_ => _.trim())
})
.reduce((accumulator, currentValue) => {
accumulator[currentValue[0]] = currentValue[1]
return accumulator
}, {})
}
console.log(str2obj('foo: 1, bar: 2')) // see? works!
You need use JSON.parse() for convert String into a Object:
var obj = JSON.parse('{ "firstName":"name1", "lastName": "last1" }');
if you're using JQuery:
var obj = jQuery.parseJSON('{"path":"/img/filename.jpg"}');
console.log(obj.path); // will print /img/filename.jpg
REMEMBER: eval is evil! :D
I implemented a solution in a few lines of code which works quite reliably.
Having an HTML element like this where I want to pass custom options:
<div class="my-element"
data-options="background-color: #dadada; custom-key: custom-value;">
</div>
a function parses the custom options and return an object to use that somewhere:
function readCustomOptions($elem){
var i, len, option, options, optionsObject = {};
options = $elem.data('options');
options = (options || '').replace(/\s/g,'').split(';');
for (i = 0, len = options.length - 1; i < len; i++){
option = options[i].split(':');
optionsObject[option[0]] = option[1];
}
return optionsObject;
}
console.log(readCustomOptions($('.my-element')));
In your case, The short and beautiful code
Object.fromEntries(str.split(',').map(i => i.split(':')));
I'm using JSON5, and it's works pretty well.
The good part is it contains no eval and no new Function, very safe to use.
string = "firstName:name1, lastName:last1";
This will work:
var fields = string.split(', '),
fieldObject = {};
if( typeof fields === 'object') ){
fields.each(function(field) {
var c = property.split(':');
fieldObject[c[0]] = c[1];
});
}
However it's not efficient. What happens when you have something like this:
string = "firstName:name1, lastName:last1, profileUrl:http://localhost/site/profile/1";
split() will split 'http'. So i suggest you use a special delimiter like pipe
string = "firstName|name1, lastName|last1";
var fields = string.split(', '),
fieldObject = {};
if( typeof fields === 'object') ){
fields.each(function(field) {
var c = property.split('|');
fieldObject[c[0]] = c[1];
});
}
const text = '{"name":"John", "age":30, "city":"New York"}';
const myArr = JSON.parse(text);
document.getElementById("demo").innerHTML = myArr.name;
This is universal code , no matter how your input is long but in same schema if there is : separator :)
var string = "firstName:name1, lastName:last1";
var pass = string.replace(',',':');
var arr = pass.split(':');
var empty = {};
arr.forEach(function(el,i){
var b = i + 1, c = b/2, e = c.toString();
if(e.indexOf('.') != -1 ) {
empty[el] = arr[i+1];
}
});
console.log(empty)
Here is my approach to handle some edge cases like having whitespaces and other primitive types as values
const str = " c:234 , d:sdfg ,e: true, f:null, g: undefined, h:name ";
const strToObj = str
.trim()
.split(",")
.reduce((acc, item) => {
const [key, val = ""] = item.trim().split(":");
let newVal = val.trim();
if (newVal == "null") {
newVal = null;
} else if (newVal == "undefined") {
newVal = void 0;
} else if (!Number.isNaN(Number(newVal))) {
newVal = Number(newVal);
}else if (newVal == "true" || newVal == "false") {
newVal = Boolean(newVal);
}
return { ...acc, [key.trim()]: newVal };
}, {});
In your case
var KeyVal = string.split(", ");
var obj = {};
var i;
for (i in KeyVal) {
KeyVal[i] = KeyVal[i].split(":");
obj[eval(KeyVal[i][0])] = eval(KeyVal[i][1]);
}
var stringExample = "firstName:name1, lastName:last1 | firstName:name2, lastName:last2";
var initial_arr_objects = stringExample.split("|");
var objects =[];
initial_arr_objects.map((e) => {
var string = e;
var fields = string.split(','),fieldObject = {};
if( typeof fields === 'object') {
fields.forEach(function(field) {
var c = field.split(':');
fieldObject[c[0]] = c[1]; //use parseInt if integer wanted
});
}
console.log(fieldObject)
objects.push(fieldObject);
});
"objects" array will have all the objects
I know this is an old post but didn't see the correct answer for the question.
var jsonStrig = '{';
var items = string.split(',');
for (var i = 0; i < items.length; i++) {
var current = items[i].split(':');
jsonStrig += '"' + current[0] + '":"' + current[1] + '",';
}
jsonStrig = jsonStrig.substr(0, jsonStrig.length - 1);
jsonStrig += '}';
var obj = JSON.parse(jsonStrig);
console.log(obj.firstName, obj.lastName);
Now you can use obj.firstName and obj.lastName to get the values as you could do normally with an object.
You don't have to always convert to JSON
So here "person begin as a string!" Finally, "person is converted to object", no necessarily to JSON.
function strToObj(e){if(typeof e=="string"){ let obj=new Function("return" +e); try{return obj()}catch{console.log("Fix, String no allowed to object")}}else{console.log("it is not a string") } };
//Example, person is a string
let person='{firstName:"John", lastName:"Doe", id: 55, fullName:function(){return this.firstName+" "+this.lastName} }';
console.log(strToObj(person));
And it run functions internal to the object without major issues if it is called:
person=strToObj(person); console.log(person.fullName())
Simply, string = "firstName:name1, lastName:last1";
let string = "firstName:name1, lastName:last1";
let object= strToObj("{"+string+"}");
console.log(object)

Categories

Resources