Reputation: 832
I am making a page that sorts values in an array by name, and then when I click on a button "write to cookie" it should store it, then I click on sort by age and then click on a button "read from cookie" the new output should be the list that I stored when I clicked on "write to cookie" previously.
I keep getting an error when I click on "read from cookie":
index.html :
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: tahoma, sans-serif;
padding: 1em;
}
div {
padding: 1em;
}
h3 {
margin-bottom: -0.5em;
}
</style>
</head>
<body>
<input type="button" onclick ="sortByAge()" value="Age Sort"/>
<input type="button" onclick ="sortByName()" value="Name Sort"/>
<input type="button" onclick="writePerson()" value="Write List to Cookie" />
<input type="button" onclick="readPerson()" value="Read List from Cookie" />
<h3>Person List</h3>
<div id="contacts"></div>
<script src="sort.js"></script>
<script src="CookiesWithObjects.js"></script>
<script>
// If you do not use this and you misspell a variable name, one is auto-declared.
"use strict";
//debugger;
function refreshPersonList() {
var output = "";
for (var i = 0; i < personList.length; i++) {
output += personList[i].getName() + " " + personList[i].getAge() + "<br/>";
}
document.getElementById("contacts").innerHTML = output + "<br/>";
}
function sortByName() {
console.log("to sort by name");
sortByKey(personList, "getName()");
refreshPersonList();
}
function sortByAge() {
console.log("to sort by age");
sortByKey(personList, "getAge()");
refreshPersonList();
}
function writePerson() {
Cookie.setCookieObj("myPerson", personList, 365);
}
function readPerson() {
personList = Cookie.getCookieObj("myPerson");
refreshPersonList();
}
function MakePerson(newName, newAge) {
var person = {};
person.name = newName;
person.age = newAge;
return person;
}
// main program
var personList = []; // empty array
personList[0] = new MakePerson("sally", 20);
personList[1] = new MakePerson("abe", 40);
personList[2] = new MakePerson("dave", 35);
personList[3] = new MakePerson("frank", 55);
personList[4] = new MakePerson("ellie", 15);
personList[5] = new MakePerson("debbie", 60);
refreshPersonList();
</script>
</body>
</html>
CookieWithObjects.js :
var Cookie = {};
Cookie.setCookie = function (cname, cvalue, exdays) {
if (!exdays) {
exdays = 365;
}
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
console.log("cookie stored");
};
Cookie.setCookieObj = function (cname, cObj, exdays) {
var jsonString = JSON.stringify(cObj);
Cookie.setCookie(cname, jsonString, exdays);
};
Cookie.getCookie = function (cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
console.log("cookie read");
return "";
};
Cookie.getCookieObj = function (cname) {
var jsonString = Cookie.getCookie(cname);
if (!jsonString) {
return null;
}
jsonString = "(" + jsonString + ")";
var obj = eval(jsonString);
return obj;
};
sort.js :
// array is the array you want to sort
// key is the name of the property by which you want to sort (in quotes)
function sortByKey (array, getter) {
/* .sort is a built-in array method provided by javaScript.
*
* .sort expects you to provide a function (such as the unnamed function below)
* that takes two elements of the array (a and b in the code below) and returns either
* 1 (if the first element is larger than the second) or
* -1 if the second element is larger that the first, or
* 0 if both elements are equal. */
return array.sort(function (a, b) {
// a and b are two elements of the array to be compared
/* These two lines of code extract the key property from the objects
* to be compared.
*
* These two lines of code use JavaScript's eval keyword that allows you
* to run (as code) whatever is stored inside of a string variable.
* Example: if the user invoked sortByKey(myList, "getName()") then
* the following line of code would execute a.getName() where a is an
* element of myList such as myList[3] */
var akey = eval("a."+getter);
var bkey = eval("b."+getter);
// If the values to be compared are character, convert to lower case
// so that it sorts characters as you would expect: "a" not larger than "A".
if (typeof akey === "string") {
akey = akey.toLowerCase();
}
if (typeof bkey === "string") {
bkey = bkey.toLowerCase();
}
// If the values to be compared are numeric, make sure to compare them numerically
// not treating the digits like characters.
if (!isNaN(akey)) {
akey = Number(akey);
}
if (!isNaN(bkey)) {
bkey = Number(bkey);
}
// The meat of the function is to return -1 if the first element is < the second
// or 1 if first element is > second element (or 0 if they are equal) - based on the
// key field by which you are comparing
var returnVal=0;
if (akey < bkey) {
returnVal = -1;
} else if (akey > bkey) {
returnVal = 1;
}
// This is the badly documented code I replaced...
//var returnVal = ((x < y) ? -1 : ((x > y) ? 1 : 0));
console.log("comparing " + akey + " to " + bkey + " yields " + returnVal);
return returnVal;
});
}
Upvotes: 1
Views: 607
Reputation: 1256
Instead of eval()
try using JSON.parse()
because eval()
doesn't return the object. It just evaluates it.
Cookie.getCookieObj = function (cname) {
var jsonString = Cookie.getCookie(cname);
if (!jsonString) {
return null;
}
var obj = JSON.parse(jsonString);
return obj;
};
And most importantly change your constructor's getAge(), getName() methods to properties.
function MakePerson(newName, newAge) {
var person = {};
person.getAge = newAge;
person.getName = newName;
return person;
}
I have tested entire code on the jsFiddle.
Upvotes: 1
Reputation: 11940
You have 2 problems
Your MakePerson
is a class, and the instance doesn't have properties
So when storing Cookie.setCookieObj("myPerson", personList, 365)
It actually stores
myPerson [{},{},{},{},{},{}]
You need to persist properties
function MakePerson(newName, newAge) {
var person = {};
person.name = newName;
person.age = newAge;
return person;
}
You return null
in Cookie.getCookieObj
But you are not checking the value in refreshPersonList function
function refreshPersonList() {
var output = "";
if (personList && personList.length) { // <== added check
for (var i = 0; i < personList.length; i++) {
// change getName()/getAge() to name/age
output += personList[i].name + " " + personList[i].age + "<br/>";
}
document.getElementById("contacts").innerHTML = output + "<br/>";
}
}
Also Harun Diluka Heshan made good point, you must JSON.parse
, not eval
Upvotes: 1