JavaScript Design Patterns for Web Apps

Add & Delete Commands

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
JavaScript Design Patterns for Web Apps

Check out a free preview of the full JavaScript Design Patterns for Web Apps course

The "Add & Delete Commands" Lesson is part of the full, JavaScript Design Patterns for Web Apps course featured in this preview video. Here's what you'd learn in this lesson:

Max uses the Command pattern to create ADD and DELETE commands to handle adding and removing items. The advantage of separating this logic from the main application is its reusability. TodoList items can be added from the UI or any other event, and there is now a single class through which these commands are funneled.

Preview
Close

Transcript from the "Add & Delete Commands" Lesson

[00:00:00]
>> Maximiliano Firtman: So far, we have already created the mixing and the classes. We have one more step before we can actually connect this together and see if it's working. We're going to implement the command design pattern. For that, I'm going to create another file within the web app folder, command.js.

[00:00:23]
And here, we're going to implement actually one class and then two literal objects. We're going to create a class for one command. Actually, it's one command execution, but typically, this is what is known as the command. So the command is a class that will typically has the name.

[00:00:43]
So remember, what's a command, something that you wanna execute in your app. So for example, it can be add, delete. So every action has a name. And also, it can contain arguments. So then just for making this easier to construct, we can create the constructor, receiving both name and args, and just applying this,
>> Maximiliano Firtman: To the properties.

[00:01:13]
That's all our class, nothing else. Then I'm going to create some kind of enum for all the classes we have. We don't have enums in JavaScript, so we can simulate the idea of an enum, so like a short set of options. We can call this Commands. I'm using capital C to express it's kind of a singleton class, even if it's not a class, okay, it's an object.

[00:01:43]
And then we have two right now, ADD and DELETE. And because this is object literal syntax, we need to actually set a value to those. This is just for the name. So then we don't need to pass the name, we can just use that constant value, okay, like emulating enums in other languages.

[00:02:05]
And finally, we need to create another object that should be a singleton. So, instead of creating a class and applying the singleton pattern there, I can just use the idea of an object literal. And I'm going to create the CommandExecutor.
>> Maximiliano Firtman: That will for now just have one only method, execute, that will receive a command and it will try to execute that.

[00:02:31]
So this is the command. One point, we could also do OOP here and create commands extending from command. So there are more ways to solve the problem, but I don't wanna overreact, okay? Because we can actually cross the line and add so much complexity to this that we are going into an anti-pattern.

[00:02:54]
So for now, I will just do a switch, asking for the name of that command, and then check. If it's Commands.ADD, I will do something, and if it's Commands.DELETE, I will do something else. Okay, I can do a break as well. On both ADD and DELETE, I think I will need the TodoList.

[00:03:17]
I remember our to-do list is the class that we have created the list, that has the singleton using getInstance. So something that I can do is here, before the switch, I can create the property, a reference to that TodoList.getInstance. So we can use the instance on both the ADD and DELETE commands.

[00:03:44]
Have in mind that TodoList is a class that is available on a separate file on a separate module. So VS Code may have already added the import that we know it's in value for the browser. So we need to add the .js to that import as well. But now we need to add some code.

[00:04:05]
And actually, I can use pretty much the same code that I had before, okay, in our todo without patterns. But anyway, I need the input, the DOM element. And if you remember, we do have in globalThis, the DOM object. So globalThis.DOM, I'm fighting with the autocomplete, globalThis.DOM.todoInput. That's my input.

[00:04:37]
So I'm going to take the text from from that input.value.trim. I'm trimming the spaces, just in case. And then I will create an itemToAdd.
>> Maximiliano Firtman: Actually, before creating an item, I should check, for example, if the item is actually available. Because remember that idea that we don't wanna add twice the same todo.

[00:05:08]
So lunch, it should be there once. So we can check first here if it exists or not. So we can say this is the itemToAdd. So we can call, for our todoList, our find. Remember, we do have a find method. So we're going to find if, A todo with that text already exists there.

[00:05:38]
So then, we're going to add something to the list if two conditions are true. First, the text shouldn't be just empty string, okay? And also, we need the itemToAdd to be null. Well, actually, we can change the name. Here, it can be itemInList. I think that will be better for understanding what it is, right?

[00:06:08]
So then, if that's the case, I will first remove the value from the input, so I will clear the input. And then I will talk to my todoList and I will add a new todoItem that is another class using that text, okay? So if those conditions are happening, that means that I don't have the todoItem in the list, and also it's not empty, the text is not empty, I'm going to add something there.

[00:06:40]
And just verify that when the new todoItem class was added here, it's in the right place with the .js import, if you're using VS Code. Okay, that's for that. And then for DELETE, we're going to use the arguments for DELETE. Remember that a command has arguments. So the arguments, typically, talking about these arguments, typically, it's an array.

[00:07:06]
It's not mandatory, we are creating this, okay? But on the design pattern, typically, arguments is an array. That's why it's args, okay?. There is an s, so it's an array. So in this case, when we are deleting, we are receiving one argument that is the text that we wanna delete.

[00:07:22]
So we can actually destructure the array and say the textToDelete, or the item to delete, it's from the current command arguments. This is destructuring. This is like sub zero, it's destructuring the first element. And then we will code to the list, the DELETE method, delete, passing as an argument, the textToDelete.

[00:07:53]
So at at some point, I'm pretty sure that some of you are thinking, I'm not sure if all of you, but some of you're thinking that this is too complex compared with the other example. And yeah, I get it, okay? I feel the pain. But believe me that in a couple of minutes, you will start understanding why this is better, mostly when we are adding features.

[00:08:17]
And you will see how simple it is to add more features after you have implemented. So it's like we have some pain initially, so it's more painful initially, but after that, everything is is better, okay? Okay, and I think that we are ready with our command. So and question on this implementation?

[00:08:42]
I think array.find returns undefined instead of null. Probably, we'll see. You're talking about- Line 26 Line 26, this one? So this is itemInList. This can go into find. Okay, we can check. I can trust you, and we can check that later.
>> Speaker 2: I don't trust me, so I just looked on MDN.

[00:09:05]
>> Maximiliano Firtman: Okay, no worries. Anyway, we can also do something better. We can just check for the validity of this in terms of, we'll see. Anyway, because this is coming from find, and find is coming from classes here, from find. So actually, it's finding from array. So the question is, well, when you are using find with array, what are you getting in return?

[00:09:33]
Good question, right? So we can get here and see in the documentation, it returns a value in the array where predicate is true, and undefined, okay, otherwise. So you were right, it's undefined.
>> Speaker 2: MDN was right, I wasn't sure.
>> Maximiliano Firtman: That's okay, yeah, but that's how you drag and you browse through this documentation and see if something is wrong.

[00:09:57]
Okay, cool. So now that we have this, it's time to go back to app.js and start filling the gaps that we have there, okay? So we can use the command and also our classes and try to render something on the screen.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now