/    Sign up×
Community /Pin to ProfileBookmark

Items persist in local storage after being removed

I’m building a Phone Book where users are able to add, delete and search contacts. Everything works well so far, I can add and save contacts in local storage and I can delete them in the UI. But after deleting them, they still persist in the local storage, so they reappear when the page is refreshed. Any suggestion is welcome!
I have a Contact class:

“`
class Contact {
constructor(name, phone) {

this.name = name;
this.phone = phone;
}
}
“`

Here is removeContact function in the Store class:

“`
static removeContact(phone) {
const contacts = Store.getContact();

contacts.forEach((contact, index) => {

if(contact.phone === phone) {
contacts.splice(index, 1);
}

});

localStorage.setItem(‘contacts’, JSON.stringify(contacts));

}
}
“`

And here I call the method:

“`
document.querySelector(‘#contact-items’).addEventListener(‘click’, (e) => {

// Remove contact from storage
Store.removeContact(e.target.parentElement);

});

“`

to post a comment
JavaScript

19 Comments(s)

Copy linkTweet thisAlerts:
@SempervivumNov 19.2019 — removeContact requires a phone number which is a string probably. However `e.target.parentElement` is a DOM element.
Copy linkTweet thisAlerts:
@maxianna7authorNov 19.2019 — @Sempervivum#1610983

Thank you for the feedback. What change would you suggest to the code?
Copy linkTweet thisAlerts:
@SempervivumNov 19.2019 — I cannot answer this question without viewing the HTML context of that script. In your last snippet you add an event listener for click to the element #contact-items. Probably this is the list of contacts visible to the user. Please post the HTML of that list. Some entries will be sufficient.
Copy linkTweet thisAlerts:
@maxianna7authorNov 19.2019 — @Sempervivum#1610988

The HTML div:
``<i>
</i>&lt;div id= "contact-items"&gt;
&lt;ul id="names" class="collection with-header"&gt;<i>

</i>
`</CODE>
And here I add the &lt;li&gt;'s dynamically:

<CODE>
`<i>
</i>static addContactToList(contact) {
const itemDiv = document.querySelector('#contact-items');
const list = document.querySelector('#names');


list.insertAdjacentHTML("afterbegin",

</li>
<li class="collection-item">

<a href="#"><i class="fas fa-user text-blue "></i><span class="text-grey">${contact.name} </span></a>

<span class="contact-phone"><i class="fas fa-phone text-blue phi "><span class="text-grey ph">${contact.phone}</span></i></span>

<i class="far fa-trash-alt delete"></i>
</li> );

;


}<i>
</i>
``
Copy linkTweet thisAlerts:
@SempervivumNov 19.2019 — In order to keep things simple I recommend to add the phone number as a data attribute to the delete button like this:
static addContactToList(contact) {
const itemDiv = document.querySelector('#contact-items'); <br/>
const list = document.querySelector('#names');

<i> </i>
<i> </i>list.insertAdjacentHTML("afterbegin", <span><code>
&lt;i&gt; &lt;/i&gt; &amp;lt;/li&amp;gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;li class=&quot;collection-item&quot;&amp;gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;a href=&quot;#&quot;&amp;gt;&amp;lt;i class=&quot;fas fa-user text-blue &quot;&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;span class=&quot;text-grey&quot;&amp;gt;${contact.name} &amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;span class=&quot;contact-phone&quot;&amp;gt;&amp;lt;i class=&quot;fas fa-phone text-blue phi &quot;&amp;gt;&amp;lt;span class=&quot;text-grey ph&quot;&amp;gt;${contact.phone}
&lt;i&gt; &lt;/i&gt; &amp;lt;/span&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/span&amp;gt;
&lt;i&gt; &lt;/i&gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;i class=&quot;far fa-trash-alt delete&quot; data-phone=&quot;${contact.phone}&quot;&amp;gt;&amp;lt;/i&amp;gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;/li&amp;gt; </code></span>);
}

Then we can get it easily in the event listener:
<i>
</i> // add event listener to each delete button
const delButtons = document.querySelectorAll('#contact-items .delete');
for (let i = 0; i &lt; delButtons.length; i++) {
delButtons[i].addEventListener('click', function () {
const phone = this.getAttribute('data-phone');
removeContact(phone);
});
}


As the phone number is inserted by templating, I think it's OK to insert it twice.
Copy linkTweet thisAlerts:
@maxianna7authorNov 20.2019 — @Sempervivum#1610992

Thanks for the solution. Unfortunately, this works only at the UI level, still doesn't remove the item from the local storage. After some logs, I came up with the conclusion the issue is not in the event listener but somewhere in the removeContact method. I also tried to use use the filter method but still doesn't work:

contacts = contacts.filter(contact =&gt; contact.phone !== phone);

So far, I can't figure out where the code breaks...
``<i>
</i>static removeContact(phone) {
const contacts = Store.getContact();

contacts.forEach((contact, index) =&gt; {

if(contact.phone === phone) {
contacts.splice(index, 1);
}

});

localStorage.setItem('contacts', JSON.stringify(contacts));

console.log(contacts);

}

} <i>

</i>
``


@Sempervivum#1610992
Copy linkTweet thisAlerts:
@SempervivumNov 20.2019 — As I wrote previously I'm not shure about the type of the phone number: String or Number? You are using a strict comparison:

`if(contact.phone === phone) {</C><br/>
Try to allow for implicit type conversion:<br/>
<C>
if(contact.phone == phone) {</C><br/>
or cast the type:<br/>
<C>
if(String(contact.phone) === phone) {`
Copy linkTweet thisAlerts:
@SempervivumNov 20.2019 — PS: What does `console.log(contacts);` output? Is the contact that should be deleted still there?
Copy linkTweet thisAlerts:
@maxianna7authorNov 20.2019 — @Sempervivum#1611007

Basically, the console.log shows the same 3 items array before and after removeContact.

(3) [{…}, {…}, {…}] So that method doesn't work. The event target is ok, the problem is clearly at the function level. I will try your last solutions.
Copy linkTweet thisAlerts:
@maxianna7authorNov 20.2019 — @Sempervivum#1611007

Oddly enough, the other solutions give the same result...It looks like that method doesn't want to work.
Copy linkTweet thisAlerts:
@SempervivumNov 20.2019 — Is that page online, so that you can post the URL?

If not we should do some debugging:
static removeContact(phone) {
const contacts = Store.getContact();
<br/>
<i> </i> contacts.forEach((contact, index) =&gt; {
<i> </i> console.log(contact.phone);
<i> </i> console.log(phone);
<i> </i> if(contact.phone === phone) {
<i> </i> contacts.splice(index, 1);
<i> </i> }
<i> </i>
<i> </i> });
<i> </i>
<i> </i> localStorage.setItem('contacts', JSON.stringify(contacts));
<i> </i>
<i> </i>console.log(contacts);
<i> </i>
<i> </i>}

}
Copy linkTweet thisAlerts:
@maxianna7authorNov 20.2019 — @Sempervivum#1611013

This is the capture of the console, the way you suggested:

``<i>
</i>contacts.forEach((contact, index) =&gt; {
console.log(contact.phone);
console.log(phone);<i>
</i>
``

[upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-11-20/1574253731-198513-log.jpeg]
Copy linkTweet thisAlerts:
@SempervivumNov 20.2019 — I see, this way it cannot work as there is no equality. Are you shure that your added the event listener exactly the way I recommended?
// add event listener to each delete button
const delButtons = document.querySelectorAll('#contact-items .delete');
for (let i = 0; i &lt; delButtons.length; i++) {
delButtons[i].addEventListener('click', function () {
const phone = this.getAttribute('data-phone');
removeContact(phone);
});
}

If there is no success, please post the code that has been created by the template, as visible in the HTML inspector: Rightclick and then "inspect element".
Copy linkTweet thisAlerts:
@maxianna7authorNov 21.2019 — Yes, I used the code you proposed. The items are still deleted only in the UI, not local storage.

Here is what I have in the console now, after removing an item:

[upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-11-21/1574324546-737439-capture-log.jpeg]

And here's the HTML template generated:
``<i>
</i>&lt;body&gt;

&lt;div class="container"&gt;

&lt;h1 class="center-align" id="htitle"&gt;
&lt;i class="fas fa-address-book fa-lg text-blue"&gt;&lt;/i&gt; My&lt;span class="text-blue"&gt;Phone&lt;/span&gt;Book&lt;/h1&gt;

&lt;i class="fas fa-search"&gt;&lt;/i&gt; &lt;input type="text" id="filterInput" placeholder="Search a contact..."&gt;

&lt;!-- Add a Contact--&gt;
&lt;div class="quickadd"&gt;
&lt;button id="QuickAdd" class="waves-effect blue darken-2 btn"&gt;+ Add New Contact&lt;/button&gt;
&lt;/div&gt;
&lt;div class="quickaddForm"&gt;
&lt;form id="book-form"&gt;
&lt;div class="form-group"&gt;
&lt;input type="text" id="name" placeholder="Add a name" class="form-control"&gt;
&lt;/div&gt;
&lt;div class="form-group"&gt;
&lt;input type="text" id="phone" placeholder="Add a phone number" class="form-control"&gt;
&lt;/div&gt;
&lt;i class="waves-effect blue darken-2 btn waves-input-wrapper" style=""&gt;&lt;input type="submit" id="Add" value="Add Contact" class="waves-button-input"&gt;&lt;/i&gt;
&lt;i class="waves-effect blue darken-2 btn waves-input-wrapper" style=""&gt;&lt;input type="button" id="Cancel" value="Cancel" class="waves-button-input"&gt;&lt;/i&gt;

&lt;/form&gt;&lt;/div&gt;
&lt;div id="contact-items"&gt;
&lt;ul id="names" class="collection with-header"&gt;

&lt;li class="collection-item"&gt;

&lt;a href="#"&gt;&lt;i class="fas fa-user text-blue "&gt;&lt;/i&gt;&lt;span class="text-grey"&gt;So &lt;/span&gt;&lt;/a&gt;

&lt;span class="contact-phone"&gt;&lt;i class="fas fa-phone text-blue phi "&gt;&lt;span class="text-grey ph"&gt;9999999999&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;

&lt;i class="far fa-trash-alt delete" data-phone="9999999999"&gt;&lt;/i&gt;
&lt;/li&gt;

&lt;li class="collection-item"&gt;

&lt;a href="#"&gt;&lt;i class="fas fa-user text-blue "&gt;&lt;/i&gt;&lt;span class="text-grey"&gt;Moniu &lt;/span&gt;&lt;/a&gt;

&lt;span class="contact-phone"&gt;&lt;i class="fas fa-phone text-blue phi "&gt;&lt;span class="text-grey ph"&gt;777777777777&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;

&lt;i class="far fa-trash-alt delete" data-phone="777777777777"&gt;&lt;/i&gt;
&lt;/li&gt;
&lt;!--
&lt;li class="collection-header"&gt;
&lt;h5&gt;A&lt;/h5&gt;
&lt;/li&gt;
&lt;li class="collection-item"&gt;


&lt;a href="#"&gt;&lt;i class="fas fa-user"&gt;&lt;/i&gt;Abe&lt;/a&gt;

&lt;i class="fas fa-phone"&gt;+40 726998877&lt;/i&gt;


&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
--&gt;
&lt;/ul&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;!-- Compiled and minified JavaScript --&gt;
&lt;script src="https://code.jquery.com/jquery-3.3.1.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"&gt;&lt;/script&gt;
&lt;script src="script.js"&gt;&lt;/script&gt;
&lt;/body&gt;<i>
</i>
``
Copy linkTweet thisAlerts:
@SempervivumNov 21.2019 — @maxianna7#1611041 I used the HTML you posted and created a completed test file:
&lt;!doctype html&gt;
&lt;html lang="en"&gt;

&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;title&gt;Convert Wavelength to Hex&lt;/title&gt;
&lt;link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" /&gt;
&lt;/head&gt;

&lt;body&gt;
&lt;div class="container"&gt;

<i> </i> &lt;h1 class="center-align" id="htitle"&gt;
<i> </i> &lt;i class="fas fa-address-book fa-lg text-blue"&gt;&lt;/i&gt; My&lt;span class="text-blue"&gt;Phone&lt;/span&gt;Book&lt;/h1&gt;

<i> </i> &lt;i class="fas fa-search"&gt;&lt;/i&gt; &lt;input type="text" id="filterInput" placeholder="Search a contact..."&gt;

<i> </i> &lt;!-- Add a Contact--&gt;
<i> </i> &lt;div class="quickadd"&gt;
<i> </i> &lt;button id="QuickAdd" class="waves-effect blue darken-2 btn"&gt;+ Add New Contact&lt;/button&gt;
<i> </i> &lt;/div&gt;
<i> </i> &lt;div class="quickaddForm"&gt;
<i> </i> &lt;form id="book-form"&gt;
<i> </i> &lt;div class="form-group"&gt;
<i> </i> &lt;input type="text" id="name" placeholder="Add a name" class="form-control"&gt;
<i> </i> &lt;/div&gt;
<i> </i> &lt;div class="form-group"&gt;
<i> </i> &lt;input type="text" id="phone" placeholder="Add a phone number" class="form-control"&gt;
<i> </i> &lt;/div&gt;
<i> </i> &lt;i class="waves-effect blue darken-2 btn waves-input-wrapper" style=""&gt;&lt;input type="submit" id="Add"
<i> </i> value="Add Contact" class="waves-button-input"&gt;&lt;/i&gt;
<i> </i> &lt;i class="waves-effect blue darken-2 btn waves-input-wrapper" style=""&gt;&lt;input type="button" id="Cancel"
<i> </i> value="Cancel" class="waves-button-input"&gt;&lt;/i&gt;

<i> </i> &lt;/form&gt;
<i> </i> &lt;/div&gt;
<i> </i> &lt;div id="contact-items"&gt;
<i> </i> &lt;ul id="names" class="collection with-header"&gt;

<i> </i> &lt;li class="collection-item"&gt;

<i> </i> &lt;a href="#"&gt;&lt;i class="fas fa-user text-blue "&gt;&lt;/i&gt;&lt;span class="text-grey"&gt;So &lt;/span&gt;&lt;/a&gt;

<i> </i> &lt;span class="contact-phone"&gt;&lt;i class="fas fa-phone text-blue phi "&gt;&lt;span
<i> </i> class="text-grey ph"&gt;9999999999&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;

<i> </i> &lt;i class="far fa-trash-alt delete" data-phone="9999999999"&gt;&lt;/i&gt;
<i> </i> &lt;/li&gt;

<i> </i> &lt;li class="collection-item"&gt;

<i> </i> &lt;a href="#"&gt;&lt;i class="fas fa-user text-blue "&gt;&lt;/i&gt;&lt;span class="text-grey"&gt;Moniu &lt;/span&gt;&lt;/a&gt;

<i> </i> &lt;span class="contact-phone"&gt;&lt;i class="fas fa-phone text-blue phi "&gt;&lt;span
<i> </i> class="text-grey ph"&gt;777777777777&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;

<i> </i> &lt;i class="far fa-trash-alt delete" data-phone="777777777777"&gt;&lt;/i&gt;
<i> </i> &lt;/li&gt;
<i> </i> &lt;/ul&gt;
<i> </i> &lt;/div&gt;

<i> </i>&lt;/div&gt;
<i> </i>&lt;script&gt;
<i> </i> const contacts = [
<i> </i> { phone: "9999999999", name: "So" },
<i> </i> { phone: "777777777777", name: "Moniu" }
<i> </i> ];
<i> </i> function removeContact(phone) {
<i> </i> // const contacts = Store.getContact();

<i> </i> contacts.forEach((contact, index) =&gt; {
<i> </i> console.log(phone);

<i> </i> if (contact.phone === phone) {
<i> </i> contacts.splice(index, 1);
<i> </i> }
<i> </i> });
<i> </i> localStorage.setItem('contacts', JSON.stringify(contacts));
<i> </i> }

<i> </i> const delButtons = document.querySelectorAll('#contact-items .delete');
<i> </i> for (let i = 0; i &lt; delButtons.length; i++) {
<i> </i> delButtons[i].addEventListener('click', function () {
<i> </i> const phone = this.getAttribute('data-phone');
<i> </i> console.log(phone);
<i> </i> removeContact(phone);
<i> </i> });
<i> </i> }
<i> </i>&lt;/script&gt;
&lt;/body&gt;

&lt;/html&gt;
Result: This is working fine, when viewing the local storage the item has been deleted correctly.

Now I'm a bit helpless and have no idea why it doesn't work for you.

Is there no way for you to put it online and post the URL?
Copy linkTweet thisAlerts:
@maxianna7authorNov 22.2019 — He

@Sempervivum#1611043

Here is a link to the folder on Drive:

[](https://drive.google.com/drive/folders/1z-s4Pj6Ld_HjhYHl4zK_5TPcb94bCfn-?usp=sharing)

Thank you
Copy linkTweet thisAlerts:
@maxianna7authorNov 22.2019 — @Sempervivum#1611043

Here is a link to the folder on Drive:

[https://drive.google.com/drive/folders/1z-s4Pj6Ld_HjhYHl4zK_5TPcb94bCfn-?usp=sharing](url)

Thank you
Copy linkTweet thisAlerts:
@SempervivumNov 22.2019 — When testing the files I found out the reason for this issue:

The contacts are created dynamically, thus the event listener has to be added when a contact has been created:
static addContactToList(contact) {
const itemDiv = document.querySelector('#contact-items');
const list = document.querySelector('#names');


<i> </i>list.insertAdjacentHTML("afterbegin", <span><code>
&lt;i&gt; &lt;/i&gt; &amp;lt;/li&amp;gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;li class=&quot;collection-item&quot;&amp;gt;
&lt;i&gt; &lt;/i&gt;
&amp;lt;a href=&quot;#&quot;&amp;gt;&amp;lt;i class=&quot;fas fa-user text-blue &quot;&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;span class=&quot;text-grey&quot;&amp;gt;${contact.name} &amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;
&lt;br/&gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;span class=&quot;contact-phone&quot;&amp;gt;&amp;lt;i class=&quot;fas fa-phone text-blue phi &quot;&amp;gt;&amp;lt;span class=&quot;text-grey ph&quot;&amp;gt;${contact.phone}&amp;lt;/span&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/span&amp;gt;
&lt;i&gt; &lt;/i&gt;
&lt;i&gt; &lt;/i&gt;&amp;lt;i class=&quot;far fa-trash-alt delete&quot; data-phone=&quot;${contact.phone}&quot;&amp;gt;&amp;lt;/i&amp;gt;
&amp;lt;/li&amp;gt; </code></span>);

<i> </i>// add event listener to the delete button that has been added
<i> </i>const delButton = document.querySelector("#contact-items .delete[data-phone='" + contact.phone + "']");
<i> </i>delButton.addEventListener('click', function () {
<i> </i> const phone = this.getAttribute('data-phone');
<i> </i> console.log(phone);
<i> </i> Store.removeContact(phone);
<i> </i>});
}
Copy linkTweet thisAlerts:
@maxianna7authorNov 22.2019 — @Sempervivum#1611086

Great solution, it finally works! 😃

Thanks a lot for taking the time to help me!
×

Success!

Help @maxianna7 spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 3.28,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,

tipper: Anonymous,
tipped: article
amount: 10 SATS,
)...