I keepy getting TypeError: testsession.testset[0].athletes is undefined - i have tried lots of different ways, is it not possible to have an array of arrays of objects
var testsession = {};
var testsetname = {};
var testset = [];
testsession.testsetname = testsetname;
testsession.testsetname = "week9";
testsession.testset = testset;
testsession.testset.push("400M");
testsession.testset.push("800M");
var athletes = [];
var Time = "49.2";
var AthleteID = "a92";
var athlete = { "AthleteID": AthleteID, "Time": Time};
//console.log(pointer);
testsession.testset[0].athletes = athletes;
testsession.testset[0].athletes.push(athlete)
console.log(testsession.testset[0].athletes[0]);
The testset[0] is a string. Make it an object
var testsession = {};
var testsetname = {};
var testset = [];
testsession.testsetname = testsetname;
testsession.testsetname = "week9";
testsession.testset = testset;
//Earlier you pushed 400m directly which is a string hence causing the error later on
testsession.testset.push({distance: "400M"});
testsession.testset.push({distance: "800M"});
var athletes = [];
var Time = "49.2";
var AthleteID = "a92";
var athlete = { "AthleteID": AthleteID, "Time": Time};
//console.log(pointer);
testsession.testset[0].athletes = athletes;
testsession.testset[0].athletes.push(athlete)
console.log(testsession.testset[0].athletes[0]);
testsession.testset[0] is a primitive value, a string.
The following statement will therefore not have the effect you may think it has:
testsession.testset[0].athletes = athletes;
What happens here? The primitive at the left has no athletes property, but JavaScript will coerce it to a String object, then assign that property to that temporary String object, which then disappears into oblivion.
So it is like that assignment never happened: testsession.testset[0] will remain a primitive value, and primitive values have no properties.
When you read the athletes property, the same will happen again: JavaScript coerces it to a String object, only to find that object has no athletes property, and so you get undefined.
When you try to access testsession.testset[0] that entry is a string. You maybe at least would like to set testsession.testset[0] = {}; before accessing its members.
I think you are working code like this.
<script >
var testsession = {};
testsession.testset = [];
testsession.testset.push({testsetname:"week9"});
testsession.testset[0].list = [];
testsession.testset[0].list.push({distance:"400M"});
testsession.testset[0].list[0].athletes = [];
testsession.testset[0].list[0].athletes.push({ AthleteID: "a92", Time: "49.2"});
testsession.testset[0].list.push({distance:"900M"});
testsession.testset[0].list[1].athletes = [];
testsession.testset[0].list[1].athletes.push({ AthleteID: "a93", Time: "99.2"});
console.log(testsession);
</script>
and result will be like that:
"{"testset":[{"testsetname":"week9","list":[{"distance":"400M","athletes":[{"AthleteID":"a92","Time":"49.2"}]},{"distance":"900M","athletes":[{"AthleteID":"a93","Time":"99.2"}]}]}]}"
Related
I have taken a string that is "title:artist" and used str.split :
res = song.split(":");
Which gives me an output of :
["Ruby","Kaiser Chiefs"]
I was wondering how I could add name to this so that it appears as :
["name":"Ruby", "artist":"Kaiser Chiefs"]
var res = song.split(':');
var jsonString = JSON.stringify({ name: res[0], artist: res[1] });
You can find more information about how to use JSON.stringify here but basically what it does is takes a JavaScript object (see how I'm passing the data as an object in my answer) and serializes it into a JSON string.
Be aware that the output is not exactly as you have described in your question. What you have is both invalid JavaScript and invalid JSON. The output that I have provided will look more along the lines of {"name":"Ruby", "artist":"Kaiser Chiefs"}. Notice how there is {} instead of [].
["name":"Ruby", "artist":"Kaiser Chiefs"] isn't a valid format I guess you want to create an object so you could use just the split like :
var my_string = "Ruby:Kaiser Chiefs";
var my_string_arr = my_string.split(':');
var my_object = {'name': my_string_arr[0],"artist": my_string_arr[1]};
console.log(my_object);
Or also assign the values to the attributes separately like:
var my_string = "Ruby:Kaiser Chiefs";
var my_string_arr = my_string.split(':');
var my_object = {};
my_object.name = my_string_arr[0];
my_object.artist = my_string_arr[1];
console.log(my_object);
Hope this helps.
What you're looking for is: Object. Here is how you do it:
var str = "Ruby:Kaiser Chiefs";
var res = str.split(':');
// this is how to declare an object
var myObj = {};
// this is one way to assigne to an object
// using: myObj["key"] = value;
myObj["name"] = res[0];
// this is another way to assign to an object
// using: myObj.key = value;
myObj.artist = res[1];
console.log(myObj);
suppose i receive JSON object from the server as this
{ "asdf[zxcv]": "qwer" }
how do i access asdf, zxcv, and qwer in javascript, so i can use the object this way ?
theobj.asdf[zxcv] = 'qwer'
Bracket notation is not in the JSON RFC. You can only read it as string.
var simpleObj = {
"simpleKey": "simpleValue"
}
console.log(simpleObj)
var advObj = {
"advKey[1]": "advValue"
}
console.log(JSON.parse(advObj)); // SyntaxError
console.log(advObj.advKey[1]) // TypeError
console.log(advObj["advKey[1]"]) // can only read as string
You would need to refactor the source JSON into something more meaningful so you can access the values in regular JavaScript way.
Run the following snippet to check how you can solve the issue:
var x = '{ "asdf[zxcv]": "qwer" }';
var y = JSON.parse(x);
var result = Object.keys(y).reduce(function(result, key) {
var parentKey = key.substring(0, key.indexOf("["));
var innerKey = /[a-z]+\[([a-z]+)\]/i.exec(key)[1];
if (!result.hasOwnProperty(key))
result[parentKey] = {};
result[parentKey][innerKey] = y[key];
return result;
}, {});
document.getElementById("structure").textContent = JSON.stringify(result);
var zxcv = result["asdf"]["zxcv"];
document.getElementById("someValue").textContent = zxcv;
<h2>Refactored data structure as nested objects:</h2>
<div id="structure"></div>
<h2>Accessing some value: result["asdf"]["zxcv"] or result.asdf.zxcv</h2>
<div id="someValue"></div>
It's all about creating nested objects to represent the associative keys in the source JSON properties representing a conceptual associative array...
This is one of the way to access all elements without reconstructing object.
jQuery.each(JSON.parse('{ "asdf[zxcv]": "qwer" }'), function(index, value) {
var i = index;// i = "asdf[zxcv]"
var v = value;// v = "qwer"
var iOfInnerValue = (/\[(.*?)\]/g).exec(i)[1];// innerValue = "zxcv"
var iOfOuterValue = index.replace("["+(/\[(.*?)\]/g).exec(i)[1]+"]",""); // outerValue = "asdf"
});
You'll need to assign the data to a variable and then you can use Object keys to get the key which is the part before the :. Here's an example.
var j = { "asdf[zxcv]": "qwer" };
console.log(Object.keys(j)); //["asdf[zxcv]"]
console.log(j); //{asdf[zxcv]: "qwer"}
So, I am having an issue and for the life of me I cannot seem to resolve it. It seems very basic, but I just cannot understand for the life of me why this code is not working.
My issue is, I am assigning a key value pair to an array, but the values DO NOT get assigned. Is it a variable scope issue?
Here is my code
function getcookie(cookiename){
var mycookies = []; // The cookie jar
var temp = document.cookie.split(";");
var key = "";
var val = "";
for(i=0;i<temp.length;i++){
key = temp[i].split("=")[0];
val = temp[i].split("=")[1];
mycookies[key] = val;
}
return mycookies[cookiename];
}
Trim your key because cookie strings look like this:
"__utma=250730393.1032915092.1427933260.1430325220.1430325220.1; __utmc=250730393; __utmz=250730393.1430325220.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); clicks=22; _gat=1; _ga=GA1.2.1032915092.1427933260"
so when you split on ; there will be an extra space before some of the key names.
function getcookie(cookiename){
var mycookies = []; // The cookie jar
var temp = document.cookie.split(";");
var key = "";
var val = "";
for(i=0;i<temp.length;i++){
key = temp[i].split("=")[0].trim(); // added trim here
val = temp[i].split("=")[1];
mycookies[key] = val;
}
return mycookies[cookiename];
}
Demo: JSBin
mycookies should be populated assuming temp.length is greater than 0. Your return value is always going to be undefined; mycookies[cookiename] is never assigned a value.
Try adding console.log(mycookies) just before your return statement.
Mycookies should be an Object, not an Array.
var mycookies = {};
JavaScript arrays are not associative arrays, only possible index values are numerical, starting with 0 and ending at array.length - 1. What you might have seen in examples before or used in another language before was JavaScript object, which does, in fact, behave as an associative array. You can access object values by object['key'] or as object.key. The first is used only when accessing key using a variable or a key which includes illegal characters, i.e. some-key, otherwise it's recommended to use dot access, as illustrated in second example.
Therefore your mycookies variable should be an object, not an array.
If you change your line var mycookies = []; to var mycookies = {};, i.e. change it from empty array to empty object, the remaining code should work as you expected.
Here is an example snippet for fixed code, I added a mock cookies string so it can work reliably:
var mockCookies = "a=1;b=2;c=3";
function getcookie(cookiename){
var mycookies = {}; // The cookie jar
var temp = mockCookies.split(";");
var key = "";
var val = "";
for(i=0;i<temp.length;i++){
key = temp[i].split("=")[0];
val = temp[i].split("=")[1];
mycookies[key] = val;
}
return mycookies[cookiename];
}
function printCookie(name) {
alert(getcookie(name));
}
<button onclick="printCookie('a')">Get a</button>
<button onclick="printCookie('b')">Get b</button>
<button onclick="printCookie('c')">Get c</button>
My friend, you are a little confused (maybe you have programmed in PHP) because in JavaScript, an Array is not a associative key : value object, it is an indexes based object. But what you looking for is an Object Literal
function getcookie (cookiename){
var i, max, keyvalue, key, val,
cookiesObj = {}, //empty object literal
cookiesArr = document.cookie.split(";");
for(i=0, max=cookiesArr.length; i<max; i+=1) {
keyvalue = cookiesArr[i].split("=");
key = keyvalue[0].trim();
val = keyvalue[1].trim();
cookiesObj[key] = val;
}
return cookiesObj[cookiename];
}
But you can refactor your code:
function getcookie (cookiename) {
var cookie = "",
cookies = document.cookie.split(";");
cookies.forEach(function (item) {
var keyvalue = item.split("="),
key = keyvalue[0].trim(),
val = keyvalue[1].trim();
if (key === cookiename) {
cookie = val;
return false; //exit from iteration
}
});
return cookie;
}
I'm trying to stringify an object but don't know why it is not working as expected:
function request(url) {
this.url = url;
this.head = [];
}
var r = new request("http://test.com");
r.head["cookie"] = "version=1; skin=new";
r.head["agent"] = "Browser 1.0";
document.write(JSON.stringify(r));
I hope this object can be stringified as:
{"url":"http://test.com","head":["cookie":"version=1; skin=new", "agent":"Browser 1.0"]}
But I only get:
{"url":"http://test.com","head":[]}
How to fix it?
You want the hear property of r to be an associative array I think (like in PHP). They don't exist in JavaScript. Array's have values that are indexed by a number.
Since r.head is an object (array is object in JS) you can add properties to it with r.head["whatever property name"]="value" but these properties don't seem to be serialized to JSON when you use JSON.stringify because r.head is defined as an array and it'll only serialize the numbered index values.
To fix this you can define r.head as an object so JSON.stringify will serialize all properties.
function request(url) {
this.url = url;
this.head = {};
}
var r = new request("http://test.com");
r.head["cookie"] = "version=1; skin=new";
r.head["agent"] = "Browser 1.0";
document.write(JSON.stringify(r));
If you run the following code in your cosole (press F12 in your browser) you'd see that arrays are not serialized in the same way as objects are:
var b = [];
b.something=22
console.log(b.something);
console.log(JSON.stringify(b));//=[]
console.log(b.hasOwnProperty("something"))//=true
b = {};
b.something=22
console.log(b.something);
console.log(JSON.stringify(b));//={"something":22}
console.log(b.hasOwnProperty("something"))//=true
It would be impossible to serialize it the way you are hoping to.
With this object:
function request(url) {
this.url = url;
this.head = [];
}
This variation:
var r = new request("http://test.com");
r.head.push({"cookie": "version=1; skin=new"});
r.head.push({"agent": "Browser 1.0"});
document.write(JSON.stringify(r));
would give you:
{"url":"http://test.com","head":[{"cookie":"version=1; skin=new"},{"agent":"Browser 1.0"}]}
If you were to change the object to:
function request(url) {
this.url = url;
this.head = {};
}
var r = new request("http://test.com");
r.head["cookie"] = "version=1; skin=new";
r.head["agent"] = "Browser 1.0";
document.write(JSON.stringify(r));
would give you:
{"url":"http://test.com","head":{"cookie":"version=1; skin=new","agent":"Browser 1.0"}}
The first variation is guaranteed to give you the head values in order when you iterate it. It also has the advantage in that you can later insert things in specific order if that is of interest.
The second version, by convention, will give you the items back in the order they were inserted as long as there are no number based keys, but that ordering is not guaranteed by the ecma spec.
Not sure what to search for here, so apologies if I'm repeating another question.
I'm wondering if there are any issues that I'm not aware of with using the following syntax in JavaScript:
var a = {};
var b = a.niceCoat = {};
Seems handy, but I just want to make sure...
That is perfectly fine, because a was declared previously. The expressions will be evaluated as
var a = {};
var b = (a.niceCoat = {});
I.e. it first assigns a new empty object to a.niceCoat and the result (the result of an assignment is the assigned value) to b.
But be aware of something like
var a = b = 'c';
which, again, is evaluated as
var a = (b = 'c');
Only a will be in local scope, b would be global. If you want b to be local too, you have to declare it beforehand: var b;. Something like var a = var b = .... does not work (not valid syntax).
Slightly off topic:
This method is indeed handy. Imaging you have an object of objects, something like:
var map = {
foo: {},
bar: {}
};
and you want to get the object for a certain key or create a new one if the key does not exists. Normally one would probably do:
var obj = map[key];
if(!obj) { // works because if the key is set, it is an object
obj = {}; // which evals to true
map[key] = obj;
}
// now work with obj
With the above method, this can be shortened to
var obj = map[key];
if(!obj) {
map[key] = obj = {};
}
And we can make it even shorter with the logical OR operator (||):
var obj = map[key] || (map[key] = {});
(though it might be less readable).
You can do that. a.niceCoat = {} will be evaluated first, which assigns the object to the property and also has the object as result, which you then can assign to the variable.
You should however be aware that b and a.niceCoat are now referencing the same object, so if you put anything in the object it will show up for both the variable and the property:
var a = {};
var b = a.niceCoat = {};
b.x = 42;
alert(a.niceCoat.x); // shows 42
There no issue with that. It's the same as:
var b = (a.niceCoat = {});
Which is the same as:
a.niceCoat = {};
var b = a.niceCoat; // Now b and a.niceCoat are the same object
Just be careful with declaring entirely new variables with it like:
var i = j = 0;
Which is the same as:
j = 0;
var i = j;
Notice how j is not declared with the var keyword.
this is how you create an empty object in javascript. nothing wrong with it.
Yep, absolutely valid.
E.g.
var a = {};
var b = a.niceCoat = {};
a.foo = function() { alert('foo!'); };
a.foo(); // shows the alert