Check out a free preview of the full Vanilla JS: You Might Not Need a Framework course:
The "Displaying Items in the Cart" Lesson is part of the full, Vanilla JS: You Might Not Need a Framework course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano walks through and implements the code for the CartItem component to display the items that have been added to the cart. A student's question regarding why importing the custom element renders the content is also covered in this segment.

Get Unlimited Access Now

Transcript from the "Displaying Items in the Cart" Lesson

[00:00:00]
>> So what's the last part? Finishing the order, okay? That is not really complicated, it's more of the same thing. So, for finishing the cart, I also have something similar to the home page that we have list items. So I also create a component for an order item, so we have the design separately.

[00:00:27] So to finish the cart, if you're following along using the documentation, we are now in chapter five, lesson seven, finishing the cart. So here you have the steps. This is also more copy and paste and then I will explain maybe something that is different but it's kind of creating

[00:00:46] another web component. Card item will not use Shadow DOM. Remember why I'm not using Shadow DOM on these items that we are repeating, so we can share the document and we can share CSS and everything for that particular page. It's not mandatory, it's just one decision and a way to show you that you don't need to use Shadow DOM everywhere.

[00:01:09] You decide on each web component when to create a new document and when to share the document with the rest of the HTML. So we are going to create CartItem.js. That's another web component, that doesn't have its own CSS because it's sharing the CSS with its container. This one has nothing special, it's just filling data, just that.

[00:01:40] It's reading the data differently, you will see in a minute where this is coming from. That's cart item and then we have order page, the whole page. So I'm going to copy this. It's long because it has also a form that we will finish in a minute. So this is OrderPage.js.

[00:02:06] Go into paste OrderPage.js to replace everything that I have here, and I'm going to get rid of the default. So let's see if that works and then I will explain what's going on. So first, if I'm going to the cart, it says your order is empty, so that's different, okay?

[00:02:30] Is different from before. We also need to solve a bug that we have when we're going back to the home that we don't see the home, okay? So we need solved that problem later. Why the router is not rendering the home, that's a bug. So but if I add something, let's add black americano and two cappuccinos, so I have three items.

[00:02:52] If I'm going to the cart, I see nothing, okay? But I'm seeing something, but I'm not seeing the items, so let's inspect that. What's going on here? It's great in me to cart items, not three, why? Because two were cappuccinos, so the same item which is okay, but why is not rendering?

[00:03:16] I'm not seeing the cart item rendering, we already had that issue before. Every time you create a new web component, you need to call that web component. And you say, yeah, but it's there. Yeah, but we don't have Webpack. We don't have any tool here that knows that there is a JavaScript file that need to be executed.

[00:03:39] So the only way for the browser to know at this point that there is a new web component registered is to import that here. If not, it's not going to work. And we don't get an error because the browser says, okay, I will render this as an empty element.

[00:03:58] Okay, that's not actually an error. So in this case, I'm going to add the cart item, like so. A way to avoid this issue, there is a way, or a design pattern to avoid this problem forgetting about importing the web component. And that is, instead of calling the customElements define in each JavaScript file, do that in app.js.

[00:04:28] So if you copy this into app.js, somewhere, where you declare all your web components, you are forced to import that and you will not forget. And also you are defining this in app.js and not in a separate file, okay? But I did that because if you're coming from a library, you're used to do the setup in a different file.

[00:04:50] The problem with Vanilla JS is that the browser doesn't know about all your files in the server, you have to call them. Okay, so if you don't want to have this problem, clone this, copy all the define declarations to the app.js or to a JS specifically targeting that purpose.

[00:05:12] So now we can add, again, a couple of things here. And I can see the details, two black americanos, three cappuccinos, one cold brew. And if I delete one, it works. And also look at this. When we delete something, it also updates the badge, Because actually now we have two listeners for the same event.

[00:05:45] Because the order page is also rendering when the appcartchange, as the app.js. So we have here a component and also an app.js that is global, listening for the same window event. If this was a document event, it's not gonna work because of different DOM's. We have the original DOM and the Shadow DOM, and then it's not going to be so simple as adding an event listener with document add event listener, okay?

[00:06:20] Makes sense? You have any questions? Yeah.
>> It's strange that the HTML is there, but wasn't showing up. I don't understand why importing the custom element does something to render it. In both cases, the HTML is there, it seems like something should be displayed in the browser.
>> So what's the problem?

[00:06:46] So let me show you this. So if I go to one of these templates, now it can be the menu page templates and add in frontendmasters-genius-code, that's an HTML element. So if I execute this, I don't see the rendering, but it's in the DOM. Because that's how browsers work.

[00:07:09] And fortunately, let's say because that's how we evolve HTML, are the new elements and older browsers will still try to render that. So, here we have the frontendmasters-genius-code, rendered, but of course, nothing is inside. So, the browser by default, will render that in the DOM, but empty, okay?

[00:07:35] So it has no real rendering, but it's in the DOM, it's not giving me an error, it's just rendering it. How the browser knows that there is a class there that should be executed, because it's a web component or actually a custom element. Well, you actually need to execute, Define over custom elements.

[00:07:58] So if in the JavaScript execution runtime process you didn't call define, the browser doesn't know about it. So this is an ECMAScript module. How does an ECMAScript module call this to execute it? If you import it. When you, if I import in app.js one file, even if, you can see it, I'm not sure if you'll see that on the video but it's kind of grayed out.

[00:08:29] In VS code that says that case it's like you're not using these objects, but actually what I want is kind of a side effect. So a side effect of importing this JavaScript file is that it's going to execute the files. And executing the file will execute customElements.define.

[00:08:49] That's why if you don't want to have that problem, one solution is to call define somewhere else. For example, in app.js, or in another JavaScript file that you call components.js, or register.js, something like that. This is like on Angular, if you don't add a component in the array of components, it's not gonna work, something similar happens there.

[00:09:13] So there are some frameworks where you have this problem as well, you have to register the components that you wanna use.