Javascript array within JSON Object - javascript

I'm trying to achieve this structure (a JSON Object with an array inside):
var data = {
page : 'hello',
rows: [
{
column: 'two'
}
]
}
But i'm failing miserable, trying various methods, this is my work in progress code:
var data = new Array();
data['settings'] = [];
var i = 0;
var inputName, value;
for (i; i < inputs.length; i++){
inputName = $(inputs[i]).attr('name');
value = $(inputs[i]).val();
data['settings'][inputName] = value;
}
data['page_id'] = page_id;
So i know the variable names are not the same as the desired example but you get the general gist! At the moment, its just making data an empty array. But i need to make it a JSON object with the idea to send it to a server.

What you've quoted is a JavaScript object with a JavaScript array in it, no JSON* in sight.
To create it, I don't think you want an array at all, just an object with a nested object:
var data = {
settings: {},
page_id: page_id
};
var i, input;
for (i = 0; i < inputs.length; i++){
input = $(inputs[i]);
data.settings[input.attr('name')] = input.val();
}
That works because JavaScript objects are maps of name/value pairs. You can refer to a property of an object using dotted notation and a literal property name:
x = obj.foo;
...or using bracketed notation and a string name:
x = obj["foo"];
In the latter case, you can use any expression you like for the string, so for instance:
x = obj["f" + "o" + "o"];
JavaScript also has literal object initializers, which you can use to create an object with properties already on it:
obj = {foo: "bar"};
That creates an object with a property called foo with the value "bar" and assigns the object to the obj variable.
So looking again at the code block above:
We create an object with the properties settings and page_id. settings is initialized with a blank object; page_id is initialized with the value of the page_id variable.
Then we loop through your inputs and add properties to settings using the name of each input, setting the value of the property to be the value of the input.
So let's assume we have
<input name="oneField" value="bar">
<input name="anotherField" value="bang">
<input name="yetAnotherField" value="cool">
...and let's assume page_id is 3.
We'll end up with this structure in the object referenced by the data variable:
{
settings: {
oneField: "bar",
anotherField: "bang",
yetAnotherField: "cool"
},
page_id: page_id
}
* JSON is a textual notation. When you're writing things like var data = { ... }; in code, you're just using JavaScript. JSON is a subset of JavaScript literal syntax that's designed to be easy to parse, so for instance it's handy for storing arbitrary complex data in data stores, or for retrieving data from a server. You retrieve the string, which contains the data, and then parse that string to build up an object structure in memory.

var data = {};
data['settings'] = {};
var i = 0;
var inputName, value;
for (i; i < inputs.length; i++){
inputName = $(inputs[i]).attr('name');
value = $(inputs[i]).val();
data['settings'][inputName] = value;
}
data['page_id'] = page_id;
This will give you such result like below:
{
page_id: 12345,
setting: { foo: 'one', bar: 'two'}
}

Both [] and new Array() are used to initialize an array; what you're after (as you're trying to map keys to values), are objects; which are initialized using either {} or new Object().
var data = {};
data['settings'] = {};
var i = 0;
var inputName, value;
for (i; i < inputs.length; i++){
inputName = $(inputs[i]).attr('name');
value = $(inputs[i]).val();
data['settings'][inputName] = value;
}
data['page_id'] = page_id;
To help you with your syntax, square bracket notation is only needed if the member you're looking up is a variable, or if the key contains reserved words or special characters (spaces etc). Otherwise, you can use dot notation;
var data = {};
data.settings = {};
var i = 0;
var inputName, value;
for (i; i < inputs.length; i++){
inputName = $(inputs[i]).attr('name');
value = $(inputs[i]).val();
data.settings[inputName] = value;
}
data.page_id = page_id;
When using object literal syntax ({}) to construct an object, you are allowed to define members on the object as well. It's also more common to declare your looping variable within the for loop rather than outside.
var data = {
settings: {}
};
var inputName, value;
for (var i=0; i < inputs.length; i++){
inputName = $(inputs[i]).attr('name');
value = $(inputs[i]).val();
data.settings[inputName] = value;
}
data.page_id = page_id;

Related

Why is object property not setting correctly in loop?

I'm looping through an array and for each element 1) checking if it's a property in my object, 2) and if not, adding it to obj as prop with the val of it's index. Code is here in full as i'm not sure which part contains the error.
var repeat = function(arr) {
for(let i=0; i<arr.length; i++){
const obj = {};
if (obj.hasOwnProperty(arr[i])) {
return arr[i]
} else {
obj.arr[i] = i;
}
}
};
I'm getting the error "Cannot set property of '0' to undefined".
I did search similar questions and errors but didn't find an answer within the context of objects. Would appreciate insight as to this specific error and/or where my code is going wrong.
You trying to check the properties in a empty object. const obj = {}; You have to pass the object in to the function as well. When adding the property to a object it should be like this obj["New Property"] = value. We can't add new values using .(dot) as we access values from objects.
var repeat = function(arr,obj) {
var pObj = {}
for(let i=0; i<arr.length; i++){
if(!obj.hasOwnProperty(arr[i])){
pObj[arr[i]] = i
}
}
const a = {...obj, ...pObj};
return a;
};
var myarr= ["a","b","c","d"];
var myObj = {a:"Property A",b:"Property B"};
this.repeat(myarr,myObj)

Unexpected result pushing objects into an array

How to iterate over an array of literal objects in JavaScript?
I would like to do something like that:
grupo = []; // declare array
text = {}; // declare new object
text.a = "texta"; // declare property "a" of an object.
text.b = "textb";
grupo.push(text); // add object to array
text = {}; // declare new object
text.a = "textc"; // declare property
grupo.push(text); // add object with other property
// Iterate over
for (i=0; i<=grupo.length; i++) {
console.dir(grupo[i].text.a);
}
There are various errors in that code:
You're putting the same object in the array twice, not putting two objects in the array. After you push text into the array, you're just overwriting the a property on the same object and pushing it again. You haven't created a new object.
You haven't declared any of your variables (everywhere you've said "declare" in your comments, those are not declarations), so you're falling prey to The Horror of Implicit Globals. Use var to declare variables.
A line comment should start with //, not \\ (those cause a syntax error)
The for loop at the end should use <, not <=, for its termination condition. For the various ways to loop through arrays in JavaScript, see this question and its answers.
Here's a cleaned-up version of that code:
var text, grupo, i; // Declare variables
text = {}; // Create an object and assign it to the variable
grupo = []; // Create an array and assign it to the variable
text.a = "texta"; // Set the property `a` on the object
text.b = "textb"; // Set the property `b` on the object
grupo.push(text); // Put that object onto the array
text = {}; // Create a second object
text.a = "textc"; // Set the property `a` on that new object
grupo.push(text); // Put that object on the array
for (i=0;i<grupo.length;i++) {
// ^-------------------- Note no =
console.dir(grupo[i].text.a);
}
Do you mean something like this?
for (var key in validation_messages) {
var obj = validation_messages[key];
for (var prop in obj) {
// important check that this is objects own property
// not from prototype prop inherited
if(obj.hasOwnProperty(prop)){
alert(prop + " = " + obj[prop]);
}
}
}
Reference: https://stackoverflow.com/a/921808/1054926
groupo[i] is already a text object so you there is an error there. Also, you don't want to look until your index is <= to the length.
Here is a quick look at what you may be looking for in your loop:
for (i=0;i<grupo.length;i++) {
console.log(i,grupo[i].a);
}
However you will have additional problem when you discover that the value of "a" is not what you may be expecting.
Here another possible "solution"
var text = {};
var grupo = [];
text.a = "texta";
text.b = "textb";
grupo.push(text);
text.a = "textc";
grupo.push(text);
for (var i=0;i < grupo.length;i++) {
var x = grupo[i];
if (x && x.a){
console.log(x.a);
} else {
console.log(x);
}
}

How to convert String to an object type

I'm using emberjs to find stuff but the question is more JS related than Ember.
I have two variables: var type = "stars"; var term = "5"
I have a property called stars in my API.
When I do: App.Response.find({stars: term}); I find results
However, when I do: App.Response.find({type: term}); I don't find results. I want this to be translated to App.Response.find({stars: term}) since type has value "stars"
I am assuming this is because type (with value stars) is not being understood as a hash key?
Exactly - it will not evaluate object keys. If you want to dynamically create that object as {stars:5} you could do:
var obj = {};
obj[type] = term;//Using the array notation will cause JS to evaluate type to "stars" and use that as the key
//obj is now {stars:5}
App.Response.find(obj);
There's no dynamic way to set object keys in an object literal.
You have to do
var conditions = {},
type = "stars",
term = "5";
conditions[type] = term;
App.Response.find(conditions);
If you find yourself using this pattern a lot, you could setup something like
var buildObject = function(key, value) {
var base = {},
base[key] = value;
return base;
};
var type = "stars",
term = "5";
App.Response.find(buildObject(type, term));
// or directly as
App.Response.find(buildObject("stars", "5"));
Lastly, let's make the buildObject helper a little more useful
// accepts [key, value] pairs
var buildObject = function() {
var base = {};
for (var i=0; i<arguments.length; i++) {
base[arguments[i][0]] = arguments[i][1];
};
return base;
};
Now we can pass in multiple pairs
App.Response.find(buildObject(["stars", "5"], ["foo", "bar"]));
// equivalent to
App.Response.find({stars: "5", foo: "bar"});

Dynamically Add Variable Name Value Pairs to JSON Object

I have a json object full of ips like
var ips = {}
I then add ip objects to this object like so
ips[ipID] = {}
I then need to add dynamic/variable name value pairs to each ip so I am using code like this
var name; var value; var temp = {};
tmp[name] = value
My question is, how can I add these name value pairs/ tmp to my ipID objects so that my outcome turns out like
ipID = { name : value, anotherName : anotherValue }
That's not JSON. It's just Javascript objects, and has nothing at all to do with JSON.
You can use brackets to set the properties dynamically. Example:
var obj = {};
obj['name'] = value;
obj['anotherName'] = anotherValue;
This gives exactly the same as creating the object with an object literal like this:
var obj = { name : value, anotherName : anotherValue };
If you have already added the object to the ips collection, you use one pair of brackets to access the object in the collection, and another pair to access the propery in the object:
ips[ipId] = {};
ips[ipId]['name'] = value;
ips[ipId]['anotherName'] = anotherValue;
Notice similarity with the code above, but that you are just using ips[ipId] instead of obj.
You can also get a reference to the object back from the collection, and use that to access the object while it remains in the collection:
ips[ipId] = {};
var obj = ips[ipId];
obj['name'] = value;
obj['anotherName'] = anotherValue;
You can use string variables to specify the names of the properties:
var name = 'name';
obj[name] = value;
name = 'anotherName';
obj[name] = anotherValue;
It's value of the variable (the string) that identifies the property, so while you use obj[name] for both properties in the code above, it's the string in the variable at the moment that you access it that determines what property will be accessed.
With ECMAScript 6 there is a better way.
You can use computed property names in object property definitions, for example:
var name1 = 'John';
var value1 = '42';
var name2 = 'Sarah';
var value2 = '35';
var ipID = {
[name1] : value1,
[name2] : value2
}
This is equivalent to the following, where you have variables for the property names.
var ipID = {
John: '42',
Sarah: '35'
}
when using javascript objects, you can also just use "dot notation" to add an item, (which JSLint prefers)
var myArray = { name : "john" };
//will initiate a key-value array with one item "name" and the value "john"
myArray.lastName = "smith";
//will add a key named lastName with the value "smith"
//Object {name: "john", lastName: "smith"}
Here is a screenshot from testing in the Chrome console
I'm assuming each entry in "ips" can have multiple name value pairs - so it's nested. You can achieve this data structure as such:
var ips = {}
function addIpId(ipID, name, value) {
if (!ips[ipID]) ip[ipID] = {};
var entries = ip[ipID];
// you could add a check to ensure the name-value par's not already defined here
var entries[name] = value;
}
in Javascript.
var myObject = { "name" : "john" };
// { "name" : "john" };
myObject.gender = "male";
// { "name" : "john", "gender":"male"};
if my understanding of your initial JSON is correct, either of these solutions might help you loop through all ip ids & assign each one, a new object.
// initial JSON
var ips = {ipId1: {}, ipId2: {}};
// Solution1
Object.keys(ips).forEach(function(key) {
ips[key] = {name: 'value', anotherName: 'another value'};
});
// Solution 2
Object.keys(ips).forEach(function(key) {
Object.assign(ips[key],{name: 'value', anotherName: 'another value'});
});
To confirm:
console.log(JSON.stringify(ips, null, 2));
The above statement spits:
{
"ipId1": {
"name":"value",
"anotherName":"another value"
},
"ipId2": {
"name":"value",
"anotherName":"another value"
}
}
From what the other answers have proposed, I believe this might help:
var object = ips[ipId];
var name = "Joe";
var anothername = "Fred";
var value = "Thingy";
var anothervalue = "Fingy";
object[name] = value;
object[anothername] = anothervalue;
However, this is not tested, just an assumption based on the constant repetition of:
object["string"] = value;
//object = {string: value}
You can achieve this using Lodash _.assign function.
var ipID = {};
_.assign(ipID, {'name': "value"}, {'anotherName': "anotherValue"});
console.log(ipID);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.10/lodash.min.js"></script>

JavaScript object - add property without using eval?

I have a JavaScript object that I'd like to add some properties to, but I don't know what the names of the properties are until runtime.
Can I do this without using eval? If so, how?
var get_params = new Object();
var params = {'name':'john', 'age':'23'}; //actually not known until runtime
for (var i=0, len=params.length; i<len; ++i ){
get_params.p[0] = p[1]; //How can I set p[0] as the object property?
}
}
Since your code example has a malformed array, I will include 2 variations.
Variation 1 (params is an actual object and not an array):
var get_params = {}; // prefer literal over Object constructors.
var params = {'name':'john', 'age':'23'}; // #runtime (as object literal)
for (var key in params){
if(params.hasOwnProperty(key)) { // so we dont copy native props
get_params[key] = params[key];
}
}
Variation 2 (param is an array containing objects):
var get_params = {}; // prefer literal over Object constructors.
var params = [{'name':'john'},{'age':'23'}]; // #runtime (as array literal)
for(var i=0,param;param=params[i];i++) {
for (var key in param){
if(param.hasOwnProperty(key)) {
get_params[key] = param[key];
}
}
}
Enjoy.
You can access objects via object['someKey'] as well.
var get_params = {};
var params = [{'name':'john'}, {'age':'23'}];
for (var i=0,len=params.length; i<len; ++i){
for (var p in params[i]) {
if(params[i].hasOwnProperty(p)) {
get_params[p] = params[i][p];
}
}
}
Ok, that's my third version. I think it will do what I understand you to desire. Kind of convoluted however, and there are probably better formats for your dynamic array. If I understand what you want to do correctly, this should work. Basically, it creates the following object:
get_params = {
name: "john",
age: "23"
}

Categories