0

I want to target one of this object however the function returns me both objects, how can I target only one specific object inside the array, to be deleted.

// This is the object stored in the local storage:
const data = [{
    title: 'one',
    text: 'one',
    date: '2022-08-10'
  },
  {
    title: 'two',
    text: 'two',
    date: '2022-08-10'
  }
]


const deleteNote = (event) => {
  let data = Array.from(JSON.parse(localStorage.getItem("notes")));
  data = data.filter(function(item) {
    return item !== event;
  });
  console.log(data);
};
//The HMTL:

<div>
  <span id="index">Note 1</span>
  <h3>one</h3>
  <h4>Date: 2022-08-10</h4>
  <p>one</p>
  <button class="btn-details">View Details</button>
  <i class="fa-solid xclose" onclick="deleteNote(this)">x</i>
  <button class="xedit">Edit</button></div>
</div>

4
  • 1
    Your input data in the question is missing some close quotes making it invalid. What is event? Is it a title, text? Commented Aug 3, 2022 at 17:52
  • Are you saying that event is an object that looks like {title: 'one', text: 'one', date: '2022-08-10}? Commented Aug 3, 2022 at 17:54
  • Please try to create a real running example Commented Aug 3, 2022 at 17:57
  • Additional and important information was obtained in the comments of a proposed answer. The OP's title is a bit misleading because the object code was OK, however the technique for obtaining the index from the DOM was the underlying problem. For this reason, I do invite the OP to amend the question to include some HTML from the accepted answer. This will help add context to why other answers were not accepted. Commented Aug 4, 2022 at 17:09

4 Answers 4

1

To delete an object, you need to specify some unique property of that object (usually id) or an index.

const data = [{
    title: 'one',
    text: 'one',
    date: '2022-08-10'
},
{
    title: 'two',
    text: 'two',
    date: '2022-08-10'
}]

const deleteNote = (data, noteTitle) => {
  let filterNotes = data.filter(function(item) {
    return item.title !== noteTitle;
  });

  return filterNotes
};

let notes = deleteNote(data, 'one')
console.log(notes)

Sign up to request clarification or add additional context in comments.

3 Comments

This example does not use local-storage, which seems important to the OP. For that reason, I do not believe this properly answers the question.
LocalStorage is not the case. He parsed it into an array.
Since it's in one of the provided hashtags for the question, it should be considered an important detail to the OP (and thus should be part of an accepted solution.)
0

If your events come from adjacent elements, you'll need to find them using parentElement and children. The children will work fine if the ordering stays the same, but using unique IDs is ultimately a better solution, explanation in the comments.

(This HTML was obtained through question/answer in the comments section)

<div>
    <span id="index">Note 1</span>
    <h3>one</h3>
    <h4>Date: 2022-08-10</h4>
    <p>one</p>
    <button class="btn-details">View Details</button>
    <i class="fa-solid xclose" onclick="deleteNote(this)">x</i>
    <button class="xedit">Edit</button></div>
</div>
const data = [{
    title: 'one',
    text: 'one',
    date: '2022-08-10'
},
{
    title: 'two',
    text: 'two',
    date: '2022-08-10'
}];

localStorage.setItem('notes', JSON.stringify(data));

const deleteNote = (target) => {
    let data = Array.from(JSON.parse(localStorage.getItem("notes")));
    console.log("BEFORE:", data);
    data = data.filter(function(item) {
        var parentDiv = target.parentElement;
        var value = parentDiv.children[1].innerHTML; // [1] is the index of your <h3> tag
        return item.title !== value;
    });
    console.log("AFTER:", data);
};

NOTE: This will NOT remove it from local storage, you'll have to write the data JSON value back again in your action for the deletion to be remembered.

9 Comments

Hello, the event.target .value doesnt work because this function is onclick in the button that is created in the innerHTML which shows the data, I tried to target event.parentNode.children[1].value so it would be the title but it also doesnt work
@Rod021 can you please share what the <button>...</button> code looks like when rendered on the page?
it looks like this : <i class="fa-solidxclose" onclick="deleteNote(this)" ></i>
Hey @ tresf, this element.title , this is the entire innerHTML += ` <div> <span id="index">Note ${index + 1}</span> <h3>${element.title}</h3> <h4>Date: ${element.date}</h4> <p>${element.text}</p> <button class="btn-details">View Details</button> <i class="fa-solid xclose" onclick="deleteNote(this)" ></i> <button class="xedit">Edit</button> </div>
it is working, thank you so much , you have no idea how grateful I'm!
|
0

I'm assuming your deleteData is an event handler. In that case, event is of Event type. Assuming that the object this handler is attached to contains the data you want to delete in some way, you could do something like:

const deleteNote = (event) => {
  const data = Array.from(JSON.parse(localStorage.getItem("notes")));

  // Return the note you want to delete
  const itemToDelete = data.filter(function(item) {

    // ideally, I'd store the note (as a JSON string) in data attribute, so this is what I'd do. Otherwise use JSON.parse(event.target.value). JSON strings stored in data attributes should be automatically converted to a JS object when retrieved.
    return item === event.target.dataset.note;
  });

  // filter returns an empty array if nothing meets the conditions.
  if (itemToDelete.length) {

    // Deletes the note from data.
    data.splice(data.indexOf(itemToDelete[0]), 1);
  }

  // Update localStorage to new data.
  localStorage.setItem("notes", JSON.stringify(data));
};

event refers to the Event that occurred (it contains properties like target, type, timeStamp, and others, but target is what we need). event.target refers to the object (DOM Element) that the event occurred on.

In order to filter the correct data, you will need to attach the note in some way that the handler is attached to. Assuming (based on provided code) that you have a delete button/anchor per note, the note should be referenced on the anchor/button in a data attribute. For example:

<a href="/crud/delete/route" data-note="{\"title\":\"one\",\"text\":\"one\",\"date\":\"2022-08-10\"}">delete</a>

(proper JSON string can only use double-quotes, hence the escapes...could enclose JSON string in single-quotes but I prefer to keep formatting consistent).

You wouldn't obviously want to type the note manually, I only did this to provide an example. I'd supply the data nodes programmatically on the JS end using DOM manipulation. If this is React or a templating language then it is even easier.

In either case, in your filter, you need to be more specific, since event will not be equal to a note as mentioned above, whether you use a data attribute or set a value to equal the item.title or something, as other answers suggest.

Comments

0

Here's a full example based on what little we know of your code.

It produces a table from the notes data along with some delete buttons. Clicking on a delete button will remove the row, and filter that row from the notes data. Note: to facilitate this I've added an id property to the data.

The save button can then push that updated array back to local storage.

// Get your notes data from local storage
// let notes = JSON.parse(localStorage.getItem('notes'));
let notes = [
  { id: 1, title: 'one', text: 'one', date: '2022-08-10' },
  { id: 2, title: 'two', text: 'two', date: '2022-08-10' },
  { id: 3, title: 'three', text: 'three', date: '2022-08-10' },
  { id: 4, title: 'four', text: 'four', date: '2022-08-10' }
];

// Creates a delete button
function buildDelete(id) {
  return `<td><button class="delete" data-id="${id}">Delete</button></td>`;
}

// Creates a row using the values from the object
function buildRow(obj) {
  const row = [];
  row.push('<tr>');
  for (const prop in obj) {
    row.push(`<td>${obj[prop]}</td>`);
  }
  row.push(buildDelete(obj.id));
  row.push('</tr>');
  return row.join('');
}

// Filter out the row with the corresponding id
function deleteNote(id) {
  return notes.filter(item => {
    return item.id !== +id;
  });
}

// When a child element of the table is clicked
// we check first to see if it's a delete button
// grab the id, update `notes`, and then remove the
// row from the table
function handleClick(e) {
  if (e.target.matches('.delete')) {
    const { id } = e.target.dataset;
    notes = deleteNote(id);
    e.target.closest('tr').remove();
  }
}

// Saves the data back to local storage
function saveNotes() {
  console.log(JSON.stringify(notes));
  // localStorage.setItem(JSON.stringify(notes));
}

// Creates a table from the notes data
const html = `
  <table>
    ${notes.map(buildRow).join('')}
  </table>
  <button class="save">Save</button>
`;

// Attaches the table HTML to the document body
document.body.innerHTML = html;

// Cache the table element, and add an event listener to it
const table = document.querySelector('table');
table.addEventListener('click', handleClick);

// Cache the save element, and add an event listener to it
const save = document.querySelector('.save');
save.addEventListener('click', saveNotes);
table { border-collapse: collapse; }
td { padding: 0.3em; border: 1px solid #dfdfdf; }
.delete:hover { cursor: pointer; }
.save { margin-top: 1em; }

Additional documentation

3 Comments

This example does not use localStorage, so I do not believe it answers the OPs question.
Local storage doesn't work with snippets. I used the data that the OP said they were getting from local storage which was included in the question.
That was my initial observation as well, but after re-reading it, it's rather trivial to infer how the OP is working with localStorage, since the example parses the JSON back out. The use of keyword event infers an event listener. Since these are important parts of the question, they should be part of the solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.