Variable value not being saved in function - javascript

I want my filters variable to update, my guess is it's re-initializing as the set value every time the function is called, whenever i try to declare it outside of the function I get a lexical error, how can I make sure it keeps the value assigned to it after a button has clicked
export function categoryRender(){
let filter = 'RICK'
console.log(filter)
const all = document.getElementById('all');
all.onclick = function(){
filter = 'ALL'
render(filter);
}
categories = categories.sort();
const filterContainer = document.getElementById("filter-container");
filterContainer.innerHTML = "";
const allFilterImg = document.getElementById('all-image');
if (filter === 'ALL'){
allFilterImg.setAttribute('src', './images/checked.jpeg')
}else{
allFilterImg.setAttribute('src', './images/unchecked.png')
console.log('unchecked all firing')
}
for (let i = 0; i < categories.length; i++){
const line = document.createElement("span");
const filterButton = document.createElement("img");
const filterLabel = document.createElement("h2");
filterContainer.appendChild(line);
line.appendChild(filterButton);
line.appendChild(filterLabel);
line.setAttribute('id', categories[i]);
line.classList.add('filter-line');
filterLabel.innerHTML = categories[i];
if (filter === categories[i]){
filterButton.setAttribute('src', './images/checked.jpeg')
}else{
filterButton.setAttribute('src', './images/unchecked.png')
}
line.onclick = function(){
filter = categories[i];
render(filter)
}
}
}

Related

Javascript chaining window.onload functions

I have a javascript function that grabs a dataset numeric value and appends it to an XMLhttprequest parameter. It has to run onload as the content is printed dynamically through php.
I now am trying to create a simple carousel for the elements printed and finding some difficulty chaining onload functions.
I've found creating an additional onload function for anything breaks the first onload function. What can I do here?
function userData() {
let infoWrap = document.querySelector(".agent-detail-info").dataset.id;
console.log(infoWrap);
return infoWrap;
}
window.onload = userData;
window.onload = () => {
const request = new XMLHttpRequest();
request.open(
"GET",
`url&usertolookup=${userData()}`
);
request.onload = function () {
let response = request.response;
let parsedData = JSON.parse(response);
console.log(parsedData);
let testimonials = parsedData.data.testimonials.details;
testimonials.forEach((testimonial, index) => {
const testimonialWrap = document.querySelector(".testimonials");
// Create testimonials container
let innerTestimonials = document.createElement("div");
innerTestimonials.className = "inner-testimonial-container";
testimonialWrap.appendChild(innerTestimonials);
// Create star rating container
let starWrap = document.createElement("div");
starWrap.className = "testimonial-stars";
innerTestimonials.appendChild(starWrap);
// Create Testimonial Content
let innerTestimonialParagraph = document.createElement("p");
innerTestimonials.appendChild(innerTestimonialParagraph);
// Create Testimonial Signature
let innerTestimonialSignature = document.createElement("address");
innerTestimonials.appendChild(innerTestimonialSignature);
// Loop through rating value and create elements
let rating = testimonial.rating;
for (let i = 0; i < rating; i++) {
let star = document.createElement("i");
star.className = "fa fa-star";
starWrap.appendChild(star);
}
// Insert Testimonial Content
let testimonialText = testimonial.Testimonial;
innerTestimonialParagraph.innerHTML = testimonialText;
// Insert Testimonial Signature
let signature = testimonial.Signature;
innerTestimonialSignature.innerHTML = signature;
});
};
request.send();
};
Testing Carousel (have tried alternative with event listeners rather than inline onclick and cannot access the elements printed through the response(returns undefined as the elements are printed after dom load))
let tabIndex = 1;
function nextTestimonial(n) {
testimonialSlide((tabIndex += n));
}
function currentTestimonial(n) {
testimonialSlide((tabIndex = n));
}
function testimonialSlide(n) {
let innerTestimonials = document.querySelectorAll(
".inner-testimonial-container"
);
if (n > innerTestimonials.length) {
tabIndex = 1;
}
if (n < 1) {
tabIndex = innerTestimonials.length;
}
for (let i = 0; i < innerTestimonials.length; i++) {
innerTestimonials[i].style.display = "none";
}
innerTestimonials[tabIndex - 1].style.display = "block";
}
Random attempt to chain onload functions (this breaks the response)
window.onload = () => {
const innerTestimonialsNew = document.querySelectorAll(
".inner-testimonial-container"
);
console.log(innerTestimonialsNew);
};

How to display localStorage data

How I can display localStorage information on my webpage?
I am easily setItem() to localStorage and when I console.log() it is showing but I cannot display it on the page(after reloading it is gone) I wanna keep this data on my page even when I am closing the tab
Thank you in advance
const title = document.querySelector("#title");
const author = document.querySelector("#author");
const rating = document.querySelector("#rating");
const category = document.querySelector("#category");
const bookList = document.querySelector("#book-list");
document.querySelector("#book-form").addEventListener("submit", (e) => {
e.preventDefault();
});
document.querySelector("#submit-btn").addEventListener("click", function () {
if (
title.value === "" ||
author.value === "" ||
rating.value === "" ||
category.value === ""
) {
alert("Please fill the form");
} else {
// Creating tr th and appending to list
const bookListRow = document.createElement("tr");
const newTitle = document.createElement("th");
newTitle.innerHTML = title.value;
bookListRow.appendChild(newTitle);
const newAuthor = document.createElement("th");
newAuthor.innerHTML = author.value;
bookListRow.appendChild(newAuthor);
const newRating = document.createElement("th");
newRating.innerHTML = rating.value;
bookListRow.appendChild(newRating);
const newCategory = document.createElement("th");
newCategory.innerHTML = category.value;
bookListRow.appendChild(newCategory);
const deleteBtn = document.createElement("th");
deleteBtn.classList.add("delete");
deleteBtn.innerHTML = "X";
bookListRow.appendChild(deleteBtn);
bookList.appendChild(bookListRow);
//Storage
let storageTitle = title.value;
let storageAuthor = author.value;
let storageRating = rating.value;
let storageCategory = category.value;
localStorage.setItem("title", JSON.stringify(storageTitle));
localStorage.setItem("author", JSON.stringify(storageAuthor));
localStorage.setItem("rating", JSON.stringify(storageRating));
localStorage.setItem("category", JSON.stringify(storageCategory));
for (var i = 0; i < localStorage.length; i++) {
newTitle += localStorage.getItem(localStorage.key(i));
}
// Clear
title.value = "";
author.value = "";
rating.value = "";
category.value = "";
}
});
// Remove each books by clicking X button
bookList.addEventListener("click", (e) => {
e.target.parentElement.remove();
}); ```
the question of your code may is that you just save the data to the localStoarge, but at the initial of the page ,you did't get the data from the localStorage, you should get data like this:
window.onload = function (){
let storageTitle = JSON.parse(localStorage.getItem("title"));
document.querySelector("#title").innerHtml = storageTitle;
}
this code should be working can you specify the problem a little further!
You are setting it correctly but not reading it as you should. Local storage persists data even if you close the tab, so it is just your code that is causing you trouble.
You can find an explanation how you should work with local and session storage here.
https://stackoverflow.com/a/65655155/2563841

Whenever the page gets reloaded, an item in a list gets duplicated in javascript

I’m a newbie started js like 2 weeks ago.
I have been making a to-do list.
There are key toDos & finished in localStorage.
I want the value in toDos to go to finished, getting class name “done” if I click the finBtn. Also it should move to the bottom.
At first it works. However, every time the page gets refreshed, the stuff in finished gets duplicated.
This problem’s been bothering me for a week.
Thank you for reading.
const toDoForm = document.querySelector(".js-toDoForm"),
toDoInput = toDoForm.querySelector("input"),
toDoList = document.querySelector(".js-toDoList");
const TODOS_LS = "toDos";
const FINISHED_LS = "finished";
const NOTSTART_CN = "notStart";
const DONE_CN = "done";
let toDos = [];
let toDosDone = [];
function saveToDos(){
localStorage.setItem(TODOS_LS, JSON.stringify(toDos));
}
function updateToDos(){
localStorage.setItem(FINISHED_LS, JSON.stringify(toDosDone));
}
function deleteToDo(event){
const btn = event.target;
const li = btn.parentNode;
toDoList.removeChild(li);
const cleanToDos = toDos.filter(function(toDo){
return toDo.id !== parseInt(li.id);
});
toDos = cleanToDos;
saveToDos();
}
function finish(event){
const btn = event.target;
const li = btn.parentNode;
const oldToDos = localStorage.getItem(TODOS_LS);
const parsedOldToDos = JSON.parse(oldToDos);
const btnNum = parseInt(li.id) - 1;
const finishedStuff = parsedOldToDos.splice(btnNum, 1);
finishedStuff[0].class = DONE_CN;
li.classList.add(DONE_CN);
toDos = parsedOldToDos;
toDosDone = finishedStuff;
saveToDos();
updateToDos();
}
function makeToDos(text){
const li = document.createElement("li");
const span = document.createElement("span");
const delBtn = document.createElement("button");
const finBtn = document.createElement("button");
const newId = toDos.length + 1;
delBtn.innerText="❌";
delBtn.classList.add("delBtn");
delBtn.addEventListener("click", deleteToDo);
finBtn.classList.add("finBtn");
finBtn.innerText = "✔";
finBtn.addEventListener("click", finish);
span.innerText = text;
li.id = newId;
li.appendChild(span);
li.appendChild(delBtn);
li.appendChild(finBtn);
toDoList.appendChild(li);
const toDoObj = {
text: text,
id: newId,
class:""
};
toDos.push(toDoObj);
saveToDos();
}
function handleSubmit(event){
event.preventDefault();
const currentValue = toDoInput.value;
makeToDos(currentValue);
toDoInput.value = "";
}
function loadToDos(){
const loadedToDos = localStorage.getItem(TODOS_LS);
const loadedFinToDos = localStorage.getItem(FINISHED_LS);
if(loadedToDos !== null || loadedFinToDos !== null){
const parsedToDos = JSON.parse(loadedToDos);
const parsedFinToDos = JSON.parse(loadedFinToDos);
parsedToDos.forEach(function(toDo){
makeToDos(toDo.text);
});
parsedFinToDos.forEach(function(done){
makeToDos(done.text);
});
} //else
} //ends of loadToDos
function init(){
loadToDos();
toDoForm.addEventListener("submit", handleSubmit);
}
init();
Your localStorage is not cleaning up on page refresh, you should do localStorage.clear(); Each time page load using

Incorrect loading order from local storage

I'm having problem with loading from local storage.
Here's a part of the code
const getTerminus = () => {
let terminus;
if (localStorage.getItem("terminus") === null) {
terminus = [];
} else {
terminus = JSON.parse(localStorage.getItem("terminus"));
}
let directions;
if (localStorage.getItem("directions") === null) {
directions = [];
} else {
directions = JSON.parse(localStorage.getItem("directions"));
}
terminus.forEach(async(stop) => {
let API_URL =
"https://ckan.multimediagdansk.pl/dataset/c24aa637-3619-4dc2-a171-a23eec8f2172/resource/d3e96eb6-25ad-4d6c-8651-b1eb39155945/download/stopsingdansk.json";
let response = await fetch(API_URL);
let data = await response.json();
const {
stops,
stopId,
stopName,
stopCode,
zoneId
} = data;
let input = stop;
let ID;
let dataArr = [];
for (let i = 0; i < stops.length; i++) {
if (
stops[i].stopName === input &&
stops[i].stopCode === directions[terminus.indexOf(input)] &&
stops[i].zoneId === 1
) {
ID = stops[i].stopId;
dataArr = [ID, stops[i].stopName];
}
}
API_URL = `https://ckan2.multimediagdansk.pl/delays?stopId=${ID}`;
response = await fetch(API_URL);
data = await response.json();
const {
delay,
estimatedTime,
routeId,
headsign
} = data;
let times = [];
let routeIds = [];
let headsigns = [];
for (let i = 0; i < delay.length; i++) {
times.push(delay[i].estimatedTime);
routeIds.push(delay[i].routeId);
headsigns.push(delay[i].headsign);
}
routeIds.push(" ");
times.push(" ");
const cardDiv = document.createElement("div");
cardDiv.classList.add("card");
const stopNameDiv = document.createElement("div");
stopNameDiv.classList.add("stop-name-div");
cardDiv.appendChild(stopNameDiv);
const stopNameSpan = document.createElement("span");
stopNameSpan.innerText = dataArr[1];
stopNameSpan.classList.add("stop-name-span");
stopNameDiv.appendChild(stopNameSpan);
const scheduleDiv = document.createElement("div");
scheduleDiv.classList.add("schedule-div");
cardDiv.appendChild(scheduleDiv);
if (headsigns.length !== 0) {
routeIds.unshift("Line");
headsigns.unshift("Direction");
times.unshift("Departure");
}
const lineSpan = document.createElement("span");
lineSpan.innerText = routeIds.join("\n");
lineSpan.classList.add("line-span");
scheduleDiv.appendChild(lineSpan);
const dirSpan = document.createElement("span");
dirSpan.innerText = headsigns.join("\n");
dirSpan.classList.add("dir-span");
scheduleDiv.appendChild(dirSpan);
const timeSpan = document.createElement("span");
timeSpan.innerText = times.join("\n");
timeSpan.classList.add("time-span");
scheduleDiv.appendChild(timeSpan);
const buttonsDiv = document.createElement("div");
buttonsDiv.classList.add("buttons-div");
cardDiv.appendChild(buttonsDiv);
const deleteButton = document.createElement("button");
deleteButton.innerHTML = '<i class="fas fa-trash"></i>';
deleteButton.classList.add("delete-button");
buttonsDiv.appendChild(deleteButton);
const dirButton = document.createElement("button");
dirButton.innerHTML = '<i class="fas fa-retweet"></i>';
dirButton.classList.add("reverse-button");
buttonsDiv.appendChild(dirButton);
stopList.appendChild(cardDiv);
});
};
document.addEventListener("DOMContentLoaded", getTerminus);
Terminus contains stop names, and directions contains direction codes.
On refresh, it fetches data from API based on stop name and direction, and displays a card with departure time etc.
The problem is, on closing and re-opening the page cards are sometimes displayed in a wrong order. I have found out, that as time between closing and opening lengthens, the probability of this occurring gets higher. After simple refresh everything is in correct order.
Does it have something to do with browser cache? Has anyone had similar issue or knows what's going on?
Alright, as #Yoshi stated, it was insequential promise error. I managed to fix it by using reduce().
Here are the threads that helped me
Resolve promises one after another (i.e. in sequence)?
Why Using reduce() to Sequentially Resolve Promises Works

Local Storage issue

I'm trying to use local storage so that my invites stay on the page when refreshed. How would I go about implementing this into my code. I really don't know where to start and I'm really struggling with it. Please cans someone just show me how to implement this into my code. Ive been creating child elements and appending them to the UL in the HTML.
const form = document.getElementById("registrar");
const input = form.querySelector("input");
const mainDiv = document.querySelector(".main");
const ul = document.getElementById("invitedList");
const div = document.createElement('div');
const filterLabel = document.createElement('label');
const filterCheckBox = document.createElement('input');
filterLabel.textContent = "Hide those who havent responded";
filterCheckBox.type = 'checkbox';
div.appendChild(filterLabel);
div.appendChild(filterCheckBox);
mainDiv.insertBefore(div, ul);
/*
This creates a checkbox to see you has confirmed if they are coming
to the event or not.
*/
filterCheckBox.addEventListener("change", (e) => {
const isChecked = e.target.checked;
const lis = ul.children;
if (isChecked) {
for (let i = 0; i < lis.length; i += 1) {
let li = lis[i]
if (li.className === 'responded') {
li.style.display = '';
} else {
li.style.display = 'none';
}
}
} else {
for (let i = 0; i < lis.length; i += 1) {
let li = lis[i]
li.style.display = '';
}
}
});
/*
This function creates new list items (the invites).
*/
createLi = (text) => {
createElement = (elementName, property, value) => {
const element = document.createElement(elementName);
element[property] = value;
return element;
}
appendElement = (elementName, property, value) => {
const element = createElement(elementName, property, value);
li.appendChild(element);
return element;
}
const li = document.createElement("li");
appendElement("span", "textContent", text);
appendElement("label", "textContent", "Confirmed")
.appendChild(createElement("input", "type", "checkbox"));
appendElement("button", "textContent", "edit");
appendElement("button", "textContent", "remove");
return li;
}
}
form.addEventListener("submit", (event) => {
event.preventDefault();
const text = input.value;
input.value = "";
const li = createLi(text);
ul.appendChild(li);
});
ul.addEventListener("change", () => {
const checkbox = event.target;
const checked = checkbox.checked;
const listItem = checkbox.parentNode.parentNode;
if (checked) {
listItem.className = "responded";
} else {
listItem.className = "";
}
});
ul.addEventListener("click", (e) => {
if (e.target.tagName === 'BUTTON') {
const button = e.target;
const li = button.parentNode;
const ul = li.parentNode;
const action = button.textContent;
const nameActions = {
remove: () => {
ul.removeChild(li);
},
edit: () => {
const span = li.firstElementChild;
const input = document.createElement('input');
input.type = 'text';
input.value = span.textContent;
li.insertBefore(input, span);
li.removeChild(span);
button.textContent = 'Save';
},
Save: () => {
const input = li.firstElementChild;
const span = document.createElement('span');
span.textContent = input.value;
li.insertBefore(span, input);
li.removeChild(input);
button.textContent = 'edit';
}
};
nameActions[action]();
}
});
I only can give you an idea for this, if you are planning to save any big data to localStorage, you can save your data to string and remake it to JSON object!
Here's an exmaple for saving data set
var toSave = [ ];
var whatToSave = (Your invites data List, maybe a "text" var for your code?, organize
to array or loop for your "UL" tag)
for(var i=0;i<whatToSave.length;i++){
var obj = [];
obj[i] = {
text:whatToSave[i].text,
data1:whatToSave[i].data1,
data2:whatToSave[i].data2,
...
}
toSave.push(obj[i]);
}
var saveToString = JSON.stringify(toSave);
localStorage.setItem('invites', saveToString); //your invite data saved in local
storage
....
//after refreshing or when you need to use your saved data
var cameBack = JSON.parse(localStorage.getItem('invites'));
//this will return same data again
//and make function to make UL using retured data array
you don't really need to for loop and push if you already organized needed data to array, just wrote it to make you understand an idea to save data in localStorage. I don't know if this will help you but get an idea and implement it to your project :)

Categories