I started learning Javascript a month ago, and I am trying to build projects by myself.
To this point I have been using data attribute in html to pass an unique ID and based on that ID I edited/deleted element/item off the list.
For example I am making a Workout Track app and when user enters data, list item is created and inserted with unique ID. For example:
<li class="workout workout--${workout.type}" data-id="${workout.id}">
Afterward I listen for click on entier List Container and based on proximity to the list item and clicked button(Edit/Delete) I get the ID and find object in the array.
const workout = this.#workouts.find(work => work.id === workoutEl.dataset.id);
This is an easy system and it works until you mess with ID in HTML. So what would be a better and safer way to implement what I need. I still check if ID exists and if it belongs to user to process it further, but is there any other smarter way of doing this.
TLDR: Smarter/better way of handling CRUD operations based on ID of element/item, besides using HTML data
>Solution :
If the client messes with the HTML manually, all bets are off. There’s no way to fully guard against such things – ultimately, it’s the client’s machine, and the client can run whatever code they want on it. Trying to prevent that is a waste of time. Rather, if the client wants to do something that affects something outside of their browser (such as make a change to the database that the data is sourced from), you have the right idea – validate it on the server to make sure they have permissions to do what they’re trying to do.
That’s honestly all you need to do, and is very common practice.
You can make it more difficult for the user to mess with the logic of the application by putting the IDs in, say, a WeakMap that links a <li> to a particular workout:
const workoutsByLis = new WeakMap();
// ...
// when you create a LI:
const workoutLi = document.createElement('li');
workoutLi.className = `workout workout--${workout.type}`;
workoutsByLis.set(workoutLi, id);
This way, the ID isn’t exposed in the HTML or retrieved from it. To get the ID from a clicked <li>, you’d then just do
const workoutId = workoutsByLis.get(e.target);
(or e.currentTarget – however the listener is attached, navigate to the <li>, then pass it to workoutsByLis.get)
Or you could not bother and keep using your current approach, which is fine.