Array in localStorage is not initialized at first run - javascript

window.reload = () => {
var userArray = JSON.parse(localStorage.getItem("key"));
}
let feedback = document.getElementById("feedback");
function checkemail(userArray, email) {
var i;
if (userArray == null | undefined) {
userArray = JSON.parse(localStorage.getItem("key"));
}
var person = {
name: document.getElementById("nameinput").value,
email: document.getElementById("emailinput").value,
passowrd: document.getElementById("passwordinput").value
};
let isFound = false;
for (i = 0; i < userArray.length; i++) { //here is the error it still happen even after I added the if null part
if (userArray != undefined)
var oldemail = userArray[i].email;
let newemail = document.getElementById("emailinput").value;
if (newemail === oldemail) {
isFound = true;
i = userArray.length;
return feedback.innerHTML = "email exist please log in or register with different email";
}
}
if (!isFound) {
return storeName(person, userArray);
}
}
function storeName(person, userArray) {
if (userArray != undefined)
var person = {
name: document.getElementById("nameinput").value,
email: document.getElementById("emailinput").value,
passowrd: document.getElementById("passwordinput").value
};
userArray = JSON.parse(localStorage.getItem("key"));
userArray.push(person);
userArray = JSON.stringify(userArray);
localStorage.setItem("key", userArray);
console.log(userArray);
}
I want to store an array in local storage, the first time when I run the code, of course, the array is empty and I can not use a loop for example because I can't call (array.length).
so can I tell the compiler for example if the array is null or undefined just put length is zero or assign the value of the array to an empty array?
can I do something like this?
if( userArray == null | undefined) { userArray = JSON.parse(localStorage.getItem("key")); }

function checkemail(userArray, email) {
if (userArray == null || typeof(userArray) == 'undefined') {
userArray = [];
}
// rest of the code
}
This might be working too:
userArray ??= [];

Related

How to check all input has value and do something

i have these inputs and i wanted to check every one of them has value then do something;
const tch_family_name = document.getElementById('tch_family_name');
const tch_lastname = document.getElementById('tch_lastname');
const tch_name = document.getElementById('tch_name');
const tch_phone = document.getElementById('tch_phone');
const first_alph = document.getElementById('first_alph');
const second_alph = document.getElementById('second_alph');
const third_alph = document.getElementById('third_alph');
const tch_bday = document.getElementById('tch_bday');
const textarea1 = document.getElementById('textarea1');
and I'm checking they have value or not like this
function checkEmpty(check) {
for (i = 0; i < check.length; i++) {
if (check[i].value == "" || check[i].value == " " || check[i].value == null) {
check[i].classList.add('inputErrorBorder')
} else {
check[i].classList.remove('inputErrorBorder')
}
}
}
//mainInfo button id
mainInfo.addEventListener('click', () => {
test = [tch_family_name, tch_lastname, tch_name, tch_phone, first_alph, second_alph, third_alph, tch_bday, textarea1]
checkEmpty(test)
})
now how to do something when all input have value;
I tried else if() but it gave an incorrect result for example when first input don't value then it wont add inputErrorBorder class to a second or third inputs.
Please help;
One of the easiest ways to add this to your current setup is to add a flag variable to the checkEmpty function and return that value. Then process the results in the EventListener
checkEmpty With hasEmpty Flag
function checkEmpty(check) {
let hasEmpty = false;
for (let i = 0; i < check.length; i++) {
if (check[i].value === "" || check[i].value === " " || check[i].value == null) {
check[i].classList.add('inputErrorBorder');
hasEmpty = true;
} else {
check[i].classList.remove('inputErrorBorder');
}
}
return hasEmpty;
}
Using hasEmpty flag from checkEmpty
mainInfo.addEventListener('click', () => {
let test = [tch_family_name, tch_lastname, tch_name, tch_phone,
first_alph, second_alph, third_alph, tch_bday, textarea1];
let hasEmpty = checkEmpty(test);
if (!hasEmpty) {
// All Have Value
} else {
// Something has missing value
}
})

How can I set array as a key value in javascript object?

I am trying to set an array as a key value in a JSON object using javascript.
When I set the array value,
console.log(obj["likes"]) displays an array of size 1.
but on the next line
console.log(obj) shows that the likes key is an array of size 0.
I have a JSON object that has information about posts.
If no likes exist on a post then that field does not exist in that post's objects.
I am trying to implement a like-dislike update function, where I check if a user has liked a post.
If he hasn't then I append his username to the array of likes else I remove his username.
userID is a global variable that I define at the start of the script tag.
It works if instead of userID, I set a new string like:
obj["likes"] = ["XX"]
This works too (i get an extra space but it atleast logs correctly):
obj["likes"] = [userId+" "]
console.log(obj["likes"])
console.log("Obj:",obj)
But then doing this again does not work!!!!
let arr = [" "+userId]
console.log(arr)
arr[0] = arr[0].trim()
console.log(arr)
obj["likes"] = arr
console.log("Obj:",obj)
function saveLikeDislike(url, action) {
for (i = 0; i < crawledUrlsData.length; i += 1) {
if (typeof crawledUrlsData[i] === "object") {
var obj = crawledUrlsData[i]
if (url === obj["url"]) {
if (action === "like") {
if ("likes" in obj) {
likes = obj["likes"]
if (likes.includes(userId)) {
likes = likes.filter(id => id != userId)
} else {
likes.push(userId)
}
obj["likes"] = likes
} else {
var id = window.userId
console.log(userId)
obj["likes"] = [id]
console.log(obj["likes"])
console.log("Obj:",obj)
}
if ("dislikes" in obj) {
var dislikes = obj["dislikes"]
if (dislikes.includes(userId)) {
dislikes = dislikes.filter(id => id != userId)
obj["dislikes"] = dislikes
}
}
} else {
if ("dislikes" in obj) {
dislikes = obj["dislikes"]
if (dislikes.includes(userId)) {
dislikes = dislikes.filter(id => id != userId)
} else {
dislikes.push(userId)
}
obj["dislikes"] = dislikes
} else
obj["dislikes"] = [dislikes]
}
if ("likes" in obj) {
var likes = obj["likes"]
if (likes.includes(userId)) {
likes = likes.filter(id => id != userId)
obj["likes"] = likes
}
}
}
crawledUrlsData[i] = obj
console.log(obj["likes"])
renderData()
return
}
}
}
Two problems.
1. That usrId - userId typo randomSoul has mentioned.
2. This line:
likes = likes.push(userId)
The output of likes.push(something) is a number, the length of the array after push. This line will amount to likes = 1. Do instead:
likes.push(userId)
push returns the new length of the array - so this line:
likes = likes.push(userId);
Will be a number, not an array - remove the assignment:
likes.push(userId);
Turnes out I had missed a parenthesis.
But this still does not explain the odd behavior where on one line key value was set and the very next line the output from console.log was different when accessing userId but proper if userId was modified in some way.
Anyway, here's the fixed function:
function saveLikeDislike(url, action) {
for (i = 0; i < crawledUrlsData.length; i += 1) {
if (typeof crawledUrlsData[i] === "object" && crawledUrlsData[i]["url"] == url) {
var obj = crawledUrlsData[i]
if (url === obj["url"]) {
if (action === "like") {
if ("likes" in obj) {
console.log("likes in obj")
likes = obj["likes"]
if (likes.includes(userId)) {
likes = likes.filter(id => id != userId)
} else {
likes.push(userId)
}
obj["likes"] = likes
} else {
obj.likes = [userId]
console.log("Obj:",obj)
}
if ("dislikes" in obj) {
var dislikes = obj["dislikes"]
console.log("Dislikes: ",dislikes)
if (dislikes.includes(userId)) {
dislikes = dislikes.filter(id => id != userId)
obj["dislikes"] = dislikes
}
}
} else if (action === "dislike"){
if ("dislikes" in obj) {
dislikes = obj["dislikes"]
if (dislikes.includes(userId)) {
dislikes = dislikes.filter(id => id != userId)
} else {
dislikes.push(userId)
}
obj["dislikes"] = dislikes
} else {
obj["dislikes"] = [userId]
}
if ("likes" in obj) {
var likes = obj["likes"]
console.log("ID: ",userId)
if (likes.includes(userId)) {
likes = likes.filter(id => id != userId)
obj["likes"] = likes
}
}
}
}
crawledUrlsData[i] = obj
linkTreeRef.set(crawledUrlsData)
}
}
}

Array contains only 1 value, so push fails

var user = {};
var usernameList = document.querySelectorAll('.msg.g_bot.bot.private.i ~ .msg .usr');
for (i of usernameList) {
if (i.childNodes[0].nodeName === 'SPAN') {
var theUser = (user[i.childNodes[0].innerHTML] !== undefined) ? user[i.childNodes[0].innerHTML] : user[i.childNodes[0].innerHTML] = {};
var msg = theUser.msg = [];
msg.push(i.nextElementSibling.nextElementSibling.innerHTML);
}
}
The object user.whatever.msg is an array but contains only 1 value. So it's always the last one. In this case push doesn't work, so I can't put all values into that array.
What's wrong with my code?
theUser.msg = []; does create a new array on every iteration. Just like you create a new theUser object only when it doesn't exist already, you should only create the msg array only once.
var users = {};
var usernameList = document.querySelectorAll('.msg.g_bot.bot.private.i ~ .msg .usr');
for (var i of usernameList) {
if (i.firstChild.nodeName === 'SPAN') {
var name = i.firstChild.innerHTML; // should be .textContent probably
var theUser = name in user
? user[name]
: user[name] = { msg: [] };
// ^^^^^^^^^
theUser.msg.push(i.nextElementSibling.nextElementSibling.innerHTML);
}
}
A clearer way of doing it would be to use .reduce:
const user = [...document.querySelectorAll('.msg.g_bot.bot.private.i ~ .msg .usr')]
.reduce((userObj, i) => {
if (i.childNodes[0].nodeName !== 'SPAN') return userObj;
const childHtml = i.childNodes[0].innerHTML;
const theUser = userObj[childHtml] || { msg: [] };
theUser.msg.push(i.nextElementSibling.nextElementSibling.innerHTML)
return userObj;
}, {});
You could modify your code to verify if the array was already created:
var user = {};
var usernameList = document.querySelectorAll('.msg.g_bot.bot.private.i ~ .msg .usr');
for (i of usernameList) {
if (i.childNodes[0].nodeName === 'SPAN') {
var theUser = (user[i.childNodes[0].innerHTML] !== undefined) ? user[i.childNodes[0].innerHTML] : user[i.childNodes[0].innerHTML] = {};
if(theUser.hasOwnProperty(‘msg’) === false) {
theUser.msg = [];
}
theUser.msg.push(i.nextElementSibling.nextElementSibling.innerHTML);
}
}

Javascript program keeps outputting wrong index of array

I'm trying to finish an assignment, I'm stuck at and can't find a solution.
Below is my full code.
//Student Object
var student = {
f_name: "",
l_name: "",
s_numb: "",
email: "",
courses: [],
/*This function returns if current object has a specific course
and returns true if it does and false if not.*/
hasCourse: function (course) {
for (var c = 0; c < this.courses.length; c++) {
if (course == this.courses[c]) {
return true;
}
}
return false;
}
};
/*This function returns name with first letter
capitalized and the rest lowercase.*/
function formatingName(name) {
return name.charAt(0).toUpperCase() + name.substr(1, name.length);
}
/*This function validates to match the Student ID pattern and
returns true it matches and false if not.*/
function validateStudentID(sid) {
var patt = /^([0-9]{3}[.]){2}[0-9]{3}$/;
return patt.test(sid);
}
/*This function receives a string array of course codes which
are to be registered for a student. The function returns an empty
string indicating all course codes in the array are valid; otherwise
the function returns the first invalid course code in the array.*/
function validateCourses(courses) {
var error = false;
for (i = 0; i < courses.length; i++) {
if (error == false) {
if (courses[i] != "APC100" && courses[i] != "IPC144" &&
courses[i] != "ULI101" && courses[i] != "IOS110" &&
courses[i] != "EAC150" && courses[i] != "IBC233" &&
courses[i] != "OOP244" && courses[i] != "DBS201" &&
courses[i] != "INT222") {
error = courses[i];
break;
}
}
}
if (error != false) {return error;} else {return "";}
return '';
}
var response = true; //Continues to prompt if error is true
var error = false; //Error flag
var temp_obj = []; //Temporary object that hold current object's values
var temp_course = [];
var students = [];
var x = 0;
while (response == true) {
do {
var str = prompt("Please enter first name, last name, student ID,\nemail and courses (separated by ',')");
if (str == "" || str === null) {
response = false;
break;
}
//Removing white spaces in the string
str = str.split(' ').join('');
//Splitting the string into array by , (coma) and assigning it to temporary object array
temp_obj = str.split(',');
//Validating Student ID
if (validateStudentID(temp_obj[2]) == false) {
alert(temp_obj[2] + " is not a valid student ID, Please use xxx.xxx.xxx format.\nPlease try again!");
error = true;
}
//Validating if student is registered in atleast 1 course.
if (temp_obj.length < 5) {
alert("A student must be registered in at-least 1 course");
error = true;
}
//Checking if student is registered in more than 6 courses
if (temp_obj.length > 10) {
temp_obj = temp_obj.slice(0,9);
}
//Extracting courses from temporary object array
temp_course = temp_obj.slice(4, temp_obj.length);
//Makking all the courses uppercase
for (i = 0; i < temp_course.length; i++) {
temp_course[i] = temp_course[i].toUpperCase();
}
//Validating if courses are valid
if (validateCourses(temp_course) != "") {
alert(validateCourses(temp_course) + " is not the course provided by CPD program!\nPlease try again.");
error = true;
}
}
while (error == true);
//Break out of loop if user submitted nothing or if user pressed cancel
if (response == false) {break;}
//Merging cources array back with temporary object array
temp_obj = temp_obj.concat(temp_course);
//Creating a new instance of a student
students[x] = Object.create(student);
//Assigning values to student object from temporary object;
students[x].f_name = formatingName(temp_obj[0]); //Formatting name
students[x].l_name = formatingName(temp_obj[1]);
students[x].s_numb = temp_obj[2];
students[x].email = temp_obj[3].toLowerCase(); //Making the email all lowercase
//Making the course codes in Uppercase
for (i = 0; i < (temp_obj.length) - 4; i++ ) {
students[x].courses[i] = temp_obj[i + 4].toUpperCase();
}
x++;
}
//Printing total registered students
alert("There are total " + students.length + " students registered.");
var R_fname = [];
var R_lname = [];
var R_sid = [];
var R_email = [];
do {
var no_error = false;
var query = true;
var query_course = [];
while (no_error == false) {
query = prompt("Please enter a course code:");
if (query == "" || query == null) {
query = false;
break;
}
no_error = true;
query_course[0] = query.toUpperCase();
if (validateCourses(query_course) != "") {
alert(query + " is not the course provided by CPD program!\nPlease try again");
no_error = false;
}
}
if (query == false) {break;}
//THIS IS WHERE I THINK THE PROBLEM IS
//THIS IS WHERE I THINK THE PROBLEM IS
//THIS IS WHERE I THINK THE PROBLEM IS
//THIS IS WHERE I THINK THE PROBLEM IS
for (var a = 0; a < students.length; a++) {
//Checking if student is registred in a course
if (students[a].hasCourse(query_course) == true) {
//Assigning values to temporary array.
R_fname[a] = students[a].f_name;
R_lname[a] = students[a].l_name;
R_sid[a] = students[a].s_numb;
R_email[a] = students[a].email;
}
}
var fin_str = "";
//Concatenating all the students in a specific course to fin_str as string.
for (var b = 0; b < R_fname.length; b++) {
fin_str += (R_fname[b] + " " + R_lname[b] + " " + R_sid[b] + " " + R_email[b] + " \n");
}
//Printing list of student in a specific course
alert("List of students registered in " + query + "\n\n" + fin_str);
//Retting temporary arrays
R_fname.length = 0;
R_lname.length = 0;
R_sid.length = 0;
R_email.length = 0;
//Confirms to Exit the query loop
if (confirm("Click 'OK' to continue to query class lists.\nClick 'Cancel' to stop the program.") == false) {break;}
}
while (query != false);
These are the test values:
roy,bean,056.171.486,rbean#example.ca,int222
carl,bell,121.126.536,cbell#example.ca,dbs201,int222
eric,brand,046.123.976,ebrand#example.ca,oop244,dbs201,int222
henry, clay, 034.146.412, hclay#example.ca , ibc233 , oop244 , dbs201 , int222
When the program asks to enter the course code; it is suppose to see if the students have that course and only if they do, it prints that students info.
In my case, even if student does not have the course it still prints it.
Please run the code to see if it makes more sense... I can't explain any better
The problem can be reduced to this:
var Foo = {
courses: []
};
var x = Object.create(Foo);
var y = Object.create(Foo);
x.courses.push(123);
alert(y.courses[0]); // "123"
The reason for this behaviour is that both objects inherit the same prototype and any changes made to .courses will apply to both objects.
For this reason, it would be better to create a constructor function instead:
function Foo()
{
this.courses = [];
}
var x = new Foo();

Restrict duplicate entries in json localstorage using Javascript

I went through few link, but that didnt help me. I have to restrict duplicate titles in json array. What is way to do here??
function submitForm(){
var titleInput=document.getElementById('titleName').value;
var messageInput=document.getElementById('titleDesc').value;
var oldItems = JSON.parse(localStorage.getItem('itemsArray')) || [];
var newItem = {
"title":titleInput ,
"desc": messageInput
};
if(!(titleInput=="" || messageInput=="")){
oldItems.push(newItem);
}
}
Try this:
if (!(titleInput == "" || messageInput == "")) {
var repeated = false;
for (var i = 0; i < oldItems.length; i++) {
if (oldItems[i].titleInput == titleInput) {
repeated = true;
break;
}
}
if (repeated == false) {
oldItems.push(newItem);
}
}
You could simply check wheter the item is there before adding it.
var alreadyExists = oldItems.some(function (item) { return item.title == titleInput; });
if(!(titleInput=="" || messageInput=="") && !alreadyExists) {
oldItems.push(newItem);
}
Then perhaps you should make the concept more explicit by encapsulating that logic within an ItemStore or something similar.
function ItemStore(items) {
this._items = [];
this._titleMap = {};
this.addAll(items || []);
}
ItemStore.prototype = {
constructor: ItemStore,
hasItemTitled: function (title) {
return !!this._titleMap[title];
},
add: function (item) {
var title = item.title;
if (this.hasItemTitled(title)) throw new Error("the store already contains an item titled '" + title + "'");
this._titleMap[title] = true;
this._items.push(item);
},
addAll: function (items) {
items.forEach(this.add.bind(this));
},
items: function () { return this._items.slice(); }
//other useful methods such as itemAt, remove...
};
Then your code becomes as simple as...
var titleInput=document.getElementById('titleName').value;
var messageInput=document.getElementById('titleDesc').value;
var oldItems = new ItemStore(JSON.parse(localStorage.getItem('itemsArray')) || []);
var newItem = {
"title":titleInput ,
"desc": messageInput
};
var shouldAddItem = titleInput != "" && messageInput !="" && !oldItems.hasItemTitled(newItem.title);
if (shouldAddItem) oldItems.add(newItem);
Now obviously, your function is still doing too much since it:
knows how to retrieve and create a new item from the user's input
knows how to rehydrate the item store
knows what to check to validate if an item is valid and should be added or not
You should be reading about the Single Responsability Principle, which isin't only applicable in OO.

Categories