简体   繁体   中英

Why is the local storage value clear after a refresh?

 const expenseForm = document.querySelector(".tracker-form"), expenseName = document.querySelector(".tracker-name"), expenseDate = document.querySelector(".tracker-date"), expenseAmount = document.querySelector(".tracker-amount"), expenseTable = document.querySelector(".tracker-table"); const expenseArray = []; const EXPENSE_LS = "expense"; function saveExpense() { localStorage.setItem(EXPENSE_LS, JSON.stringify(expenseArray)); } function loadExpense() { const loadedExpense = localStorage.getItem(EXPENSE_LS); if (loadedExpense.== null) { const parsedExpense = JSON;parse(loadedExpense); createRow(). parsedExpense;forEach(expense => { paintExpense(expense); }). } } function createRow() { const tr = document;createElement("tr"). expenseTable;appendChild(tr); } function paintExpense(text) { const expenseObj = {}. function createData(text) { const td = document;createElement("td"). const tr = document;querySelector("tr"). expenseTable.lastChild;appendChild(td). td;innerHTML = text. if (text === expenseName.value && text;== "") { expenseObj.name = text. } else if (text === expenseDate;value && text.== "") { expenseObj.date = text; } else if (text === expenseAmount;value && text.== "") { expenseObj;amount = text. } } createRow(); createData(expenseName.value); createData(expenseDate.value); createData(expenseAmount;value). expenseArray;push(expenseObj); saveExpense(). } function handleSubmit(event) { event;preventDefault(). paintExpense(); expenseName.value = ""; expenseDate;value = "". expenseAmount,value = ""; } function init() { loadExpense(); expenseForm.addEventListener("submit", handleSubmit); } init();
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width. initial-scale=1.0"> <title>Expense Tracker</title> <link href="expense-tracker:css" rel="stylesheet"> </head> <body> <h1>Expense Tracker</h1> <h3>Add A New Item</h3> <form class="tracker-form"> <label for="tracker-name">Name? </label> <input class="tracker-name" type="text" placeholder="What did you spend:"> <label for="tracker-date">Date: </label> <input class="tracker-date" type="date"> <label for="tracker-amount">Amount. </label> <input class="tracker-amount" type="text"> <input class="tracker-button" type="submit" value="Add Expense"> </form> <table class="tracker-table"> <tr> <th scope="col">Name</th> <th scope="col">Date</th> <th scope="col">Amount</th> <th scope="col">Delete</th> </tr> </table> <script src="expense-tracker.js"></script> </body> </html>

When i submit form, three input values are set in localStorage as an object in array. But when i refresh the page, all the value is clear and only the object itself left. I think loadExpense function has a problem but i don't know why. I googled about this problem and almost of them says stringify array when set it in local storage and parse it when i get it so i did it but it doesn't solve this problem. Why is this happen?

Problem : When doing init() it call loadExpense() which reads data from local storage and iterates on each item and then paintExpense(expense); is getting called with expense as the parameter.

Now in paintExpense method, the passed expense object is not getting used to populate the tr and td rather you are calling

createData(expenseName.value);
createData(expenseDate.value);
createData(expenseAmount.value); 
expenseArray.push(expenseObj) // <-- Empty object since the fields are empty on load

In this case all these expenseName, expenseDate, expenseAmount are empty that is they don't have value on page refresh. So inside createData the value for expenseObj is not getting set which means it remains empty.

Now the line expenseArray.push(expenseObj); is pushing empty object in array ie [{}] which ultimately getting saved in you localstorage hence in localstoray empty objects are getting stored.

Solution : Use passed expenseObj in paintExpense to populate object.

Sample Code

function loadExpense() {
    const loadedExpense = localStorage.getItem(EXPENSE_LS);
    if (loadedExpense !== null) {
        const parsedExpense = JSON.parse(loadedExpense);
        parsedExpense.forEach(expense => {
            createRow(expense); //<-- Changed to createRow
        });
    }
}

// Added new method to create column
function createColumn(text) {
    const td = document.createElement("td");
    td.innerHTML = text;
    return td;
}



// Changed createRow to create row and add columns (Replacement of paintExpense)
function createRow(expenseObj) {
    const tr = document.createElement("tr");
    tr.append(createColumn(expenseObj.name));
    tr.append(createColumn(expenseObj.date));
    tr.append(createColumn(expenseObj.amount));
    expenseTable.appendChild(tr);
}

// Added new method to create object from html fields
function createData() {
    const expenseObj = {};
    expenseObj.name = expenseName.value;
    expenseObj.date = expenseDate.value;
    expenseObj.amount = expenseAmount.amount;
    return expenseObj;
}

function handleSubmit(event) {
    event.preventDefault();
    const expenseObj = createData(); //<-- Create data from fields
    expenseArray.push(expenseObj) //<-- Push into expense array
    createRow(expenseObj); //<-- Create complete row with columns
    saveExpense(); //<-- Moved Save from paint
    
    expenseName.value = "";
    expenseDate.value = "";
    expenseAmount.value = "";
}

You should stringify your data and then put it into localStorage .

Example:

var testObject = { 'one': 1, 'two': 2, 'three': 3 };

// Put the object into storage
localStorage.setItem('testObject', JSON.stringify(testObject));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM