Добавленные повторяющиеся данные перезаписываются в localStorage

#javascript #local-storage #overwrite

#javascript #локальное хранилище #перезапись

Вопрос:

Итак, у меня есть эта функция addToCart , в Javascript которой при нажатии на кнопку имя элемента и сумма сохраняются LocalStorage , а затем я получаю данные innerHTML . Проблема здесь в том, что всякий раз, когда я нажимаю дважды или более раз на эту кнопку, данные перезаписываются.

Например, я хочу добавить одну куклу в корзину, затем я хочу добавить еще две куклы, затем сохраняется только>

Кукла: 2

но я хочу, чтобы это было

Кукла: 1
Кукла: 2

Мой код:

 const lookUpItem = matches.map((match, idx)=>
    `<h2 id="name"><span id="${match.itemName}">${match.itemName}</span></h2>
     <p>Amount: <span id="am_${idx}">${match.amount1}</span></p>
     <button onclick="addToCart('${match.itemName}', 'am_${idx}')" id="add">Add to Cart</button>
                    </span></small>
            </div>`
        ).join('');
        itemList.innerHTML = lookUpItem;

//outPut is id of an <ul> in HTML
const outPutHTML = document.getElementById("outPut");

//nm, am - variables from array.map
//saves line to localStorage and adds line to outputHTML
function addToCart(nm, am) {
    {
        const itemName = nm;
        const amount = document.getElementById(am).innerText;
        localStorage.setItem(itemName, amount);
        outPutHTML.innerHTML  = `${itemName}: ${amount}<br />`;
    }
}

//shows all data in Local Storage in outPutHTML
for(let i = 0; i < localStorage.length; i  ) {
    const name = localStorage.key(i);
    const value = localStorage.getItem(name);
    outPutHTML.innerHTML  = `${name}: ${value} <br />`;
}
 

Как это решить, я видел, что вы могли бы решить это с JSON.stringtify помощью, но точно не знаете, как это применить? Я ценю помощь.

Комментарии:

1. localStorage.key уже есть подсказки, которые вы сохраняете с помощью ключа. Ключ уникален. У вас не может быть двух записей с одним и тем же ключом. Вам нужно отказаться от этого способа работы. Например, отслеживайте информацию в массиве и сохраняйте массив в локальном хранилище.

2. Согласно @trincot, а также, если вы хотите увеличить количество уже существующего товара, тогда вам нужна логика (которой нет), чтобы увидеть, есть ли товар уже в корзине, чтобы увеличить количество. Вероятно, вы захотите сделать это в своей addToCart функции.

3. Действительно, все, что ему нужно, это сказать localStorage.setItem("name of item",localStorage.getItem("name of item") "any value"); , я не ошибаюсь?

4. Вы не совсем ошибаетесь @OOPSStudio, но предположим, что ключ еще не существует. И поскольку полезная нагрузка представляет собой строку, она будет объединена.

5. У него может быть простая проверка if(localStorage.getItem("name of item") !== null) , чтобы убедиться, что элемент уже существует. А что касается » будет объединяться», да… В этом весь смысл. Он хочет, чтобы «Doll: 2» появлялось после «Doll: 1», он не хочет увеличивать значение на единицу…….. Он хочет объединить.

Ответ №1:

Вы не можете хранить два элемента с одним и тем же ключом в локальном хранилище.

Лучше сначала подумать, как вы будете хранить их в памяти — без учета языкового хранилища.

Например, вы могли бы представить себе такую структуру:

 items = [
    { name: "Doll", value: "1" },
    { name: "Doll", value: "2" }
];
 

И если вам нужно добавить еще один, вы просто делаете

 items.push({ name: "Doll", value: "15" });
 

И как только вы определили свою структуру памяти, вы можете просто записать всю эту структуру в локальное хранилище, используя один жестко запрограммированный ключ:

 localStorage.setItem("items", JSON.stringify(items));
 

И для чтения этой информации в начале вашей страницы:

 items = JSON.parse(localStorage.getItem("items") || "[]");
 

Существует || для обработки случая, когда данные еще не присутствуют в локальном хранилище, и в этом случае вы хотите получить пустой массив.

Итак, вот часть вашего адаптированного кода. Комментарии — это ваши комментарии, поэтому вы можете видеть, где код вписывается:

 //shows all data in Local Storage in outPutHTML
const items = JSON.parse(localStorage.getItem("items") || "[]");
outPutHTML.innerHTML = items.map(({name, value}) => `${name}: ${value}<br>`)
                            .join("");

//saves line to localStorage and adds line to outputHTML
function addToCart(name, am) {
    const value = document.getElementById(am).innerText;
    items.push({name, value});
    localStorage.setItem("items", JSON.stringify(items));
    outPutHTML.innerHTML  = `${name}: ${value}<br>`;
}
 

Комментарии:

1. «Вы не можете хранить два элемента с одним и тем же ключом в локальном хранилище». Вы можете, если просто преобразуете их в строки, объединяете их, сохраняете эту строку в ключе, а затем .split() позже, нет? Я не понимаю, почему решение должно быть сложным, когда на самом деле базовое решение заключается в том, чтобы просто хранить несколько значений в одном ключе… Если я чего-то не упускаю?

2. Я хочу сказать, что вы не можете хранить данные в виде двух записей локального хранилища, где каждая запись имеет один и тот же ключ. Конечно, вы можете хранить любую строку, связанную с одним ключом, и эта строка может иметь всю необходимую сложность (что также предлагается в этом ответе). Но это была не моя точка зрения. Мой ответ не слишком сложный. Он просто использует JSON кодировку вместо разделителя запятой, что более надежно, когда вы хотите хранить строки с запятой.

3. он показывает синтаксическую ошибку для JSON.parse: неожиданный символ в строке 1 столбца 2 данных JSON, и я помещаю ту же строку, я получаю данные в карту массива

4. Это означает, что вы не записывали данные в локальное хранилище в формате JSON. Я вижу, что сначала я упомянул правильный код для этого, но затем не выполнил строковую обработку в последнем блоке кода. Я сделал это сейчас.

5. Спасибо, я использовал метод join для преобразования элементов в строку, при этом вывод stringify HTML показывал ненужные запятые за каждой строкой