Javascript array object fails throwing "object error" in IE - javascript

I have a javascript array object like
{arr = {"0":{"name":"henry","role":"user"},"1":{"name":"mark","role":"admin"}}
I have a html which requests this array from my server( by including a script tag with url to my server function that serves this array}
The problem is that When I run my HTML file in firefox, it easily detects this array and does the further processing with it but On IE , when I try to access the elements of the array, it throws an exception (object is null or undefined).
Any idea why element detection could be failing in IE.
How do we find out the properties of an array object in IE?

That is not really an array, is simply an object literal with numeric properties, you should iterate it by using the for...in statement:
var arr = {"0":{"name":"henry","role":"user"},
"1":{"name":"mark","role":"admin"}};
for (var key in arr) {
if (arr.hasOwnProperty(key)) {
// value = arr[key];
}
}
But I think you should simply return a real Array:
var arr = [{"name":"henry","role":"user"},
{"name":"mark","role":"admin"}];

Related

Comparison between normal array vs generated by back-tick array

I am creating an array by two way.
my first way is creating an array normally
my second way is creating an array by using backticks function
let array=["1234"];
function createArrayByBakticks(obj)
{
return obj;
}
let backtickArray = createArrayByBakticks `1234`;// it's responding an array
console.log(array); //1st way and it returns an array
console.log(backtickArray ); //2nd way and it returns a same array
backtickArray.push(1);// but it's throwing an error while push a new value.
// Error: Uncaught TypeError: Cannot add property 1, object is not extensible
console.log(backtickArray);
Above both ways are return as a array data. But the second array is not supporting inbuilt function of array which is generated by back-ticks. WHY? And what is the difference between in the both ways?
createArrayByBakticks is used as a so-called tag function. The first argument passed to the function is an array containing all strings of the template literal.
If you dive deep into the language specification, section 12.2.9.3, then you will see the following step is performed after the array has been created:
Perform SetIntegrityLevel(template, "frozen").
This means that in your case objis frozen and no property can be added. That's why invoking push doesn't work.
You can confirm this by calling console.log(Object.isFrozen(backtickArray)).
The array returns from the function by value, meaning it's immutable.
If you use concat, you'll get a new copy of it, which you can modify:
let array = ["1234"];
function createArrayByBakticks(obj) {
return obj;
}
let backtickArray = createArrayByBakticks `1234`; // it's responding an array
console.log(array); //1st way and it returns an array
console.log(backtickArray); //2nd way and it returns a same array
let newArray = backtickArray.concat(1); // a new mutable array is generated
newArray.push(2); // so you can even keep modifying it
console.log(newArray);

put content of all elements of class into array..why do i get these error messages

I'm trying to load text of all divs that have a particular class into an array, but this
var temp = $('.theClass').text();
temp = temp.toArray();
console.log(temp);
keeps giving me the error
Uncaught TypeError: Object has no method 'toArray'
And
var tempArr = [];
var temp = $('.theClass').text();
for (var t in temp){
tempArr.push(t);
}
console.log(tempArr);
results in an array filled with many, many objects within objects just filled with integers.
An explanation of how to do this properly can be found here, but I wonder if someone could provide me with an explanation for why I get these errors. Thanks!
You can use map to iterate over each element of the matched set and return some data (in this case, the text). You can then use get to convert the resulting jQuery object into an actual array:
var arr = $('.theClass').map(function () {
return $(this).text();
}).get();
Your first attempt fails because the text method returns a string, and strings don't have a toArray method (hence your "Object has no method" error).
Your second attempt fails because you're iterating over the string with the for...in loop. This loop iterates over the characters of the string. Each iteration t is assigned the index of the character, so you end up with an array, with one element for each character in the string. You should never really be using a for...in loop for iterating over anything other than object properties, and even then, you should always include a hasOwnProperty check.

Creating multi-dimensional arrays in javascript, error in custom function

I was trying to define an array (including other arrays as values) in a single javascript statement, that I can loop through to validate a form on submission.
The function I wrote to (try to) create inline arrays follows:
function arr(){
var inc;
var tempa = new Array(Math.round(arguments.length/2));
for(inc=0; inc<arguments.length; inc=inc+2) {
tempa[arguments[inc]]=arguments[inc+1];
}
return tempa;
}
This is called three times here to assign an array:
window.validArr = arr(
'f-county',arr('maxlen',10, 'minlen',1),
'f-postcode',arr('maxlen',8, 'minlen',6)
);
However in the javascript debugger the variable is empty, and the arr() function is not returning anything. Does anyone know why my expectations on what this code should do are incorrect?
(I have worked out how to create the array without this function, but I'm curious why this code doesn't work (I thought I understood javascript better than this).)
Well from what your code does, you're not really making arrays. In JavaScript, the thing that makes arrays special is the management of the numerically indexed properties. Otherwise they're just objects, so they can have other properties too, but if you're not using arrays as arrays you might as well just use objects:
function arr(){
var inc;
var tempa = {};
for(inc=0; inc<arguments.length; inc=inc+2) {
tempa[arguments[inc]]=arguments[inc+1];
}
return tempa;
}
What you're seeing from the debugger is the result of it attempting to show you your array as a real array should be shown: that is, its numerically indexed properties. If you call your "arr()" function as is and then look at (from your example) the "f-county" property of the result, you'll see something there.
Also, if you do find yourself wanting a real array, there's absolutely no point in initializing them to a particular size. Just create a new array with []:
var tempa = [];
Your code works. Just inspect your variable, and you will see that the array has the custom keys on it. If not expanded, your debugger shows you just the (numerical) indixed values in short syntax - none for you.
But, you may need to understand the difference between Arrays and Objects. An Object is just key-value-pairs (you could call it a "map"), and its prototype. An Array is a special type of object. It has special prototype methods, a length functionality and a different approach: to store index-value-pairs (even though indexes are still keys). So, you shouldn't use an Array as an associative array.
Therefore, their literal syntax differs:
var array = ["indexed with key 0", "indexed with key 1", ...];
var object = {"custom":"keyed as 'custom'", "another":"string", ...};
// but you still can add keys to array objects:
array.custom = "keyed as 'custom'";

How to access fields in JSON object by index

I know this isn't the best way to do it, but I have no other choice :(
I have to access the items in JSONObject by their index. The standard way to access objects is to just wirte this[objectName] or this.objectName. I also found a method to get all the fields inside a json object:
(for (var key in p) {
if (p.hasOwnProperty(key)) {
alert(key + " -> " + p[key]);
}
}
(Soruce : Loop through Json object).
However there is no way of accessing the JSONfields directly by a index. The only way I see right now, is to create an array, with the function above, get the fieldname by index and then get the value by fieldname.
As far as I see it, the p (in our case the JSON file must be an iteratable array to, or else the foreach loop wouldn't work. How can I access this array directly? Or is it some kind of unsorted list?
A JSON Object is more like a key-value-map; so, yes, it is unsorted. The only way to get around is the index->property name map you've already mentioned:
var keysbyindex = Object.keys(object);
for (var i=0; i<keysbyindex.length; i++)
alert(object[keysbyindex[i]]);
But why would you need these indexes? A unsorted map also has no length property, as an Array had. Why don't you use the for-in-loop
var counter = 0; // if you need it
for (var key in object) {
alert(object[key])
counter++;
}
? If you have a parsed JSON object, i.e. a plain JS Object, you won't have to worry about enumerable prototype properties.
Based on Bergis anserwer this is my solution:
var keysbyindex = Object.keys(this);
alert(this[keysbyindex[index]]);
return this[keysbyindex[index] || ""];
However, I think (not tested) it's extremly bad regaring performace and shouldn't be used! But desperate times require desperate measures.....
I don't think you can actually achieve this without creating your own parsing of JSON. You're writing that you want to go trough a JSON-object, but what you're actually trying to do is go trough a plain old Javascript object. Json is simply a string-representation used to transfer/store said object, and in here lies the main problem: the parser that transforms the string into an actual object (ie. the browser in most cases) can chose to ignore the order it finds the properties if it want to. Also, different browsers might have different approaches to parsing JSON for all you know. If they simply use a hash-map for the object that it's simple to loop through it, but the order won't be dependent on the order of the keys in the file, but rather the keys themselves.
For example, if you have the json {"b":"b","a":"a"} and do the for in loop, under some implementations you might end up with a comming first, and in others you might end up with b.
var jsn = {keyName: 'key value result come here...'};
var arr = jsn ? $.map(jsn, function (el) { return el }) : [0];
console.log(arr[0])
$('.result').text(arr[0]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="result"></span>

jQuery delete array index

I'm having trouble deleting/removing an item from an Array in jQuery. I've run the results in console.log() and it shows up as an Object. I've created a function which returns a json string and then I parses it, an example below:
var ret = jQuery.parseJSON($.return_json(data));
It works nicely, however, I am running an $.each loop which removes items from that array/object.
var old = $("element").find("li[rel=item]");
$.each(old, function(index, value) {
ret.splice($(value).attr("id"), 1);
});
Above, I am searching for elements with attribute rel = item. The same element contains an id which is related to the index of the function which returns the json parsed variable.
I ran Developers Tools in Google Chrome to see the error and it prints:
Uncaught TypeError: Object #<Object> has no method 'splice'
Any words of guidance will be much appreciated. Thanks.
It seems like ret is not actually an array (and likely an object (ex: {someName: "someVal"}) instead).
I'm also making an assumption that you mean for $(value).attr("id") to be a string identifier like someName in the object example above. If that is the case and you are working with an object and you do have the appropriate property identifier, then luckily there is an easier solve than splice.
Try:
$("element").find("li[rel=item]").each(function() {
delete ret[$(this).attr("id")];
});
splice is only a method of arrays, not objects. ret in this case, is an object, not an array.
If you are trying to remove specific elements from an object, you can do this:
$("element").find("li[rel=item]").each(function(i,v){
delete ret[v.id];
});
ps. You can use .each instead of $.each.
If you really want to make the object into an array, you can simply loop through it and push the elements into an array.
var obj = {"1":"item 1", "2": "item 2", "3": "Item 3"};
var arr = [];
for(i in obj){
if(obj.hasOwnProperty(i)){
arr.push(obj[i]);
}
}
ret is the JSON object containing the array, and you can't splice it. You need to reference whatever you called the array within the object and splice that.
(Would help if you posted the code where you define the array).

Categories