How to display localStorage data - javascript

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

Related

The values are not replacing with new values

firstly, when I search for any city it shows the weather correctly, but when I try to search for another city/country It shows the details of the same city that I have searched for before. I think there is something wrong with my JavaScript code. I think the new values that I'm fetching from the API are not getting replaced by the old values.
let enterCity = document.querySelector("#enterCity");
let city = document.querySelector(".city");
let country = document.querySelector(".country");
let temp = document.querySelector(".temp");
let text = document.querySelector(".text");
let inputVal = enterCity.value;
// the base url
let url = `http://api.weatherapi.com/v1/current.json?q=${inputVal}&key=cb58be19d0d2****************`;
fetch(url).then((response) => {
return response.json();
}).then((data) => {
let search = document.querySelector(".search");
search.addEventListener("click", () => {
let container = document.querySelector(".container");
card = document.createElement("div");
card.className = "card";
city = document.createElement("h2");
city.className = "city";
***The problems are with the innerText down below ***
city.innerText = data.location.name;
country = document.createElement("h5");
country.className = "country";
country.innerText = data.location.country;
temp = document.createElement("h4");
temp.className = "temp";
temp.innerText = data.current.temp_c;
span1 = document.createElement("span");
span1.id = "deg";
span1.innerText = "°C"
temp.appendChild(span1);
icon = document.createElement("img");
icon.className = "icon";
icon.src = data.current.condition.icon;
text = document.createElement("h3");
text.className = "text";
text.innerText = data.current.condition.text;
card.appendChild(city);
card.appendChild(country);
card.appendChild(temp);
card.appendChild(icon);
card.appendChild(text);
container.appendChild(card);
Here, I have also cleared the input value
that I'm taking from the user
enterCity.value = "";
});
});
let search = document.querySelector(".search");
search.addEventListener("click", () => {
let enterCity = document.querySelector("#enterCity");
let city = document.querySelector(".city");
let country = document.querySelector(".country");
let temp = document.querySelector(".temp");
let text = document.querySelector(".text");
var inputVal = enterCity.value;
// the base url
let url = `http://api.weatherapi.com/v1/current.json?q=${inputVal}&key=cb58be19d0d2********************`;
fetch(url).then((response) => {
return response.json();
}).then((data) => {
//Do the remaining works here
})
});
The actual problem was already assigned the value of document.querySelector("#enterCity"); when the page loads instead of on click. So value of enterCity was not changing when you click the search button.
Note : If the key you given in the question is your personal API key,
then please try to change it in the console, because it is not good
idea to publish it in the outside.
This is happening beacause you haven't added onchange event listener on your input(enter city).if you don't add onchange event this will take only your inital value.
So add a onchange listener then call fetch api inside of it.
Dummy example -
let entercity=document.querySelector("#entercity");
entercity.addEventListener('change',()=>{
let inputVal=entercity.value;
let url = `http://api.weatherapi.com/v1/current.json?q=${inputVal}&key=cb58be19d0d2476da35134140211107`;
fetch(url).then((res)=>console.log(res))
.catch((err)=>console.log(err));
})

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

Validating input on JavaScript before sending to the back-end

I am a beginner in programming. My code has a lot of errors and any help will be welcome. First I'm trying to write a function on the JavaScript file where it is sending the data to the back-end, I have posted a snippet to my front-end to help visualize what I am trying to achieve.
Basically, I want to send some data, but before the back-end receive the data I would like to validate the data, and send an error to the user informing what is wrong with the input field.
Quantity(indivQty) should be ONLY int more than 0 and less than the stockIndivQty.
Function to send/save the data:
async function saveTransfer(){
//ID (inventorylocation table)
let invLocId = document.querySelector('#itemID span').textContent;
console.log('invLocId: '+invLocId);
// Item SKU
let customSku = document.querySelector('#sku span').textContent;
console.log('itemSku: '+customSku);
// Type
let invType = document.querySelector('#type span').textContent;
console.log('type: '+invType);
// InvID
let invId = document.querySelector('#invID span').textContent;
console.log('Inventory ID: '+invId);
let stockIndivQty = document.querySelector('#indivQty span').textContent;
let trs = document.querySelectorAll('.rows .row');
let locations = [];
for(let tr of trs) {
let location = {};
location.indivQty = tr.querySelector('.quantity').value;
location.locationName = tr.querySelector('.input-location').value;
locations.push(location);
}
console.log('locations: '+locations);
let formData = new FormData();
formData.append('invLocId', invLocId);
formData.append('customSku', customSku);
formData.append('locations', JSON.stringify(locations));
formData.append('invType', invType);
formData.append('invId', invId);
let response = await fetch(apiServer+'itemTransferBay/update', {method: 'POST', headers: {'DC-Access-Token': page.userToken}, body: formData});
let responseData = await response.json();
if (!response.ok || responseData.result != 'success') {
window.alert('ERROR');
} else {
window.alert('teste');
location.reload();
}
}
window.addEventListener("load", () => {
let elTotalQuantity = document.querySelector("#totalqty");
let totalQuantity = parseInt(elTotalQuantity.innerHTML);
function getSumOfRows() {
let sum = 0;
for (let input of document.querySelectorAll("form .row > input.quantity"))
sum += parseInt(input.value);
return sum;
}
function updateTotalQuantity() {
elTotalQuantity.innerHTML = totalQuantity - getSumOfRows();
}
function appendNewRow() {
let row = document.createElement("div");
row.classList.add("row");
let child;
// input.quantity
let input = document.createElement("input");
input.classList.add("quantity");
input.value = "0";
input.setAttribute("readonly", "");
input.setAttribute("type", "text");
row.append(input);
// button.increment
child = document.createElement("button");
child.classList.add("increment");
child.innerHTML = "+";
child.setAttribute("type", "button");
child.addEventListener("click", () => {
if (getSumOfRows() >= totalQuantity) return;
input.value++;
updateTotalQuantity();
});
row.append(child);
// button.increment
child = document.createElement("button");
child.classList.add("decrement");
child.innerHTML = "-";
child.setAttribute("type", "button");
child.addEventListener("click", () => {
if (input.value <= 0) return;
input.value--;
updateTotalQuantity();
});
row.append(child);
// label.location
child = document.createElement("label");
child.classList.add("location-label");
child.innerHTML = "Location: ";
row.append(child);
// input.location
let input2 = document.createElement("input");
input2.classList.add("input-location");
input2.value = "";
input2.setAttribute("type", "text");
row.append(input2);
// button.remove-row
child = document.createElement("button");
child.classList.add("remove-row");
child.innerHTML = "Remove";
child.setAttribute("type", "button");
child.addEventListener("click", () => {
row.remove();
updateTotalQuantity();
});
row.append(child);
document.querySelector("form .rows").append(row);
}
document.querySelector("form .add-row").addEventListener("click", () => appendNewRow());
appendNewRow();
});
<form>
<label>Total Quantity: <span id="totalqty">10</span></label>
<br>
<div class="rows">
</div>
<button type="button" class="add-row">Add new row</button>
</form>
You can use the JavaScript functions parseInt() and isNaN() to check if a value is a valid number, and then use basic if-statements to check if the number is inside a given range.
If not, then display a notification that some value is incorrect (best: highlight the incorrect input-field) and return, to not reach the code where you send the data to the back-end.
An example would look like this:
let valueFromString = parseInt("10");
if (isNaN(valueFromString)) valueFromString = 0; // Define default value
let lowerBound = 0;
let upperBound = 20;
// Checking if valueFromString is of range [lowerBound, upperBound]; if not, 'return;'
if (valueFromString < lowerBound || valueFromString > upperBound) return;
Now, most of the values don't necessarily need an extra assignment to new variables like lowerBound or upperBound. However, for the purpose of the example, it is demonstrated here.

Keep Todo Results after browser refreshing

I created a todo app to add and remove tasks on the page.
however i would like to keep todo results when browser refreshed .
Is that possible to make this like storing data on db or any storage to save these results?
any idea to make this to save data ??
Now I posted the complete code hereee! because i cant posted code here before
let menu = document.querySelector(".bs");
let btn1 = document.querySelector(".btn");
let btn2 = document.querySelector(".btn3");
let irp = document.querySelector(".date");
let inp = document.querySelector(".input");
let bsd = document.querySelector(".sss");
let brs = document.querySelector(".marker");
let addBr = () => {
btn1.addEventListener("click", addBr);
let br = document.createElement("DIV");
let dd = document.createElement("H1");
dd.innerHTML = (inp.value);
br.className = "red";
var bn = document.createElement("H1");
bn.innerHTML = (irp.value);
menu.appendChild(br);
br.appendChild(dd);
br.appendChild(bn);
if( inp.value == "") {
br.remove();
}
else {
menu.appendChild(br);
}
if( irp.value == "") {
dd.innerHTML = "Albenis";
}
else {
menu.appendChild(br);
}
let ttt = document.createElement("BUTTON");
ttt.className = "marker";
ttt.innerHTML = "Remove";
br.appendChild(ttt);
// This is the important change. Part of creating the .ttt element
// is setting up its event listeners!
ttt.addEventListener('click', () => br.remove());
};
btn1.addEventListener("click", addBr);
// Call `addBr` once to add the initial element
addBr();
<html>
<body>
<div class="bs">
<input type="text" class="input">
<input type="date" class="date">
<button class="btn">
Add
</button>
</div>
</body>
</html>
TL;DR: use localStorage to read the items at page load and write the items when they change, like in the final version
To keep your todo entries, you need to store it in a Database. This can be either a local database in the website like localStorage. Or you need to build a backend which is connected to a Database and send and load the Data from there.
localStorage example:
const items = [{ name: "My Todo" }, { name: "My Todo 2" }];
const setItems = () => {
localStorage.setItem("items", JSON.stringify(items));
};
const getItems = () => {
return JSON.parse(localStorage.getItem("items"));
};
Including your code:
const getItems = () => {
return JSON.parse(localStorage.getItem("items"));
};
const items = getItems() || [];
const setItems = () => {
localStorage.setItem("items", JSON.stringify(items));
};
let addBr = (item) => {
let br = document.createElement("DIV");
let dd = document.createElement("H1");
dd.innerHTML = (item ? item.name : inp.value);
br.className = "red";
var bn = document.createElement("H1");
bn.innerHTML = (item ? item.name : irp.value);
if (!item) {
items.push({ name: inp.value });
setItems();
}
menu.appendChild(br);
br.appendChild(dd);
br.appendChild(bn);
if( inp.value == "") {
br.remove();
}
else {
menu.appendChild(br);
}
if( irp.value == "") {
dd.innerHTML = "Albenis";
}
else {
menu.appendChild(br);
}
let ttt = document.createElement("BUTTON");
ttt.className = "marker";
ttt.innerHTML = "Remove";
br.appendChild(ttt);
// This is the important change. Part of creating the .ttt element
// is setting up its event listeners!
ttt.addEventListener('click', () => br.remove());
};
for (const item of items) {
addBr(item);
}
btn1.addEventListener("click", () => addBr());

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