How to make array of objects in JS - javascript

I want to send a multi level array via AJAX. so I tried to make an object of objects as follow:
var info = {};
info.pickup = {};
info.pickup.contact = {};
info.pickup.items_quantity = {};
info.pickup.items = {};
info.delivery = {};
info.delivery.contact = {};
info.delivery.level = {};
then I started filling the objects, for example:
$('.operation-create .pickup .contact-details').each(function () {
var arr = {};
arr['contact_name'] = $(this).find('input[name="pickup-contact-name"]').val();
arr['contact_phone'] = $(this).find('input[name="pickup-contact-phone"]').val();
arr['pickup-suburb'] = $(this).find('select[name="pickup-suburb"]').val();
arr['single-pickup-address'] = $(this).find('input[name="single-pickup-address"]').val();
info.pickup.contact.push(arr);
});
info.pickup.push(info.pickup.contact);
etc...
However unfortunately it didn't work. I get this error:
info.pickup.contact.push is not a function
What I should do here? What is the right way to send this array via AJAX?

You need an array as value
info.delivery.contact = [];
// ^^
The last line
info.pickup.push(info.pickup.contact);
makes no sense, because you have properties in this object. For pushing some values, you need an array
info.pickup = [];
// ^^
An while you already have an array for info.pickup.contact, you could skip the line
info.pickup.push(info.pickup.contact);

It's important to understand the difference between an object and an array.
{} creates a plain object, which doesn't have a push method.
[] creates an array, which is an object with additional features, including a push method.
Looking at your code, at the least, you want info.pickup.contact and probably info.delivery.contact to be arrays (I'm guessing probably items_quantity and items as well, but it's hard to be sure). (The thing you call arr in your looping function isn't an array and doesn't need to be.)
So at a minimum:
info.pickup.contact = [];
// -------------------^^
and
info.delivery.contact = [];
// ---------------------^^
You also want to remove the info.pickup.push(info.pickup.contact); at the end; info.pickup isn't an array, and you've already put the contacts in info.pickup.contact.
Side note: Your code might also benefit from using object initializers:
var info = {
pickup: {
contact: [],
items_quantity: {}, // This might also want to be an array
items: {} // This might also want to be an array
},
delivery: {
contact: [],
level: {} // No idea what you're doing with this, so...
}
};
$('.operation-create .pickup .contact-details').each(function () {
info.pickup.contact.push({
contact_name: $(this).find('input[name="pickup-contact-name"]').val(),
contact_phone: $(this).find('input[name="pickup-contact-phone"]').val(),
pickup-suburb: $(this).find('select[name="pickup-suburb"]').val(),
single-pickup-address: $(this).find('input[name="single-pickup-address"]').val()
});
});
...but it's a matter of style.

info.pickup.contact = {};
That is an object declaration, not array.
An array should be
info.pickup.contact = []; // `[]`

As the other answers have stated you need to change the contact from an object (ie. {}) to an array ([]).
Also note that you can use jQuery's map() to build the array and make the code a little more succinct:
info.pickup.contact = $('.operation-create .pickup .contact-details').map(function () {
return {
contact_name: $(this).find('input[name="pickup-contact-name"]').val(),
contact_phone: $(this).find('input[name="pickup-contact-phone"]').val(),
pickup-suburb: $(this).find('select[name="pickup-suburb"]').val(),
single-pickup-address: $(this).find('input[name="single-pickup-address"]').val()
}
}).get();

You need an array in order to push a element into it. Here it is object so obviously it is not possible for you to add.
if you want to add then make it as array like
info.pickup.contact = [];
now if you add then it will accept. After adding, your array will be like follows..
info.pickup.contact = [];
info.pickup.contact.push("Sample");
{"pickup":{"contact":["Sample"]}}

Related

push Object in array in $.each

Maybe I'm just blind, but I'm struggling for a good amount of time now:
I have a small piece of JS-Code here:
var linkInput = $('#Link input.gwt-TextBox').val();
var parentRow = $('#Link').parent().parent();
var links = linkInput.split("|");
// hide text-input
$(parentRow).hide();
// get rid of empty elements
links = links.filter(Boolean);
var aSites = [];
var oSite = {};
$(links).each(function (k, v) {
splits = v.split(".");
domainName = splits[1];
oSite.name = domainName;
oSite.url = v;
aSites.push(oSite);
});
console.log(aSites);
To specify: Get the value of an input-field, hide the row afterwards and save all the values in an object, which is then pushed into an array.
The parameter, taken from the console-tab of google Chrome:
var links = ["www.myshop1.de/article/1021581", "https://www.myshop2.de/article/1021581"] [type: object]
I thought, I iterate through all elements of this object (in that case 2 times), push the values into an object and the object into an array, to have access to all of them afterwards.
At some point however, I seem to override my former values, since my output looks like this:
0: {name: "myshop1", url: "https://www.myshop1.de/1021581"}
1: {name: "myshop2", url: "https://www.myshop2.de/1021581"}
length: 2
__proto__: Array(0)
Where is my mistake here? Is there a smarter way to realize this?
On a sidenote:
I tried to use only an array (without adding an object), but it seems like I
can't use an associative key like this:
var myKey = "foo";
var myValue = "bar";
myArray[myKey] = myValue
You should move this:
var oSite = {};
...inside the each callback below it, because you need a new object in each iteration.
Otherwise you are mutating the same object again and again, pushing the same object repeatedly to the aSites array, which ends up with multiple references to the same object.
Not related, but you can use $.map to create your array (or vanilla JS links.map()):
var aSites = $.map(links, function(v) {
return { name: v.split(".")[1], url: v };
});

Push to a javascript array if it exists, if not then create it first

Is there a way for this line to always work and not throw TypeError: Cannot read property 'Whatever' of undefined
var MyArray = [];
MyArray[StringVariableName][StringVariableName2].push("whatever");
Try this:
var MyArray = [];
MyArray[StringVariableName] = MyArray[StringVariableName] || [];
MyArray[StringVariableName][StringVariableName2] = MyArray[StringVariableName][StringVariableName2] || [];
MyArray[StringVariableName][StringVariableName2].push("whatever");
You could even, through the power of expressions, do this with a one-liner.
(MyArray[StringVariableName][StringVariableName2] || (MyArray[StringVariableName][StringVariableName2] = [])).push("whatever");
You could use the literal syntax to set things up like you'd have them:
var myObj = {
StringVariableName: {
StringVariableName2: []
}
};
myObj.StringVariableName.StringVariableName2.push("whatever");
I think instead of using array in the first place, use object if your keys are not integers.
In Javascript Arrays are also object So it is not wrong to do this
var a = [];
a['key'] = 'something';
console.log(a); //Gives []
I think it is conceptually wrong So instead of using Array to hold such pair of data you should use objects. See this:
var myObject = myObject || {};
myObject[str1] = myObject[str1] || {};
myObject[str1][str2] = myObject[str][str2] || [];
// Now myObject[str1][str2] is an array. Do your original operation
myObject[str1][str2].push("whatever");
To check without getting an error:
this snippet allows you to check if a chained object exists.
var x;
try{x=MyArray[name1][name2][name3][name4]}catch(e){}
!x||(x.push('whatever'));
from
https://stackoverflow.com/a/21353032/2450730
Shorthand creation of object chains in Javascript
this function allows you to create chained objects with a simple string.
function def(a,b,c,d){
c=b.split('.');
d=c.shift();//add *1 for arrays
a[d]||(a[d]={});//[] for arrays
!(c.length>0)||def(a[d],c.join('.'));
}
usage
var MyArray={};//[]
def(MyArray,'name1.name2.name3.name4');//name1+'.'+name2....
from
https://stackoverflow.com/a/21384869/2450730
both work also for arrays with a simple change.replace {} with []
if you have any questions just ask.

JavaScript Two dimensional Array

I am creating javascript two dimensional array
code is :
var field_arr=[];
$(".dr").each(function(index){
Id=$(this).attr("id");
alert(dragId);
topPos=$("#"+ dragId).position().top;
left=$("#"+ dragId).position().left;
parentDiv=$("#"+dragId).parent().attr("id");
parentDiv= parentDiv.split('-');
paId=parentDiv[1];
field_arr[Id]=new Array();
field_arr[Id]['paId']=paId;
field_arr[Id]['top']=topPos;
field_arr[Id]['left']=left;
});
console.log(field_arr);
Output Is:
[undefined, [] left 140 paId "1" top 10
What is problem in It Any help Should be appreciated.
The problem is in the display method of your arrays. The information is there, but both alert and console.log will not show it to you because it is expected that the only interesting properties of arrays are the ones with numeric indexes.
In JavaScript, unlike PHP, objects are used as maps/associative arrays.
First to check that your information is actually there:
$(".dr").each(function(index){
var Id=$(this).attr("id");
console.log(Id, field_arr[Id]['paId'], field_arr[Id]['top'], field_arr[Id]['left']);
});
Now to make make the display methods work you can go about multiple ways, but the best one is to use objects instead:
var field_arr = Object.create(null); // replace with {} if you want to support IE8-
$(".dr").each(function(index){
var id = $(this).attr("id"); // added var to keep variable local
var drag = $("#"+dragId);
field_arr[id] = Object.create(null); // {}
field_arr[id]['paId'] = drag.parent().attr("id").split('-')[1];
field_arr[id]['top'] = drag.position().top;
field_arr[id]['left'] = drag.position().left;
});
console.log(field_arr);
Iterating over properties of objects is quite easy:
for (var id in field_arr) {
console.log(field_arr[id], field_arr[id]['paId'], 'etc');
}
Add a hasOwnProperty check if your object doesn't inherit from null (var obj = {} needs it, unlike var obj = Object.create(null))
you're storing values with a key string and its wrong because you declared your field_arr as a numerical array (well there's no such thing as associative array in javascript i think).
field_arr[Id] = new Array();
field_arr[Id]['paId']=paId; //this is wrong
You need to create an object to store in values as if they are associated with string keys. But literally they are object properties
redeclare it like this
field_arr[Id] = {}; //you create an object
field_arr[Id]['paId'] = paId; //create an object property named paId and store a value
field_arr[Id].paId = paId; //you can also access property paId like this
EDIT:
but to conform to you current code you can access your indexes using strings by accessing it like a property of an object. (Thanks to Tibos)
var field_arr=[];
...
...
field_arr[Id].paId = paId;

creating multi-dim arrays (JS)

I was trying to create a 3-dimensional array and couldn't find an easy way to do it.
array = [[[]]];
or
array = [][][];
or
array = []; array[] = []; array[][] = [];
would for example not work. (the console'd say the second array is 'undefined' and not an object, or for the second and third example give a parse error).
I cannot hard-code the information either, as I have no idea what the indexes and contents of the array are going to be (they are created 'on the fly' and depending on the input of a user. eg the first array might have the index 4192). I may have to create every array before assigning them, but it would be so much easier and faster if there's an easier way to define 3-dimensional arrays. (there'll be about 2 arrays, 25 subarrays and 800 subsubarrays total) every millisecond saves a life, so to say.
help please?
JavaScript is dynamically typed. Just store arrays in an array.
function loadRow() {
return [1, 2, 3];
}
var array = [];
array.push(loadRow());
array.push(loadRow());
console.log(array[1][2]); // prints 3
Since arrays in javascript aren't true arrays, there isn't really a multidimensional array. In javascript, you just have an arrays within an array. You can define the array statically like this:
var a = [
[1,2,3],
[4,5,6],
[7,8,9]
];
Or dynamically like this:
var d = [];
var d_length = 10;
for (var i = 0;i<d_length;i++) {
d[i] = [];
}
UPDATE
You could also use some helper functions:
function ensureDimensions(arr,i,j,k) {
if(!arr[i]) {
arr[i] = [];
}
if(!arr[i][j]) {
arr[i][j] = [];
}
}
function getValue(arr,i,j,k) {
ensureDimensions(i,j,k);
return arr[i][j][k];
}
function setValue(arr,newVal,i,j,k) {
ensureDimensions(i,j,k);
arr[i][j][k] = newVal;
}

Jquery fill object like array

This should be pretty easy but I'm a little confused here. I want to fill this object:
var obj = { 2:some1, 14:some2, three:some3, XX:some4, five:some5 };
but in the start I have this:
var obj = {};
I´m making a for but I don't know how to add, I was using push(), but is not working. Any help?
You can't .push() into a javascript OBJECT, since it uses custom keys instead of index. The way of doing this is pretty much like this:
var obj = {};
for (var k = 0; k<10; k++) {
obj['customkey'+k] = 'some'+k;
}
This would return:
obj {
customkey0 : 'some0',
customkey1 : 'some1',
customkey2 : 'some2',
...
}
Keep in mind, an array: ['some1','some2'] is basicly like and object:
{
0 : 'some1',
1 : 'some2'
}
Where an object replaces the "index" (0,1,etc) by a STRING key.
Hope this helps.
push() is for use in arrays, but you're creating a object.
You can add properties to an object in a few different ways:
obj.one = some1;
or
obj['one'] = some1;
I would write a simple function like this:
function pushVal(obj, value) {
var index = Object.size(obj);
//index is modified to be a string.
obj[index] = value;
}
Then in your code, when you want to add values to an object you can simply call:
for(var i=0; i<someArray.length; i++) {
pushVal(obj, someArray[i]);
}
For info on the size function I used, see here. Note, it is possible to use the index from the for loop, however, if you wanted to add multiple arrays to this one object, my method prevents conflicting indices.
EDIT
Seeing that you changed your keys in your questions example, in order to create the object, you can use the following:
function pushVal(obj, value, key) {
//index is modified to be a string.
obj[key] = value;
}
or
obj[key] = value;
I'm not sure how you determine your key value, so without that information, I can't write a solution to recreate the object, (as is, they appear random).

Categories