Complete Blazor Course - e-Commerce App & Clean Architecture | Frank Liu | Skillshare

Playback Speed

  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Complete Blazor Course - e-Commerce App & Clean Architecture

teacher avatar Frank Liu, Senior Software Developer

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

75 Lessons (7h 27m)
    • 1. 1.0 Introduction

    • 2. 1.1 ASP.NET Core Platform

    • 3. 1.2 How a Blazor App is Bootstrapped

    • 4. 1.3 Understanding Project Structure

    • 5. 1.4 Adding Dynamic Content

    • 6. 1.5 View, State and Events

    • 7. 2.1-2 Screen Mockup and Components Breakdown

    • 8. 2.3 Analysis and Design

    • 9. 2.4 Implementing Core Business Layer

    • 10. 2.5 Implementing Use Cases Layer

    • 11. 2.6 Data Store Plugin Interface

    • 12. 2.7 Implement In-Memory Data Store Plugin

    • 13. 2.8 Create Search Products Component

    • 14. 2.9 Implement the Search Products Screen

    • 15. 2.10 Implement the Search Bar Component

    • 16. 2.11 Implement Product Item Component

    • 17. 2.12 Implement Filtering

    • 18. 2.13 Styling with BootStrap

    • 19. 2.14 View Product Details Component

    • 20. 2.15 Summary of Section 2

    • 21. 3.1 Data Binding #1

    • 22. 3.2 Data Binding #2

    • 23. 3.3 Overview of Communication Between Components

    • 24. 3.4 Review Parameters, Route Parameters and EventCallback

    • 25. 3.5 Cascading Parameters

    • 26. 3.6 Referencing Child Componnent

    • 27. 3.7 RenderFragment

    • 28. 3.8 When does a component render

    • 29. 3.9 Component Lifecycle Events

    • 30. 3.10. Forms and Validations

    • 31. 3.11 State Management with Observer Pattern

    • 32. 4.1 Dependency Problems

    • 33. 4.2. Dependency Inversion Principle

    • 34. 4.3. Inversion of Control

    • 35. 4.4. Dependency Injection in Razor Components

    • 36. 4.5. Lifetime Management in Blazor Server

    • 37. 4.6. How to Choose the Lifetime Management

    • 38. 4.7. Lifetime Management in Blazor WebAssembly

    • 39. 5.1 Reorganize Projects to Reflect the Architecture

    • 40. 5.2 Order Entity and Business Rules

    • 41. 5.3 Shopping Cart Abstraction

    • 42. 5.4 Add Product to Shopping Cart Use Case

    • 43. 5.5 Implement Shopping Cart Plugin

    • 44. 5.6 Test Add Product to Cart Use Case

    • 45. 5.7 Improve Web UI

    • 46. 5.8 View Shopping Cart Use Case

    • 47. 5.9 View Shopping Cart Component

    • 48. 5.10 Order Line Item Component

    • 49. 5.11 Order Summary Component

    • 50. 5.12 Shopping Cart State Management

    • 51. 5.13 Shopping Cart Items Count Component

    • 52. 5.14 Delete Product and Update Quantity Use Cases

    • 53. 5.15 Delete and Update on Order Line Item Component

    • 54. 5.16 Order Repository

    • 55. 5.17 Place Order Use Case

    • 56. 5.18 Place Order Component

    • 57. 5.19 Order Confirmation Use Case and Screen

    • 58. 6.1 Admin Use Cases

    • 59. 6.2 Admin Portal Screens

    • 60. 7.1 Configure Middleware and DI

    • 61. 7.2 Authentication End Point

    • 62. 7.3 Login Screen

    • 63. 7.4 Sign Out

    • 64. 7.5 Process Orders with Admin_s user name

    • 65. 7.6 Testing the Admin Portal

    • 66. 8.1 Install and Prepare the Database

    • 67. 8.2 SQL Statement Basics

    • 68. 8.3 What is Dapper and Installation

    • 69. 8.4 Read with Dapper

    • 70. 8.5 Create with Dapper

    • 71. 8.6 Update with Dapper

    • 72. 8.7 Delete with Dapper

    • 73. 8.8 Helper Class for Dapper

    • 74. 9.1 Create a SQL Data Store Plugin with Dapper

    • 75. 9.2 Use SQL Data Store Plugin in our e-commerce App

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.





About This Class

ASP.NET Core Blazor is Microsoft latest SPA application framework. With Blazor you can build reactive full stack single page web applications with C# without much help from JavaScript.  Blazor relies on existing mature technologies like SingalR, WebAssembly and ASP.NET Core. It is being adopted or has already been adopted by most companies that utilizes Microsoft technologies. If you want to get employed in these companies, knowing how to build applications with Blazor is required or will be required very soon along with Razor pages, MVC and Web API.

In this course with 9 sections, more than 70 lectures and about 8 hours of content, you will not only follow me step by step and master Blazor, but you will also work with me implementing a good sized e-Commerce web application following Clean Architecture, starting from requirements analysis, software design, all the way to the final implementation.

The course covers the following technical topics:

  • ASP.NET Core Platform

  • Every aspect of ASP.NET Blazor

  • Components State Management

  • Dependency Injection

  • Authentication and Authorization with ASP.NET Core Identity

  • Custom Cookie Authentication

  • AutoMapper

  • Dapper

  • SQL Statements

  • HTML

  • Bootstrap

  • Requirements Analysis and Software Design

  • Clean Architecture

  • Repository for encapsulating data accessing details

By the end of the course, you will:

  • Know every aspect of Blazor in depth.

  • Be able to independently build web applications with Blazor.

  • Be able to analyze requirements and design software.

  • Understand and be able to Implement Clean Architecture.

  • And much more...

You will be building a good sized real world secured e-Commerce application with me. Together, we will build both the customer portal that allows customers to browse products catalog, add products to shopping cart, place orders and  admin portals that allows store owners to login and manage the orders.

After following the lessons and exercises in this course, you will have a good understanding of ASP.NET Core platform and you will be able to create single page web applications with Blazor Server. You will also have a good understanding of Clean Architecture and be able to use what you have learned about architecture in your own project. At the end of the course, you will become a full stack web developer knowing how to create web applications with Microsoft’s latest application framework: ASP.NET CORE 3 Blazor.

Whether you're new to ASP.NET Core Blazor or have worked with it for a bit, but are looking for a course to fill in the gaps, you will enjoy this course. Since this course not only cover the basics, but goes into each topic in depth.


Intermediate C# (you should have at least 3 - 6 months experience programming in C#)

Basic HTML

Previous knowledge of ASP.NET Core is nice to have, but it is not required since I will cover it in the course.

The Course Structure and Details

In the first two sections, we will learn about Blazor by creating part of the e-Commerce web application without hearing me talking too much about each topic of Blazor. The purpose of this is to fast track your learning experience and provide you with a solid foundation of coding web applications with Blazor.

In the third section, I will go through all the topics about Blazor one by one in depth.

Starting from the fifth section, we will together implement both the customer portal and the admin portal of our e-Commerce with authentication and authorization.

When implementing the solution, you will hear me cover Clean Architecture and you will see how I implement a Use Case Driven and Plugin Based clean architecture that is highly testable and extremely flexible for future extensions. I will show you how I do it and explain why I do it in certain ways. If you really follow these hands-on sections and implement the project with me, you will definitely learn a lot from the process of building this real world application.

In this course, both the shopping cart and Data store (database) will be implemented as plugins. We will implement two types of data store plugins: an in-memory data store and a SQL Server data store with Dapper as the micro ORM. You will see clearly how powerful it is to build solutions with this kind of architecture. (Disclaimer: Architectural choices should be made case by case, I don’t suggest you to follow my architecture presented in this course in all projects. Analysis is needed all the time.)

Who this course is for

  • C# developers who want to become full stack developers without the hassle of mastering JavaScript.

  • Developers who work with Razor pages and/or MVC along with front end frameworks/libraries and would prefer work with less JavaScript.

  • Developers with some experience  in Blazor who is looking for a comprehensive course to fill in the gaps.

  • Developers who are curious about Mirosoft's newest SPA application framework: Blazor.

  • Developers who want to learn about implementing Clean Architecture.

Meet Your Teacher

Teacher Profile Image

Frank Liu

Senior Software Developer


With a master degree in software engineering and 18 years of professional software development experience, I am excited to be an instructor on SkillShare and begin sharing my knowledge and experience through this wonderful platform. I am a full stack developer with extensive experience in .NET technologies like ASP.NET, ASP.NET Core, as well as JavaScript frameworks like Angular, React and VueJs. I am also very experienced with data including SQL Server, Reporting, ETL, Azure Data Factory and Power BI. I have a passion of learning and sharing all my experience in development as well as design and architecture.


Besides technologies, I spend a lot time reading about philosophy, thinking and reflecting on life...

See full profile

Class Ratings

Expectations Met?
  • Exceeded!
  • Yes
  • Somewhat
  • Not really
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.


1. 1.0 Introduction: Are you a C Sharp developer who dream to become a full-stack web developer without writing too much JavaScript. Core later has Microsoft newest application framework that allows you to execute C Sharp codes in the browsers, which helps from existing mature technologies. All you need to do is to write beautiful C Sharp codes that you always enjoyed doing. My name is frankly, I'm Senior Software Developer. I will be your instructor in this complete Glaser course, where I will guide you step by step to understand later in death. This is not just a theoretical course, this is also a hands-on course. You will actually get your hands dirty and work with me to develop a real world e-commerce web application was clean architecture, compose the customer portal and the admin portal. We will start with a simplified implementation of part of the application. And then slowly, we will refactor the code and improve. By the end of the course. You will know every aspect of blazer in deaths. And you will be able to independently build web applications with Core. Later, you will be able to analyze requirements and design software. And you will understand and be able to implement a use case driven and plucking based queen architecture that is highly testable and extremely flexible for future extensions. Feel free to take a look at the course description. I am excited to take this journey with you and I'll see you in the course. 2. 1.1 ASP.NET Core Platform: The blazer application framework is based on core platform, I think will help us a lot. We spend about five minutes and a stand how SPI and core works. So let's do just that. Glaeser is used to create web applications. Or web applications, process HTTP requests and return HTTP responses. Users send HTTP requests, typically from a brother, and the corresponding responses contain the information that users requested. Espn a core. Once the request is routed to the web server, the HTTP request is then encapsulated in HTTP context object. After that, the context object is passed through one middleware after another. Each middleware takes different responsibilities in processing the request. For example, some middleware take her off loading static resources. Some take care of generating dynamic contents. Some take care of logging, and some others may take care of error handling. Middleware should be made according to the single responsibility principle. When processing the request. Middleware me right to the HTTP context object for generating the funnel HTTP response. Since all the middleware is linked together, we call the LinkedIn middleware. The middleware pipeline. Web developers are responsible to choose what middleware to use in order to solve their particular problems. And they're also responsible for configuring the chosen Middleware. Esp don't I? Core web server is actually a council application that runs in infinite loop while listening to your chosen port for HTTP requests. When the console application starts, the first thing it needs to do is to configure the middleware platform. Spi core instantiate the start-up plus automatically and calls the configure services method to import the middleware packages and their dependencies. And then it automatically calls to configure method for developers to configure the middleware in the middleware pipeline. It might be helpful for understanding the purpose of the two methods. If you imagine the configure services method contains the import statement in JavaScript. And configure method is where you use those JavaScript modules. But officially to configure services method is where developers do dependency injections in order to do blocking the services that the middleware will use for processing the HTTP requests. So you may ask, as an Core web developer, is it true that my job is to create middleware and configure them. Actually, most of the time your work within the framework of a certain sets of middleware. Because in ESPN, a core above the ASP.NET Core Platform, there are three different application frameworks. Mvc, either pages, and later. Each framework uses a set of middleware. When creating NBC web applications or web APIs. You work with modal classes, razor views and controller methods. When creating reasoner pages applications, you work with razor view and their corresponding code behind model clauses. When creating blazer applications, you work with blade or components, aka reader components. In the next lecture, Let's see how blazer application framework works while we are creating our first to place our application. 3. 1.2 How a Blazor App is Bootstrapped: Let's jump into we just do and create our first laser application. So thus, as registered to 2019, the version I have as Visual Studio Community Edition. And thus Edition is free for anyone to download. So I would suggest you to use the same. We're just do do. So first let's go to File menu and create a new project. And here, typing laser up. I have it already displayed here. Click on Next and then give it a name, my first laser, and then click on Create pleaser. It comes with two flavors. We have play, There's serve up, and we help laser lab assembly. They are very similar but works differently. In this course, I'm going to use laser server app. When you create a blazer application was played her server app, and it's not very difficult, come converted into play there WebAssembly or vice versa. During this course, I'm going to talk about the differences. But for now, let's choose play this eradication and select the default settings and click on Create. So let's quickly take a look at what we have in this project. We have a program file. Inside the file, we have this main method. So this looks like a console application. It's a little bit confusing. We wanted to create a web application, but why there is a main method for a console application. The thing is, every web application needs to have a web server. Laser is based on Core and ASP done a core as using council application to host Core platform. And then the core platform in turn hosts a blazer application framework. That's why we're seeing this main method. So when we deploy this blazer application on-prem or on Cloud, this console application runs as a web server and the web server host the Core platform. All right, let's see how it bootstrap the play's application. The starting point is the main method and the main Mr. creates the web server by calling the create host computer duck-billed, and then the web server costs the run method. The ROM method runs in a infinite loop and listens to the HTTP request and then process the request. The crate host builder method lows the startup class. By convention, the startup class has two main method and configure services and configure method to configure services and mainly for dependency injection. A injects all of the dependencies that the middleware uses. And we configured a middleware in the configure method. So let's take a look. And there to configure method, we are configuring a fetal middleware. Basically anywhere we say use, like Use, exception handler, use STS, use HTTP, redirection, use static files, use endpoints. All of these are middleware. The most important part is here. This is where we configure our laser middleware. And we are basically saying that map all request to this host page because blazer application framework as a single page application framework. That's why we are mapping all of the requests to this single page. 4. 1.3 Understanding Project Structure: Since the HTTP request is routed to the host file, this is the entry point of our blazer application. You can see that this uses a root component, which is the app component, and that is at the root folder. So let's take a look at this app component, which is the root component. Basically saying that we are running within this assembly, which is the assembly that this program.cs file belongs to. And it also says that this mainly out as the layout file. Once the Core Ross DHCP requests to the app component, the rudder component here takes care of the rest of the rotting task. It will look at the URL and was the request to our corresponding reader components. And if a finds the location of the user request, then it will display the main layout component. But if it cannot find it, it also displays the main layout, but with this error message. So sorry, there's nothing at this address. So let's go inside the main layout and see what it looks like. It is inside the shared folder. And as you can see, the main layout component uses the nav menu component and a body placeholder. All of our Razor components well be displayed within the body placeholder. This is the key here, and as you can see under the page folder, we have all these four razor components. And they will be all these played under the, under the body placeholder. And let's run our application with Control F5. And let's see what happens. So this is inside Visual Studio, the default laser template. It gives us a simple application, and not only has this Hello World application, and it also has a counter page and fetch data page as well. And it actually has some functionality here. If you go to the counter page, has a Click Me button, increase the count and fetch data, refers to data and display it in the very nice grid. So all of our future page components, well buddies play within the embodied place holder. We can actually change the layout. We can, for example, remove the nav menu and we can put whatever HMO here. But I want to emphasize here that the body is the key to body placeholder, although our future components will be displayed in the body placeholder. 5. 1.4 Adding Dynamic Content: The whole point of creating a loan application, web application framework like bleeder is to create dynamic content. So let's go ahead and create our first dynamic page. So if I go to Pages folder, right-click on it, and click on that, and click on new item and click on Reader component. Don't select them are either page because we're either page is so completely different application framework within the SBI core. Let's name this dynamic component of horizontal component can be dynamic component, but let's just name it as dynamic component. Click on that. In order for a component to be eroded by using the water component defined in the app component right here. We have to put a page directive, which is at page. And then we can say die. And that's bad. So when we run this, I'm doing Control F5. If we put slash dynamic, which is page tractive, riding past that we've put just now, going to hit Enter to see this dynamic component title is displayed, which is right here. Right? So to prove this, we can say our first component and then the goal here and refresh the page and we can see those. Now, what we wanna do is that we want to go to, we want to display a menu item right over here. For that. We want to go to our, we're mainly out. And then we see that the menu item is on the left-hand side sidebar. We go to our nav menu component. We can see all the links right here. I mean, in order to display that dynamic page that we've just created, we can just copy this. This is the past that we put in for an a page directive. So here we want to put that whatever pass that we give our page. And then this is the name of that. We're going to say dynamic page. And now if we refresh our page, we can see that it then I'm pages right here, so we can navigate to another page and then navigate back. We can see our dynamic page. So we go back to our nav menu component right here, which is the sidebar here. We can see this is what we did we use, we use this nav link component, which is a pre-built component and laser. And we'll use this to navigate to our page, right? So this is something we also need to remember is that whenever a in our laser application, we want to navigate to somewhere on the page, you can use the nav link component. Next, we want to add some dynamic contents on lower dynamic page because I, we're done and age is actually current, very much static. So what I wanna do is I want to add two buttons. According to which button you just clicked on. We want to display different contents on the page right here I want to add to library. And then I wanted to add the button, one button. And then the button says later server and then have another button later Web Assembly. So these are two elements that we're going to use. Next, I wanted to, I want to declare two variables. One is for the title that we want to display, the other that would want to display how we want to display it. He said after two another two line breaks, I want to display the title right here. I'm going to use header age three. The way I displayed is to use Razor syntax. So we put at sign here and put title. This is actually C Sharp code. Everything that has sign, it means it's a C Sharp code. And this is the region of syntax. So after this, I'll just play it another line brick. And then here I wanted to play a div. And inside of that, I want to also display the content. So how did we do that? Guess right, use coated. And then we aren't going to handle event handlers here. And event handlers. We don't want to just play, just use onclick because this is going to be JavaScript. So in order to use laser, it has to be ad. Click right in here. We can laser server over here. And again click and I'm going to say no laser SM click and then a squiggly lines, it's complaining about the letter is actually missing. So we're going to just declare a master right over here. And then you will see that right after that, there's frequently line is disappearing and just this care. So over here we're going to copy this name and put it over here. Also, the squiggly line will disappear. Disappear. So here, because we are clicking on the latest server button, we want to assign a title. We'll call it the laser server. And then content in the continent is this. And for handling the blazer WebAssembly button click, I'm just going to paste it over here. So basically the content is just saying what later server as play their WebAssembly. And I actually encourage you guys to read what I wrote here. Now we click on the Save button and we go to the, will go to the page and click on the Refresh button. Remember if you do Control F5, you'd actually kid, do Hot Reload. You just refresh and you don't have to recompile the gray now because I did not click on any of the buttons. So you don't see anything here because the title and Condon it too verbose or empty, having empty fields. So as soon as I click on later server, you can see play the server and when a name, and if you click on later web of somebody that's going to change the value of those two variables. Again, I can encourage you guys should read what I wrote to understand the differences between the two different flavor of the laser. But when I'm trying to demonstrate here is actually what I call the trial of displaying dynamic content on the UI, which I'm going to talk about in the next lecture. 6. 1.5 View, State and Events: And a component of any type of single-page applications. You have three different things. We have view, and the view is what? The user C. And then we have the date here, which holds the data that needs to be displayed in the view. And we have events here. This is when user into Western view and generous the events, events are handled and states get updated. On a stays, get updated. The view or song gets updated because the view displays data inside the state. So this is what I call the z component development in single-page applications, where laser publication it a single-page applications. So in this lesson, we're going to learn about the three different parts of component development. So let's look at our page component that we just created. So we have our view right here. These HTML markup represents the view of the component and these two variables, they represent the state of the component. And then these are event handlers. They're handling different kinds of events. We're displaying the data from the state to state variables is playing. And the event handlers mutate the state. And once the stays are mutated. Laser application framework automatically update the view. That's why you will see the page gets updated to when we click on different buttons. So these are the three main aspects of component development in laser. And all of our front-end development is around these three aspects. 7. 2.1-2 Screen Mockup and Components Breakdown: We have a lot of topics to cover. Or laser applications in order to fast-track are learning process, I wanted to start developing a small part of our application. We are creating a e-commerce website. And any e-commerce website should allow our users to browse our product catalogs. In this first part of our application, we want the user to be able to search our products in our broader product catalog page and be able to see the details of the product that the users are interested in. So we need to have two pages. One is the product catalog page that allows user to search for products. And the other one is the product detail page, display the details of the product. So let's get started was that the requirement is very clear. So let's actually start with a mock-up. So for the first page, which is the product catalog search page. So we have a page here. We're going to have the title here. Below the title. We're going to have our research box. Beside the search box, you know, have our button. And the button we're going to say search. And below, we're gonna have a list of products. One thing I want to emphasize for laser abutment. And this is actually true to any single-page application where all of the three things, the three main aspects, are within the same bow. We have covered the three main aspects, which are the state and the events. Because all three are in the same file. Then very quickly your file will became very big and hard for maintainers if you have worked with some other framework like Model-View-Controller or MVC, then you know that logo control actually separates into their friend aspects of UI development. The motto hold the states, and the view represents the view. The controllers are those event handlers. So all three things are in three different places. Whereas in our single-page application, all three things are in the same file. So you are going to see a foul become very messy very quickly. That's one of the reasons we want to make the component has three or small as possible. And that also follows the single responsibility principle of software development. So on this page, although it's pretty simple, That's actually break this down into components. So I choose your different color. So this is going to be our search component. This is going to be our product item component. So Elise, you're going to have two components on this page. Let's go to your studio and start over again. All of it. 8. 2.3 Analysis and Design: For this course, I'll loosely follow the clean architecture. And in clean architecture, we have two type of business logic. One is application business logic, the other is the domain business logic and the application, this is logic. Everything starts with use cases. For our search product page. We have search product and view product to use cases. And then in the view product page, Whoa, currently only have navigate back to search page because the user won't just on that page and look at the details of that product. So far we don't want to add any complicated business logic on this view product page. The only thing that a user can do is to navigate back to the search page. So we have two pages and three use cases. There is no domain business logic. The data will just flow from the data source to the reader cost-free objects and then flow into our application. This is logic objects. Let me clarify what I mean by data repository. A repository class is where I encapsulate all of the data access codes so that I don't have to write those codes in the application logic layer basically follows the facade pattern to hide the details of data access. So far we're not touching later yet because in clean architecture later will belong to the UI layer. We develop any applications. No matter what type of applications spatter to encapsulate the application business logic and domain business logic in a separate layer than the UI, so that we can have a nice separation of concerns in this first two pages that we're gonna, we're gonna develop. We don't have any domain business logic. So let's get started implementing the three different use cases under our application in business logic layer. 9. 2.4 Implementing Core Business Layer: Although we don't have any core business rules, we do have to implement the core business and monomers. In this case, we're dealing with products, so we had to create that. So let's go ahead and create that. Let's reuse the application that we created last time and we click on this and click on new and new product. And we're going to use this first one. The class library was done extender because we studied standard anywhere. And let's click on Next. Let's call it E sharp. So I'll run the kitchen name and let's call it a core business. Like I said, I'm a loosely coupled falling the clean architecture and I don't want to use like domain business because for anyone who does not know clean architecture very well, they may not know what domain business as. So with core business, people will immediately understand the core business class library contains those or business logic. And I just want to give you a very brief overview of what a core business logic is. There's logic exists Wes or without the existence of the applications, right? So it's those visits, people who follows the business coordinates and wolves to carry out the business every day. They didn't use pen and paper. They can use phone calls. They do not have to rely on any of the newer technology, let alone application that was computers, right? So the carbon is Rosh exist for the business. They don't actually depend on the indications, right? Whether without inexistence, application Department has rules and of course it'll be coordinates and rules. So we're going to create this layer to encapsulate that part of the business. In this case, for our search product catalog application, actually, we don't have any coordinate is rules right here. All we have our search and view and they all belong to the application business logic, right? The application business logic. Our business logic exist because of the medication. So because of the existence application, you are able to just search and you are able to view. So, so now let's define a core businesses, create a core business class library that contains, There's no business logic, but there is the domain model, which is the product. Let's delete this class before class, and let's create two folders. One is the mottos, the other as the services for. So the mottos contains the domain models and services photo. For now it would be empty because we don't have any core business logic. We will have a recurrent class. And I have in my clipboard and right over here the product ID, brand name, brand name price, and immensely. So we have this and the next, we're going to implement the use cases. 10. 2.5 Implementing Use Cases Layer: Okay, We have just implemented the product motto in our core business logic layer that we don't have any business logic. The reason why we implement the product model first, because the product motto is because our use cases depend on the model, the core business models. So let's create another class library to encapsulate the use cases. Again, we're going to use the class library data center and call it sharp cases. I don't want to call it application because the application is from the clean architecture, but I want to call them use cases. It's also from the clinical director. But I think using use cases is way better than you'd implication because everybody understand what use cases, even the businesspeople now they say it is, then we'll use cases is it's more intuitive, right? So as USE, use cases, remember then the application business logic, right? So this is the application because the logic layer where it has all of the business logging encapsulate the business logic that exist because of the application. Let's actually delete those as well. We have two user interfaces as call it search, product, screen, right? I don't want to call it page because these use cases acquire business class library can be used by any type of applications, although we're click creating a web application and then use case and corporate class library can be used by normal advocate or watch any other Internet of Things. So I want to call it a page. So let's call it a search for screen. And then we have another one, which is the view product, new product. And there are search products screen we have two use cases. I want to use one class for each use case, so that when we opened up the folder, we immediately know how many years their rate. Typically I use mediator from Jamie bulgur, but I don't want to. I want in order to simplify the teaching process, I want to use just a simple class so that I can focus on what I want to teach instead of spending too much time on other frameworks or patterns. So we'll have search and we're going to have renamed this product. The surf product will have just one method which execute and it will return a list of products to our product and then go have executed for searching and we'll have a few term for now will return null so we know it's not implemented. The product will add a dependency to the core because it makes sure that dependency points to the right direction. We're Use Cases point to the core business, and that's not a problem. So once we add that, we come over here and click press Control and click on this first results the dependency problem. Here. We also implement the same thing. Let's actually copy this method because they all have the same name which is executed. But in this case, returning just the product because we're looking at one product and then consult up and turn. So griddle the dependency problems. Right now we have the two methods. So where do we implement this? This actually due the day of the record comes from the data store wherever another disorder. So let's think about how we are going to implement the data store. 11. 2.6 Data Store Plugin Interface: Most tricky part of clean architecture, as in my own opinion, is the data stores and data stores, whether it's the database or a file system or whatever. It's easier to understand the dependency directions if you think that the use cases layer is the core, like one of the course. And the database or the data store is a plug-in. In order for the datastore layer to plug into the use cases, we need to define the interfaces inside use cases layer. Let's go ahead and create another folder. And let's call it plugging into her basis. We're going to create another sub folder and we'll call it there. We're going to quit a bunch of interfaces, period. So we're going to create our first in your face or the Datastore. And that's going to be product. So it's going to be a basis. Let's call it product. Now going to implement a generic problem repository, because I don't think that's necessary. I just wanted to have a very straightforward implementation. So this, so changes to public. What we're going to have insight here is search product. And we're going to have get product will have a new product. Let's call it got products and control dot to use the model. Another one, we'll have got product with a filter, but we're now going to implement the plugin interfaces within the use cases layer. We would need to do that within the plugin layer. Here we have used implemented in our plenty interfaces ray, now we can go ahead and implement this search product and your product with the help of dependency injection for DAT, we come over here and create our panacea injection in the structured constructor. So we do see tore have two tabs and we are going to pass in the AI product deposits. And the following year. And now we do control dot. And we're gonna say creating new initialization field. So we created this automatically. And right here, use the product. I propose three, because this is the list. So we've got product passing the filter. And because this one returns, I rebel is exactly the same type. Because there's no, just no core business logic. Go straight from the Datastore into the UI. It just passing to the application and business logic, right? So this is a big issue, business logic again, and we're going to come into view product. We're gonna do our dependency injection, see tore, tap, tap. We're going to put this product costs three right here and do the same type of stuff and create a regular physician. And then come over here and say return. True dot-product got a product. Whereas here we've got our wrong thing. Fix this and the ID for this simple advocation for this exercise preppers, we actually completely created the use cases and a quarter visitors, which is the core inside the clean architecture. So at this point, without implementing the database implementation or the plugin interfaces, we are, we're already able to do our testing. Although I'm not going to do our testing, We're not going to create test cases. But I want you to understand that we have the ability to potassium and when we are doing our testing, we can lock the repository interface. And that is the power of this plug-in based cleaner architecture. So our core of the application, which is the use cases and requirements layers. They don't depend on the database. 12. 2.7 Implement In-Memory Data Store Plugin: Now let's go ahead and implement our data store. It is very important to understand that database for datastores are IO devices. Any IO devices should be implemented as plugins. I want to add a description field here. I forgot it at that. So we go to our E sharp core business and go to under models folder. So we add the description to the product Moodle. Once we've done that, we need to implement a lamentation of the plugging, the restore plug-in interface, which is the AI product to parse tree that has two method. And we are going to copy this into our clipboard. And then we go ahead and click, Go ahead and add a new project. And that's again, is going to be done a standard class library. Click on Next and Min and say shop dot data store. And for this exercise I'm going to provide hard-coded data. So I'm going to just say hard-coded, Uncle Bob's at a good architecture is architecture allow you to delaying making decisions. So instead of implementing a real data store of any kind that's make a hard-coded into the store. And the later we are going to implement a real data store that pulling data from a database or some kind of web surveys. So for now, let's implement a hard-coded data store where we are going to delete this and then change this because we, we have the interface in our clipboard. I'll just paste it over here and then it's going to change this. And we are going to be a dependency project to project reference. And I'm going to France the use cases class library because it contains the plug-in interface. So I click on that and then go over here to control dot and then hit Enter to import the using namespace. And we're going to implement this and also implementing this as well. And I added a optional parameter just so that if the filter is not guaranteed, then we, we don't have to filter the product. So this one should implement the AI product repository repository interface. And then we are also doing control dot to implement to import the interfaces namespace. Let's change the class name, the file name to also product repository and import the generic collection namespace as well. And now what we need to do is we need to have, we need to initialize the data. So because we're going to hard code it, it's so little initialized data in the constructor. So I did see tore tap, tap. So I have the product repository constructor and I'm going to declare a private variable, product, and it's going to be a list of product. I'm going to initialize this over here and I have my clipboard and you will have in the GitHub repo straight. So I have all these products where I found that there somewhere online. I'm going to provide that link to the JSON file I found online as well. It's complaining that it does not implement the interface. So let's go ahead and delete this and then control. When say implement interface. Now it's up to complain. I think there's something wrong with the intelligence. Okay, So here we are going to get the product by ID, or we're just going to say no products. The first or default, I'm going to use link and then say x dot ID. Because ID something returned us while we're here. Again, we're going to use, we're going to use ID. So we're gonna say products where x dot name. So this one is a little bit, we need to add some conditions. So if string is null or empty space, so if the filter has nothing in it, we're just going to return the product. Otherwise, we are going to say, in order to make a case insensitive, I'm going to do to lower and contains filter to lower as well. So that's how our implementation was, the hard-coded data. 13. 2.8 Create Search Products Component: So now that we have our core business, use cases in Datastore layers implemented, let's go ahead and actually test the implementation. Alright, so we need to connect our laser application was the use cases. When we want to connect that, we have a dependency from our glaze application to the class in the use cases. And the way to implement that dependency injection is to go to a startup CSS file in the configuration configuration services method, we need to add our dependencies. You see we need to use the classes in the use cases, but our use cases, they don't have interfaces for dependency injection. We need to implement interfaces. So let's actually implement interfaces for each one of these use cases. Okay, I created these two interfaces. Now we can add the dependencies. And if we look at our search search product, we can see that structure. We also add the dependency to the data store plugging interfaces. So this data store plugging interfaces also needs to be registered in our dependency injection place. So let's go to the startup.js and then let's add our dependencies here. So we can add them as transient, which means that every time you require the class is going to be created. So a new instance will be created every time. So we rely on the product, okay, so before we do that, actually we need to add the dependencies. So you can go to Add Product dependencies are actually all of them, say product repository and implementation of this is product repository. And I said basically what it does is whenever we need to have implementation, this interface is going to create an instance of this class. And the same thing is going to be done to the use cases where we have search product, the search product use case. And then we also have our view product use case, right? So now that we've done that, let's go to, go ahead and create a new page, and let's call it search product, new item, razor component. And let's call this search products. And this is going to be a page component, means that you need to rot to the component. And this component is going to be used as a page. So we're going to say Add Page and then say slash product. And remember that a component has three parts. The view, the state, and the events. Let's quickly have our use-case class libraries by writing a one of the lifecycle events mixtures overwrite only neutralize, so then they will stop complaining. And now we need to do is to inject our use case insight here. So in a set, inject, say I search product, and then you can see that it's actually pulling all of the namespace here. So in order to do it without namespace, you can go to imports in blazer. This is where we import all of the namespace. And once we import here, we can use the any components within the project. We don't have to explicitly import a namespace. So as you can see, the squiggly line is gone. So here we can say search product, and then we can get over here and you can say search product dot cubed, and then we can provide a filter. In this case, I'm going to provide nothing and to return a list of products. And when I'm going to do is I'm going to run this, run this project right now and set a breakpoint here. I need to make sure that everything is returned right. There's an oral compilation errors just manually typing the URL and then hit Enter. So let's go to our breakpoint and let's see whether press on f tan, whether there's an error, just no arrows. And let's check our products. We have 20 product. So and that's exactly what we are expecting. We cry, so it's working. 14. 2.9 Implement the Search Products Screen: Now that we know that our use-cases working in the data is properly returned. Data store plugin is also working. Now let's go ahead and implement our homepage component. As we mentioned before, we have three different parts. Within a liger component. We have, we have state and have events. So let's go ahead and implement a very simple view to see our data. So we are going to have an ordered list and then we are going to have a list of, but we need to have a list item. So we need to loop through all of the products. So let's first have a statement. So we're going to have a private eye in your herbal product. Product is from a different space for it over here. And then we go save it and go back and just saying in and say products. So here we're going to remove the product. And so now we have our state. And we also, actually this is a life-cycle event. So we have our first event and we have our state. We just need to implement our view. So let's implement a simple view just to test our component phase. So let's have a unordered list and we need to have a list of list items in here. And for that, we're going to use reader syntax. Remember we say the assigned means. We're going to write C-sharp colon, C sharp. C sharp. We have for each, for each product. Within products, we need to output the list item. So let's just have the name of the product. And again, we need to use it as psi here. And let's go ahead and test that. Let's do Control F5 without the banjo. Now let's go to our page. And very good, we see a list of our products. So now let's add the search product page into the navigation menu so that we don't have to manually type in the URL. So let's go to our shared folder and then go to the navigation menu. And in here, we're going to remove, we're going to reuse this dynamic page because it's not needed anymore. The PaaS here is product because if we go to opera product component, this is the product, this corresponds to this. So here we put products here and then I'm going to say, go back to here. We are going to remove this. So that's good. And now let's continue implementing our view. Let's add a line break here. And here we're going to have our search box. We're going to have a glioma just like this. And I'm going to have a div and say search. And within here we're going to say input, type is text. We're going to put a button over here. And it's going to be search. And let's refresh the page. It doesn't have any functionality, but let's refresh the page and see whether it looks okay or not. Okay, that doesn't look too bad. Let's add a line break between the search box and the list. I remember at the beginning we said that we're going to create a separate component vertice. So let's actually go ahead and do that in the next lesson. 15. 2.10 Implement the Search Bar Component: Now let's extract the search bar to a different component. And again, the reason why we want to do this is because we have all three things to view. The state and the events are within the same file comparing with something like MVC, the A3 things are separate. This is going to get messy very quickly. So we need to break down a page into different reusable components as small as possible. So let's go ahead and implement this search box. So who knows that in the future if we need to search something else and we can reuse this search bar Solution folder and see you how the pages. So since we have pages, Let's use controls as a terminology. So we have controls which contains the reusable components right over here. We're going to create our new razor component. Let's call it search bar. And it's going to have no title. And we can copy this into our search bar component SW. And what we need to implement is that you vent because when the user click on the Search button, we need to filter product catalog. For that, we need to do a sign. Again, this is going to be C Sharp code, so that's why we use as psi. So as onclick. And then we're going to say search window, say a 100 000 search, right? And then we go to our code block where we read our C sharp logic, C Sharp code here. So here we're going to say it's going to be a private function, so we use private void and no search. So we have this event. Also. We need the data come from the input box. So for that, we also need to employ in the state, which is going to be a string. And we are going to say filter, right? So how do we bind the filter to the input box? And this is where the data binding come into play. Here. It's actually pretty easy we're gonna do at. And then I'm going to say bind value. And we can put a filter directly in here. We don't have to say at sign anymore because we already have SII here. So in order to test the data binding, well we can do is below here, we're going to put our filter directly into view. So, and then let's, without doing any, implement any functionality, let's use this component. So in order to use component, we also need to import a namespace because this is under the control folder. So we need to go to our imports and we need to import the using my first blazer app dot controls. So that's good enough. And let's go back to our search proto component, where we can hear just say, search bar component that's at gone, That's refresh our screen and see whether everything works, right, so we still have to search bar. And because we implemented the Data binding here, and we also put the filter directly on the search bar. Let's see if we type what happens. Nothing happens, right? So what if we, what if we tap out? Now we can see, so it's automatically bond to the filter. So it's automated bound to the footer, and that's good. And you also notice if you put in some other things here and then click on the Search button, you automatically receives a food or as well. So that's good enough. And let's go ahead and go back to the search bar component, implement the rest of the library. So what happens is that when user click on the Search button, this handle search event handler is called. This action needs to be passed to the parent component, which is to search products and potent because search product component needs to use this action to trigger the filtering. So when the user click on the Search button, the handle search event handler is called. And that that moment we need to pass the filter to the parent component, which is a search product component. Because the search product products component need to know what the filter is so that it can use that to filter the product catalog. So in order to do that, we need to declare a public property here. It's not just any public property, It's something called event call back. And the event callback has a generic type. And this generic type specified the type of variable that you need to pass to the parent component. So a event callback is a way to pass information from a child component to the parent components, right? Because I researched bar component is a child component that is used inside the parent component, which is the search products component. When we want to pass information from our child component, from the search bar component to the search products component. This is where we want to use event callback and the type of information that we need to pass it. It's going to be a string because we want to pass the filter here we can say search, and this has to be prime minister. When we say parameter here, then we can use it right over in the parent component. We can use it as a kind of an attribute of this element. Or you can sit, you can see that on the searches right here, right? So here, then what you need to do is to specify a method that handles this. So again, say handle search and then go down here. We can say private, void and no search, but it needs to accept a parameter with the same type that we declared over here. So it's a string. So it needs to be a string here. And what's passed in is actually the filter. Then we go back to our search bar component and we want to invoke this and even call back parameter is as different from a delegate in C-Sharp. So it's different because we don't need to attack whether it's normal or not. We can just call it directly. So we can just invoke it. And we can pass in the filter directly because the filter is already been to the input, and that's good enough. And let's give it a test by putting a break point right over here. And then let's run the application queue. Let's click on Search Products and going over here. And then we put in something like and click on Search. Now it's triggered. And then we hover the mouse over here, we can see fit. So our search bar component is working. 16. 2.11 Implement Product Item Component: Next, let's re-implement this products list. So instead of using a simple and ordered list, Let's go ahead and use a table. So let's use table. And then we're going to have an, if we go to our core business and look at our model, we have brand name, name, price, and image link. So we are not going to display the image in the table. Uh, we're not going to display the description. We're going to display brand, name and price. Okay, so we are going to go over here and he had, and now we can say TR known as a th. So what we have, what we need is a name and Brent price. And then over here, we'll have t body. For that. We also need a list of TR. Instead of putting the TR riding here and do the loop here, we want to extract this also as a component and the reason the same, right? We need to make the component as small as part. Because reason why we want to implement this as a component is later when we want to implement like added or delete those functionalities. Those functionalities don't need to show up in this parent component. All right, so let's go ahead and add another control. That's colored product item component, then we don't need the title. And right here we need to have a TR because this product item component actually we can do this right now. Instead of having anything else within a loop through the same thing as the lowest, we're going to loop through the product, right? In products, and what we need to do is we need to use the product item component inside here. We need to provide the current product to it. So let's go and go back to the product item component and let's implement it. So it's going to be a TR in the view. And then we have three different TD. But before but, but what is the, what is going to be the state? First of all, we need to implement this state and that's an unknown. The private is going to be a public property and it's going to be a product. Let's just call it product. Okay? And this is not enough. If we have this, we go back. Let's see. So inside here we can not see the attribute. There's no product attribute. So in order to pass the information, we have to declare this as a parameter news. Because attribute to Parameter attribute declares this product property as a parameter. So then we can use a parameter to passing the current product. Once we have that, we go back to over here. So and then we have the data. We are going to display the data over the side here, and we're going to use the Razor syntax. So we have product, dot name. We can do to string and we're going to do currency. So there's a possibility that the product can be no. And we start is going to throw exception, is going to throw the null reference exception. So to avoid that, we need to again use rid their syntax. I'm going to say if this dot product is not know, then we display this in the view. And let's go back. We have this already here. We are going to also add a condition. We're going to say if products is our state, if product is not. Now, we are displaying a list of product Adam component. Otherwise, we're going to display a message. And for that, we need to have a TR and a TD with column spent three. And we're going to say, and not find products. And let's see whether this works or not because we're not filtering and his students blame the BBC here. Next, let's go ahead and implement the actual filtering. 17. 2.12 Implement Filtering: Okay, let's go out and implement the filtering functionality. So let's go back to our search product component only receive the handle search. So this handle search is trigger when Search button is clicked, it's triggered by the event callback. So let's implement this. So we already have the search product surveys here, right? So let's do that. And then we have the execute method and xy plus or actually can accept a filter right away. Okay, So now we can just end. That should just work and see what happens. And that's the refresh the page. So remember the filter as the name. So let's see. We have a whole bunch of fit, right? So let's do fit and click on the Search button. It's working. And we have normal. And then we have browser, the Dorians working. Let's remove this thing where we tested the data binding, right? So let's go to our search bar component and remove this from here. And we also need to test what if we put in something that doesn't exist, all right, so name, product, price, okay, so it's not that clean our message, so let's fix that. The reason why that's an odd display, it's because we go to our search product component. The reason why isn't on discriminates because the product is, is not, no, it's actually empty a list. So we also need to check the count has to be greater than 0. And let's see if we refresh our page, what happened? Okay, page load it. Let's put in something that doesn't exist. Still, no display shown as a complaining. Okay. Okay. Let's go back and refresh the page has again, I can now find products. Alright, so we implemented our filtering functionality. 18. 2.13 Styling with BootStrap: So before I go ahead and implement the view product page, let's implement some style. So thou are we're search product page looks better. So we have this search bar, we want to style this first, and we have our Bootstrap already included in the default complete. Let's take a look at the Bootstrap documentation. So in here we're just typing Bootstrap, bootstrap website and click on documentation. Here's the version and we got to the latest. And we are going to look at because our page, we have an input box, we have searched by them. It's a title form, go to component, go to Forms. Then we'll see things like, you know, we have input box and then buttons, right? So we need to find something, some exemple with it hires horizontal layout, write things like this, and then we set by them. So this is a very good example. So let's copy, lets actually copy this and then go to our code and we just put it over here. And we don't need this e-mail thing here. So we only need this. It's not going to be whatever here. So I'm going to remove this. And this is going to be search. And we're going to pull it space here. This is now going to be password. This is going to be our text. Actually, let's copy this over here. We have this control, and let's also give it an ID, and let's call it Filter. And this is going to be polo, corresponds to the filter. Input. Will have no placeholder. This button will change this text to search, actually, yeah, Okay, then click search. So that said, let's remove this. I don't want this button to be a submit button, so just implement ISO button. Glad to refresh our page and see if that works. Alright, so next let's style the table. Again. Let's go to here and let's see. So that's should be and their contents. And we have tables, yes, we have tables. So let's just use table. So good. Our research product page here, we just say class equals table and let's refresh. All right, very good. So it looks much better. And if we put in something, we're filtering. And if we put something doesn't exist, then yeah, looks much better. 19. 2.14 View Product Details Component: Now let's implement our new product page for diet. We need to create another page component and their pages folder. Again, we're going to choose the reader component and I'm gonna say new product. All right, so we have our view product component created. And let's change the name to be product details because this is a page components. So the first thing we need to do is to provide a PaaS. And that's going to be product. We will navigate to the POS, providing an ID, right? So it's going to be like this. So this basically says that if the URL measures this pattern, products slash and ID, then we are going to display this, use this component and we can provide a constraint. We're saying that the ID has to be an integer. And in order to get the ID, all we need to do is to provide a property here and with the same type integer, and then we can call it ID. It's not case sensitive. And also we also need to have to decorate. Ted was the parameter, and so this is what we call a rod parameter. It means that the value of the parameter passing from URL when the user navigate to this page with ID to this ID will be available from this parameter. So now let's implement the state which hosts the actual product where we need to do is there is a as override another C This on-premise or set this as a one of the life-cycle event in blood or component. And this is called when the parameter is changed or when the user never get to this page, then this parameter is given the valley. And when this parameter is given a value, this parameter set is called. So this is a perfect place where we are sure that the perimeter will have a valid. So this is the place we can call a reuse case layer to get the corresponding product. Let's inject our view product service. And then here we can say product execute. And we need to provide the ID just to be safe. We can say if ID greater than 0, then the product is good enough. So we have the state and we have the event. And now we need to handle the wind to implement a view. For that. I have a something in my clipboard. So I'm just going to copy and paste that. It's a very simple with us telling. So we are going to display our image. So instead of, it's going to change all of them to lowercase product. We have our image displayed here, and then we have the name of the product we're displaying. The brand would just mean the press and we're just playing description. And then we're going to go back to our product item component. And this is where the item of the component gets repeated, repeatedly displayed in the search product component. And what we want is we want to click on the name of the component and navigate to the product detail component, w product component. And remember, I mentioned that. In order to navigate, we have navigation link component. Let's go ahead and go to our product item component. Then wrap this name around or was the navigation link component. So if we go back to the navigation menu, we can see that we wanted these play in here and then the graph or H ref, we need to specify the path of that component. So here brings an H ref and then the password that component, which is going to be the purview product. So it's going to be products slash the ID. So that's going to be no product here we need to use actually a resource in texts to, to get the string. And for that, we're going to do as site and then apprentices. So within here we can write expression. And that's going to be select this, I'm gonna say product slash. And within the interpolation, we can write the ID of the product. So it's going to be ID, so we don't have to write the add sign here. Okay, Let's refresh pages, load it as you can see, the name and the name is displayed as a link. And you can see when we hover the mouse over the link at the bottom left corner, we can see the link as it's correctly rendered, right? So let's see, let's take a look at the second product. And we have a product image displayed, and we have the name of that bread, the pricing and the description information, which is really good. And we go back and look in the second play. Again, this one. Again, all of the information is displayed and let's spell it a little bit. That looks much better. Great. Let's again go to our documentation for Bootstrap and let's see whether we can find a container. So again, go and their components and let's find a container that we can use. And I think card could be a good one. So if you read the description card, provide a flexible and extensible content container with multiple variants and options. So let's see. So we have card title here, okay, We have subtitles, so that's pretty good. So we can use subtitle for the and then we have the description here. That's actually pretty good. So this card text. So let's actually copy this code. Our component, go to the View product component to product name here. And then we're going to have our president as the subtitle and the description and go right here. And we have our links. Don't want to have a separators right here. So it is playing a separator. And then we say, price, the price right Here. Let's actually use the bowl. Let's use inline style here to make it red. Actually, let's use dark red. After that, the price should go below. We have our image. So let's see how it looks like. If we put this image, just allow the name and it doesn't look good, we can fix that. Okay, That's not too bad. I want it to be a little bit wider. So let's go ahead and fix this to be 28. Right? So that's go to our research component and try something else. So last thing we need to implement is to allow user to click a button to go back to the search product page. For that. We don't have a use case for that because it's a pure UI behavior. We can just implement a simple link in the real product component. We can just implement that Mariah to be low this. So we're going to have a navigation link, products back to products or so. So we can see the back two products here. And that's works, that works pretty well. Let's test our filtering and functionality. Still works. Go here and back to products. Show we adding a line break here. Refresh. Okay. 20. 2.15 Summary of Section 2: This is the end of Section 2. We have implemented our research product page and we implemented a few Tori. Everything works perfectly. And we implemented product details page as well. We are able to navigate back to the search product page. So we have covered a little bit about project work was blades their components. In the next section we're gonna go to each feature of our blazer component, aka razor component. And we're going to cover each feature in death. So I'll see you in the next section. 21. 3.1 Data Binding #1: When it comes to single-page application, the first thing that is very important is data binding. So let's go ahead and learn about data binding in this lesson. So let's continue using Harvard. So Shinto we use last time, let's use the index page to do some data mining. So data mining, we have to first, of course, create our code block, which is going to declare our state to a state variable. So let's use one of our product exam hope. So let's initialize this. So there's something that is called one-way. So one thing they have is basically going from the state one way into the view. So for example, if we display the product, product name like this, then this is one we didn't have any because the value we're now flow from the view back to the state. So this is one way he went when we have a input component. If we say product, I mean, if we refresh this, you can go to our homepage. We said the index. We can see that. Let's add a line break here and refresh it. So we can see this displace the state, okay, The name of the product. And if you type in here, nothing is changing the product name above it. It's not changing both of the HTML element, a bond to the product variable, which is the state. So data flows from the state to the view, but that doesn't flow back. This is one way. And when did a flow from the real back to the state, and that's called two-way. So in blazer, in order to do two-way data binding, we just need to do, instead of using a value, we can just say that bind value rather dot. So this will be two-way data binding. So if we believe this and how about, you can see that the data is cleared because it float back. So if I put the ABC and tab away, then flow back to the state and from the state flow to the label. So this one is already a two-way data binding this input box. Another thing we can do is we can find value and we can add event. And here we can say that, for example, we will be saved on input. That means while they're typing that data is written back to the state. As you can see. So this two-way data binding. Next, let's cover a checkbox that's declare another variable and it's going to be a Boolean and let's call it active. So let's, let's initialize as false. And here we add a line break. Then we're gonna say input text box, I'm going to say bind to bind value two is active, active, so that it looks better. So runaways label here and you can add ESP, add a space here. So let's go ahead and refresh the page and see what happens. And over here, we actually want to display is active the value of that. And this refresh the page. As you can see, the original value is false. And if we check this, it will become true, right? So it's doing two-way data binding. So next let's talk about radio buttons. Radio buttons. There isn't an easy way to him laser to bind redo buttons to variable. Unfortunately, we have to do manually. So that's actually chemistry that. Again, we're going to have a label. We're going to wrap that around a radio button, so it's going to be radio. And then let's have this one hand. We have numerous group. We are going to create a to another one of these name and it says one, have another one changed this tube. And this value also is going to be, they belong to the same group. So the name is going to be the same. It's going to be the same type of radio button. Here. I'm going to declare a variable. And that's going to be an integer, and I'm gonna say so. And there isn't an automatic radio button data binding here, but we can use onclick event. All right, and again we can use the SI apprentices. So within here you can write any typeof see trap expression. I'm going to use arrow functions like this. So this is going to be a function and this is going to be called when the clicker triggered. So I'm going to call as a selected group of equals 1. I'm going to assign one to the selected group of very obviously here I'm going to copy this over and change this to two. And then I'm going to display the variable, this variable right here. And let's refresh and see. Look at the page. 22. 3.2 Data Binding #2: As we can see, that initial value is 0 and we click on one and become 2, 1, and I'll click on to become too. So this is how we manually buying state variable to read about. In the next, let's look at data mining for drop-down list. For that, we need to have a list of products. And I'm just going to paste this visualization like this over here. Okay, So that data initialized in the view area, create a drop-down list. And that's going to be select element. Within the select element we're going to have for each product loops through that, just like what we did to FOR loop through the products. And then we're gonna put option within it. And the value of that is going to be the product with their syntax product ID. And then here we're going to use the product name. We need to add another option above this. Show that this is going to be the inner shadow option, which we're going to set it to 0. And the initial value is going to be, the initial display is going to be empty. So the user know that they need to make a selection. In order to know which one we select, we can declare another variable, another state. And we're gonna say this is the selected product. We're going to say 0 at the beginning, and here we bind it to the selected product. Actually, let's add the ID, selector product ID. We are going to add a line break here and where it is playing for the selected product ID is. And we can see we have 495488477. And let's go ahead and refresh the screen. As we can see, we have this dropdown list and it's split displays the initial selected product ID as 0. We're showing all of the three of them. And then if we change, we can see that it binds back to the selected product ID state variable. So with this drop-down list example, we can see that this state variable products is bound to the view one way. And then the view bind back to the selected product ID, like a broad ideas. Then one way to the view again here. So that's the, I know that data binding lesson. And we have also have already seen some of the data by name in the previous section when we develop that first part of our application. So if you don't remember how these things were done, please go back and review those lessons. 23. 3.3 Overview of Communication Between Components: Laser development is component-based, as you have seen in the previous lessons. For example, if we go to our search products component. So this as a page component that has a page directive and a rod that user can navigate to. Another type of component is, for example, this product item component, right? So these are none page component that don't have the page directive and you cannot grow out directly to this component. So this is called NumPy, which component or we can call it reusable components. Usually a page component would contain one or many reusable component or none page components. And an unpatched component contains other non pitch component. And all of the components need to be able to communicate with each other. So, for example, you would have page one, page two, page three page in each page may have subcomponents and those components are none page components. For example, this page 1 has two subcomponents and page 2 does not have any sub-components. And page 3 is even more complicated and has a component tree like this. Page m may have something like that. So now when we have a complicated structure like that, what needs to happen is a communication between these components and the communications between the page components. This kind of communication are done by passing rotting prime and the communications between parents and child. This is done by regular prime rotting parameters, rotting parameters, and this is also rotting parameters, but these ones are regular prime. So this is also, and this is also right. So these are regular parameters. So we have rotting parameters and we have regular parameters. And the third type of parameters are cascading value parameters. So in that case, we have a deeper tree structure like page 3. And sometimes we want to pass the value down from the parent, from the page components all the way to the leaf, right? All the way to all of the head. We can do that by using the regular parameters, but all of that can be done. But laser has a better way to do that and it's called cascading parameters. I'm not sure whether I'm spelling correctly or no. So another type of communication is when the children are trying to tell the parents about something. Some interesting that happens, right? For example, your child calls you from the university about something and you would have to react to it. So that kind of is called event callback, that kind of communication. This is event callback. These blue ones are event callbacks. And another type of communication is when you want to tell your child about something, right? When you call your child about something happened, something interesting happened. And you ask your child to do something. And that kind of communication is when the parents cause the child. This type of thing. We reference, we reference the child component. And then we can call a method on that child component directly. 24. 3.4 Review Parameters, Route Parameters and EventCallback: In the previous section, when we were developing the application partially, we have already covered regular parameters, rotting parameters, and event callback in our previous section. Let's quickly review them and then we're going to cover the rest of the way of communication with the rest of the things that we didn't cover yet are cascading parameters and referencing child components. So we have use regular parameter like this to pass a product from the search product page into the product item component. So we have this products here and we'll loop through them. We have the current product or pasta to the product item component. And then the product at a component can be repeatedly re-entered. And within each product component, you will have this product populated from outside, provided from outside. So this is regular parameters that you can pass data from the parent component into the child component. Another type of parameter is the rod prime UTR, which we also demonstrated was the simple application that we developed in the previous section, which is the view product component. This is a page component that has a page directive. And you can see from the rod, we have a parameter here. And this ID corresponds to this parameter. Right here. It's a parameter and it's a special type of parameter that comes from the rot or I'm here. So this is what we call the what parameter. And Robin prime UTR can have constraint, integer count the baleen, and you can search Microsoft documentation to have a list of all these possible constraints. So this is rock parameters. With wrapped parameters, you can pass information between different page components, right? Instead of between the parent and child components, pass information between different pages. So that's rot, rotting parameters. And we also demonstrated the event callback was the search bar component. Search bar component, we have this button. When the button is clicked, this handle search event handler is called and then we declared a, again, it's also a type of parameter, but it's a special type of parameter that is an event callback. And this is the string that we want to pass to the parent component. We just invoke this callback in the event handler. And then from the parent component where we use the search bar. So this is the event callback. You can see this is the event callback, and then we just need to handle the event callback. So this is a way to pass information from the child component back to the parent component. And once this is triggered, the parent component is automatically re-rendered. 25. 3.5 Cascading Parameters: Let's talk about cascading parameter. If we have a component tree like this, where I have the page component that contains several levels of components. These components make the tree a little bit complicated. So in this case, if we want to pass a parameter value from the first level, from the page level down to the leaf, we want to use the regular parameter. We have the passive parameters as many times as the number of levels that a component tree has. So one way that Microsoft has came up with to solve this problem is they created something that is caught. Getting parameter is something that you can use to cascade a value from whichever level downward to the lower level components. You don't have to casket one-by-one. Okay, Let's jump to the computer and see how it's implemented. Since blazer template, it comes from Microsoft. And we go to the contact page and see when we click on it, the current column increases. So we're going to modify this to mimic a scenario where we have many levels opponents. We're going to create another two level. So altogether we have three levels. So this is the Counter component 38 that's created two more components. Let's call it component one. Component two. And in order to distinguish them, I'm going to add some CSS cell. So we're going to add some margin to component one. And I'm going to add another margin to component too, which will cause an indentation. They were considered different levels. So with this, we are, instead of displaying the current caught inside the counter component, we are going to remove this. And we are going to display the counter con in the component number 2. But before we do that, we are going to add the components in component 1. And then within component 1, we add component to component one contains component 2 and columnar component contains components one, right? So if we refresh our page, right, so we're gonna see component, one component to let this was the margin indicating the different levels of components. Now, I want to display the counter value inside component to how do we do that. We need to wrap our components with a cascading value element. And we're going to tell the calculator this value is called counter. And value itself comes from the current count. And we wrap this component one with it. So current account is here. So what happens is that when we click on a button, it caused this event handler and increases the current. And this current count is passed into the component tree. No matter how many levels of tree has, you can access this count value from within the component. Let's say you want to access from component to, you can actually access from Component one or Component to work both, right, so in this video, let's directly go to component two, and we're trying to display the count here, right? So let's say, oh, the count. The count is to counterbalance. And to do that, we need to declare a parameter, and that is the same type and the name can be any name. Let's call it counter value. But the, we have to decorated with this cascading parameter. The taller name of this customer parameter is Connor, right? That's the same name that would give it here, right? You can name your cascading parameter in with anything as long as you declare that the in the attribute part that you make sure that this Condor Bowden name is the same with the name that you declared inside the cascading value element. So now with this setup, you would be able to read this counter value directly from the contra component, that parent component, the ancestral component, it will contain this value. So let's see whether we get it. So in the display, this value right here on her value. And then we're gonna come back and refresh our page. Right? So now shows counterbalance 0. And we can increase. When we increase this, it goes up. Okay, So we have successfully passed down the counter value. So this helps us a lot when we want to pass values around and pulling tree. It's very convenient. But we have to know that we can only get the value from the top to the bottom, from the top to the leaf. We can never cut K the value backward. Another thing that we need to know that cascading parameters, if we implement a very big component tree, then using cascading values actually makes all of the components monitor the change of the cascading value. And that will actually affect the performance. 26. 3.6 Referencing Child Componnent: Another way to communicate between components is to reference our child components from the parent component. So once we have the reference to the component, we can call the methods or access the properties of that component with that refers. Well, let's demonstrate that. So let's create a new component. There's a component, and let's call it the component and the US that visibility component directly. We're index components. Scroll down to the bottom right over here we can say its ability, ability component Over the visibility component. So what we want to do within the visibility component is we are going to actually create a state and our state will be valine. We're going to call it as a bowl. And originally we're going to set it as true. And then we're going to create a public method. So it's called nullity and more when I'm passing the value. And here we are going to set star is visible value. And what we can do is to use reader syntax will say add, if it's a solid again is a C-sharp. When he said that start as visible. So if this is visible, I'm going to display the title of this component. Otherwise, I'm not going to display it. So because the initial value is true, so we're displaying it. So going back to the index component, if we run this, we're not going to debug. So we're going to do Control F5. As you can see that we have the visibility component displayed right now, right? So let's go ahead, let's go back and implement our VR setting here. So in here underneath, Let's have a line break, and then I'm going to have a button. And this button, we are going to call it toggle that nullity. And then I'm going to implement this, sorry, click. And I'm going to call the toggle and insert here. I'm gonna say void Togo. And how do we toggle the visibility? When is our top component, right? So that's when we need to use the RREF. See this href attribute, we can say and give it a name, right? So Ballet, velocity component like this. And then that's not enough. We have to say private, the ability component with ability component. So this is, this is the same as this. So we start variable, the private variable declared like that. We can use it. We can say this stuff visibility component. And then notice that we can access the SAT visibility method. And in here, actually let's change our method. Instead of passing the value into it, we need to actually toggle it, right? So visibility equals the visibility like this. This will toggle the visibility, right? So going back to our parent component and verify that we're calling this. So and then there's toggle method is being called unclick. So that's it. And let's go back to our page and refresh. Okay, so we have this displayed and if we click on this toggle visibility and nothing is happening. What is going on? Let's take a look. I don't see any problems. I think I think I know what's going on. So because we are triggering event handler. So this event handler is in the parent component, but we need to refresh the child component. In later, we're going to talk about lifecycle events and pages rendering. But right now I can tell you that the rendering is only triggered when. So when you have an event handler, the component is going to be re-rendered, but it's going to only re-render when a event handler is triggered within the same component. So right now we're actually triggering the toggle event handler from the parent component, but we're expecting the child component to refresh and that's not going to happen. So in order to do that, well, how to manage trigger the re-rendering. So what we have to say here is we have to tell the child component that the state has changed. So there is a method that we can use. So this is part of the blazer application framework. So with this change, let's look at the page to see whether it's fixed the problem. Okay, so let's click on Toggle visibility. Now it's gone, and then again it's back. Okay, So this is how you reference your towel component and use the functionality of the child components. 27. 3.7 RenderFragment: A templated component is a component that provides a layout, a template for the developer. And then the developer can use that component in apparent component fully out contents, HTML or Razor syntax within the component template so that the markup, the view not only come from within the Tel component, but also comes from the parent component. So let's go ahead and implement a templated component. So again, we're going to add a reader component right here and there to controls folder. And I'm going to call this a, a templated component, right? So let's make this looks a little bit better. I'm going to have a paragraph element here, and I'm going to just type in some words here. So this is my later wars. I hope it helps. And their stand. How later? All right, so above this, I want to have a header so that whoever uses the templated component can do whatever, can put whatever elements above this paragraph above what I wrote. And then I can also provide a footer. So wherever use it, it can provide a footer below the sentence. They're well. And to do that, we are going to, again, it's a tuple perimeter. It's not just a regular parameter and you have to declare it as render fragment. And so when I say header, I'm going to copy this and make another one. And this one we call it footer. And the way to use it as very, very easy. We just put either and then we put corridor, right. And notice I'm not putting anything in between so that I give control fully to the developer, whoever uses the templated component. So let's go ahead and use it in, again in our index component. Index page. Index page gets a little bit crowded, but we didn't wind. So we give two line breaks and then we use the templated component. And within here we can see the intelligence IntelliSense actually got in data science pick up, picks up our header and food or food or render fragment in the header, or say welcome to my course. And at the bottom, I wanted to approach a def here. I actually here I want to use the bold HTML element. And then here I'm also going to spell it so that it's a little bit smaller, just like a footer. Fund, size 10 px, two, free to leave. A comment. I'm very much appreciate it. All right. So that's let's refresh our page and see what happens. You can see that a tablet components rendered and we have this welcome to our course in bold. And then we have this smaller footer here. Unfortunately, we did not provide any line break. Right? So as soon as we provide the line break, we are going to be having no problem in here, so we just use a pair above. And then here we are going to just use line break and then refresh. Okay, so we have our header, we have our footer, and this is the content we already wrote within the template or component. So a typical reason why we want to provide data from the parent component to the template component is the template component provides structure for a list of items to be rendered. And then the parent component provide that list of item and the layout of a specific item to specify how the specific item is rendered. So let's see how that works. Let's change this just a little bit here. Instead of using this, we're going to have a terrible parallel with internal golf is not allowed. We're going to actually declare the type first. So use type rum and then I can use T item. And we declare a parameter which is going to be a list of the T item, and then we'll call it items. So this template component is going to work as a repeater. So it's going to repeatedly render the items. Whereas the parent component is going to provide a template about how the atom should be rendered should look like, right? So in order to do that, we are going to use C-sharp. We're going to use again for each, and we're going to say for each item within items. And then we are going to now create another parameter. And this time is a render fragment. Fragment. But it's a different type of render for recommend which takes a generic type. And that's going to be the same generic type that we're using already. So and then we are going to call this the, let's call it a repeater, repeater item, right? And we are just going to use it right here. So this is where our repeater items should be rendered. And let's go back to our index component, which is our parent component. And we are going to, so we have header footer over here. We're going to provide the list, and we already have it right here, which is the products, right? So we have the product. And then we can specifically tell the template component about what type of what is the type, right? So it's going to be product. So item is a product, items is the products list. And then here we are going to use the repeater, repeater item template. And within here, we can access the individual item that when it repeats, right? Because the template component that actually does the repeating and repeating item is the template that the parent component need to provide. So a provides a layout for the public component to render that item. So here we're actually going to say context, all right, and we're going to say item. And then here we decide how we're going to make that product, individual product look like. So we can just say very simply saying name is item, the name, brand, and Scripture. Okay, Let's refresh the page and give it a try here. So when it runs a displaced this. So I missed one thing. Missing one thing here, which is within the template of component, where the generic type template component we have to actually provide the item right inside here. This is kind of works as a function instead of a property. Okay, so now let's refresh the page and see what happens. Now as you can see that we're displaying or a product list. So we have name, bread description, another name brand description, and another name, brand description. So I'm not going to go back and make it look better because we can just highlight the name and then highlight this name. I highlight this name. So can we can make, we can distinguish between different items here. But this is demonstrating how the render for Recommend can be used as a repeater. 28. 3.8 When does a component render: Laser components are stateful component. And if we don't have a good understanding of the components lifecycle as developers and remind can be confused and we don't know where to put the logic that we want to implement. I want to cover one of the core concept of component lifecycle, which is When do a components vendor components actually render under four conditions. Components render when components are just created or one components events are triggered. Or when component's parameter values are changed, or when developers manually trigger the rendering of the components. So let's cover them one by 1. First, 1 is one, components are just created. So, so let's, let's take a look at Visual Studio. So this is, this is a project that I've just created with with laser WebAssembly. And let's see, the first one is components renders when it's just create it, right? So this one is easy, right? The reason it's obvious, when a component is created, you want to render out a component otherwise, like what's a UI component array. So it needs to be displayed. So, but when, when its component actually create it, right? So the components are created when you just load a component for the first time or when you toggle the visibility of the component, the component is created or disposed. Or when you navigate away and get back, right, or you try to refresh the page and the components of recreated. So let's see whether those three things that I said it's true or not. So let's, let's take a look at the Counter component. Let's see if we overwrite on after render method. And if we run this. So we pressed Alt Shift D. And so this is, this is page as we see that we are using Chrome, so we just copy this Control C. And then we use windows are reading right here. So Linneaus are and paste that in. And I'll click. Okay, so open up another browser. So this is actually the brother that we need to use to in order to debug. So from here, we do Control Shift D again. And this is the window that is launched. So from here we can actually separate point. So go to the Files folder, and then we can see all of the even the program files. So we can go to our current component and see whether this is rendered by the debugging. This is pretty fickle. So if we just refresh this counter page, you can see that the trick, the breakpoint is not actually triggered. So yeah, I sleep triggered a break point for the first time when the components just create it. So you want to debug code over cold. And then I can just write console right line. And this is, this is very similar to console.log in JavaScript. And then we save it. We would deal with that. So once we build it, we come back to this developer tool. And we go over here, refresh it, and come back to the developer tool. If we look at the file, the file was actually changed. You can refresh again and then we go to the console and you can see that on counter component on developer render is render at this time. So now we know that the, when a component is created, the component render, because this event is only triggered after it's renders. So this kind of proofs that the Venice just, it just render. Another possibility is that if we navigate away and we never navigate back, then, this is a very point is also triggered. And first render is true, meaning that it's just render, It's just created, therefore it's rendered, right? So those three conditions. First one is when you just come to the page. Second one is when you refresh the page. There one is when you navigate away from the component or from the page and come back to that page that contains a component, then the component is created, therefore it's render. The second one is the component renders when the components events are triggered. So for example, in this corner component, some people think that this current count only when the current contain is, do the components actually, does the component re-render, but that's not actually true. So let's actually comment out this line and then rebuild the application. And once that's done, let's go back to here and refresh the page, right? Once we refresh the page, we can actually go to the source code and we can see that the Counter component actually doesn't have that. See this is the corner components, so this has already come and out, right? So this line will not actually one at all. What we can do here is that if we click on it, see these on Render, opt to render even is also triggered. So this proves that as long as there is an event that is triggered, then the component is rerender. All right? And you can see that this parameter is false, meaning that this is not the first time. This is not the components just created this component already created and we click on a button, and that button does nothing but component is still 100. So that's the first I want to emphasize here. The second is that the when events are triggered, that's true, but it's not every single type of event a has to be. It has to be a UI events like clicking on a button or change your drop-down list. That sort of thing has to be a UI event. That what if we are increasing the current, the countercurrent by a timer that is not going to make our component rerender even though our UI state is updated. And the other case is that if you create a event or a delegate within C Sharp, within your code, and trying to trigger event or delegate manually, you are a component will not be automatically re-rendered. So another point interval for size. When component UI events are triggered, the components of rerender, that's usually the case, but that UI event has to happen within a component, right? It cannot happen outside the component. Outside the component. Thus. It's not going to be rendered. So for example, if you have a parent component, that parallel component has a button, and if you click a button, click on that button in the parent component, the child component will not be rendered, right? And if you have a child component that has a button, you click on that budget of the parent component can now be rendered, will not be rendered, but there's one exception when you use a templated component, but let's say that we have a template. So here I'm adding the render fragment. And then, and the parent component, I'm using the render fragment template, declared a button and handling the click button event. And we refresh, we see this Click body template. And let's clear the console and we click on the body template by click on was 10, we see that the Counter component guards spreader and tau component also constrained. So if I click on two more times to go here, you can see that those counter component and how component gas friend or get render. So why is that? The reason is the body template is kind of special. When you have buttons or HTML elements within the template, it's also considered part of the child components, right? It's considered so this button is considered part of this component. So when you click on the button, It's as if you're clicking a button within that token opponent, right? It's actually part of that. It's actually within it. But because the fact that it is also part of the is also defined in the parent component. So that's why the parent components also render. Okay, so that's the second bigger topic here. Our components re-render when the components events are triggered. So I covered the three important thing I want to emphasize again. So events, we don't need variables to be changed as long as you have an event handler. For event, even though event handler, you do nothing about it, the components also gets rendered, right? So second important point is that the event has to be a UI event. Any other events like a timer timed events or a event delegate, you register 2, 2 or event delegate within some other components, and that events gets triggered within this component. This component will not be re-rendered when the event happens. The third thing that I wanted to emphasize is that the man has to be triggered from outside, sorry, from inside the component, not outside the component. Except for one case that if you have templated component, then that template, but the event happens within the template triggers both the parent and the child components. So, okay, so now let's move on to the third thing, which is the component parameter values change. Here we go component. And if we Another parameter. And the parameter would be the counter if we just display the column header value right here. So there's encounter from the parent component. If we feed that culture value right here was the current count. Every time you click on the spot, the Click Me button. Your child component also guts, guts we render so without. So let's delete everything in that it's distracting. And we don't need this. Either. Don't mean the template component. This and build it. So here if I click on it, you can see that the counter value does not change. So we are, because we're not passing it. And I click on it again, you can see that the only thing that changes, it gets re-rendered is the cost component, which is the parent component. But if we go to here, go to the parent component, and if we passed out parameter right over here to be the Gantt view does refresh the page by, well, we click on it. We can see that all of them, both the parent component and a child components get re-rendered every time we click on it, right? So you can see both our re-render. So that's the third. And the fourth condition is when developers manually triggered the rendering. So again, if we remove the US and if we just come over here and even with the best. And from here, if we reference the child component, a child, and then over here just say private owner. And so this And if we just every time this is a child that will contribute to the coast count. If we do this on, let's see what happens. So basically we are increasing the counter valid. This property, right? It's not a parameter, but we are not expecting this would change. So you can see that it's not changing, right? Although the value is that's increased. The only reason why it's not convenience because the child components not render rendering. That's because none of our four conditions are met, right? We're not doing any of these. So the top components is not being re-rendered. So in order to re-render it, we had to ask developer can manually trigger diary random. We can have public and let them in color. We render this solution refresh, and we call it we call it. And then when we come over here, can call child refresh. And that woke figure the re-rendering up the cal components. And I'll just go over here, refresh the page to pay to pick up the change. And that's through this. You can see that both the Counter component and the component and the component pick up the chain. And if we go over here, we can see that we can see both are re-rendering. Remember, there are only four conditions that the components got rerender. First, seven components are created. First, second 1 is when components events are triggered, that one is one component's parameter values are changed. There. One is when developers manually trigger the rendering. 29. 3.9 Component Lifecycle Events: So what I'm going to cover the sequence of each one of the life-cycle event in terms of in what sequence they are being triggered. So I'm going to cover both the server-side laser as was the web or simply blazer. I'm going to divide us into two categories. The first one is the first time rendering, and the second one is after the first time. So the first time rendering is when the page is just load it. Or when you navigate to the component to this page component, Let's first covered the first category with server-side later. So I'll have servers have laser default template. I have all of the events are written down and a brief break points. Same with the child component of all of the events and have the breakpoints for each one of them, and have the child component used by the parent component. So I'm going to run debug and let's pay attention to and which sequence these events are triggered. Again, this is summers, I believe they're right. So the set parameters async in the parent component is triggered first. And then I'm going to continue on neutralized second problems or third. And when I press Continue again, now, I'm expected to go to the child component instead of carrying on. So i 5 and the psi parameters async in the child components ahead. Only the initialize is triggered and the child component followed by ALM parameter set. So if I press Continue again, it's actually not going to go to the shoot render or off to render. Sameness in the parent component, these two events are not triggered. So let's go over here. This is a word our breakpoint is currently at, so I'm going to hit Continue again. Now, we're jumping back to the parent component. And again, the subprime mutters async is rudder and initialize. And then, so I'll initialize and then continue again on parameter set. Actually when I, when I click on Continue, it's going to jump over here again. And then on slide and then practice it. So why are they rendered twice these three events or render twice? That's because if you look at the diagram, we're looking at the diagram will have the browser and we have the server site to first requests sent by the user and then the first rendering. So this is, again, this is server-side blazer, server, server side laser. The browser sends a request first and then run them for the first time, including the, the JavaScript for server-side leader, and that's JavaScript, establish a signal, our connection and then server SAP run, There's the component that get, That's why I run there twice though sweep events are called twice, right? So after does watch what happens if I continue from here. So I jumped back to the parent component and costs on to render skipping they should render because this is the first time and it has to render. It doesn't make any sense to allow the developer to come to control whether to render the component, NADH has to render the component. And then I continue jumping to the. Chuck component calling the on-off to render, in fact continue. Now the page is rendered. I went to my first house that the double rendering only happens when the application, when the components loaded for the very first time. So if you navigate away from the component and then navigate back because the signal, our PEDOT is already established, those three events that are called twice will not be cut price again. So let me refresh the page. So notice that we're on the parent component shall component these three events or back to the first parent page, these events. And secondly on the two-component. So we noticed so far these two events are called twice ofs the parent component and tall component. That's because I refresh the page by refreshing the page to signal arc connection is re-established. That's why these three lines are being called twice. And then we're going to the operator rather apparent age, parent component and unlock to render coach helping period. So if I'm not in that, if I navigate away from the home components and from the index and then get back to the index component. Watch what happens now these three events. And then tell component these three lines had been again. But then those two events are not going to be called a cop twice. So we're actually moving on to a loft surrender from the parent component. And then I'll have to render for additional component. Okay, Let's summarize so that you went to sequence that we're experiencing in server-side later in the first category, which is the first time rendering, is that the these three events are being called one-by-one in the parent component. And then the same set of events are being called in the same sequence in the chalcone point. And then after Dada, The same thing happens again, right? For the parent and further child. And only after done the parent component afterward there it's called and child component after, and it's called Seeing this, any initialization cold that you put inside these three methods. All servers at the laser is going to be called twice. So when you're initializing your data, you have to really pay attention to where you put your initialization. You can still choose to initialize your data within the alanine slides that were on your slides, async methods, if you are not trying to initialize a lot of data and blazer, you're not supposed to pull a lot of data from the backend anyways, there is a renderer. Async was a perimeter that indicates whether it's the first time we're not for server-side laser or you can use that method to initialize your data in the app to render depends on whether you are going to use that data to render on the screen or not. A yes, then you need to call status change method to re-render the page again. Now let's look at the same thing in blazer lab assembly, because it does not actually triggered a breakpoint. So you can either debug it through the brother. But for this lesson that's used console.log line and that is this similar to the console.log in JavaScript. So you can just do this and then expect to see the deadlock is written in the console window in developer tool. So I'm going to do that. Let's go to developer tool and we can see that it's actually the same sequence, right? Paren components of this 3, 3 lengths. Cal components again, is this where events and then paragon ponens car unlocked to render child component cause a lot to render. The only difference is that the parent component. These matters are only once because this is WebAssembly. This second rendering is no longer needed because there's no signal are turned on. That is it. Now let's moving on to the second category, which means re-render. And from the previous episode that we know the four different cases that would trigger a re-render of the lats user button. I have a button here, having 100 here. So this is serous out later. So I have a breakpoint set up right here, and let's run it and see what happens if I click on the meat. But actually the first event that is called, it's actually the event handler. This button, right? And then after that, the button is only on the Perkins School. To click the Continue button. We calling this should render. And then if I click on it again, the QALY on the oh, I'll not to whether notice that we're still on the parent component and you'll see that the child component we rendering is not called if he washed my previous episode that, you know, the reason why the talking point is not we render so those none of those four conditions satisfies to the child component are not contributing render. Whereas for the second category, which is the rerender category, this, Let's summarize that. It actually looks like this, right? So first, do you have your apparent component and it's there's no condition for the child component to render. What you're going to see is something like this, right? You have your parent components should render in the parent component after a runner. And if there's prompter change or any other condition and figured we render up the token, Connie, push it in and see is something like this. You're going to have your parent component should we enter. And then these three events, and then parent component after Enter and then child component afterwards. Something that has interesting, I want to point out is that you should run there. Okay, let's change this to return. Now let's see what happens. So I'm going to click on it, click Me button, and then the event handler of the buttons, a Cloud-first going to shoot learned. And then you see that account is so that means the top and put it in the parent company did not go. So for the second category, which is a great vendor scenario, the server-side and the client's up later, the web something later are exactly the same song, actually going to render them over him. 30. 3.10. Forms and Validations: Traditionally were using the regular forms for a user to input data. And if we look at the contents of this, we have a form element, and then we have input field and then a Submit button. So when the user clicks on the submit button, the forms will be posted back to the backend to this location. But application we can with blazer is a single-page application, which means only the first page load goes through the HTTP request and in response pipeline, a subsequent actions would not be post back to the back-end. In order to still perform form submissions, Microsoft came up was a set of components to perform the task. So instead of using regular forms and blazer, we should use the edit form component. Instead of using the regular input, we should use input text, input number and put bait in a select expression, but don't worry about the error here. I'll fix this era later. When the submit button is clicked, event handler specified, which is valid form is submitted. And if you want to handle invalid form submitted, so then you do invalid forms a minute and connect it to a function. Right? So here's two things we need to know. First, going to use a added form instead of regular form, and then we'll use input fierce differently. Another thing that we need to know as order to handle the submission, we specify them that there. The next thing you should know is that the ADA form has to eat onto a modal. I declared a lot of class here person. And then I initialized the person who had here. And then an edit form. There is a parameter that is called molto and I provide that person model instance to this model. Next, need to use Bind value to do data binding. And I'm associating each properties inside the person class to the input elements. Then the next thing we need to know is validations. In order to validate the model, we can use annotations. We need to first use that namespace. And then we can annotate the properties. Which of the entity annotation attributes like required, string lengths, maximums, range. We can specify the data type like an email address, et cetera, in order to trigger the validation and display the validation messages. At the top, we're going to use the data at a nation validator component and also going to quit validation summary here. And that's all we need to do for a basic validation scenario. So let's run this form and see what happens in red. So if I don't do anything, I click on Submit button. It will give me the required error messages, or put minus one here. And I click on this. It will give me the range Hermit answers and emails as also still required. If I put if we see dot IBC, this, then it will directly say that email address is invalid. So if I provide a rock in the address format, then this becomes a screen. Then if I go by the crack number, then all, everything is great. And the submission will trigger the loudness of that event. And this event handler will be triggered. So that's the basic validation for I finished this episode. I wanted to mention a couple of things. Notice that this v is a capital V. Usually we use data binding outside of the adage form, you would use a lowercase v. And if you keep using the lowercase v, you will encounter very weird errors. So remember to use capital V here. Another thing is that if you put buttons here like this, the bottoms default type is going to be submit button. So if you put buttons here and expecting behaving like a regular button, it's now going to happen, is going to work like a submit button. So if you want it to work just like a button, then you have to specify it. Asset button. 31. 3.11 State Management with Observer Pattern: So with a component, whether it's up later component or angular or Vgs or react. It does not matter which component. There's always going to be a view. And then the user will interact with the view. And then that interaction sugar, some events and events are handled. Events are handled and then handling the events will mutate state. And then with the status mutated, that view is updated. So you're in this trend. But the problem is if we only have one component of a very simple project and we're maintaining the state in components themselves, within components themselves, that's not a problem. But once you start writing more complicated cold, doing more complicated projects, you may run into situations where you have to share the state within different components. That's where we need to extract that state outside of the component, put it somewhere else and what we call a state store. And it's more look like this. So we have a state store where the state is stored, and then we have different components. And it'll be the same kind of triangle. Because the user will interact with the view that we would triggers and events. Events are hello and maintain the state. And then the view is notified and update it, but in this case is slightly different and stop when the step is mutated. Notification is not only sent to one component, hey, it will be sent to multiple components. In this case, you can see that notification is sent to this component one as well as component too. So the same thing will happen if the user interacts with component 2. Then events are handled and state are multiplied, and then notification sent to both components and update both. And this is actually what we call a observer pattern. So observer pattern you have, you have subject and then you have observers. Okay? So the subject in this case is going to be our store, store. And observers in this case, components. The observers actually listen to the subject of interest to the store. And then as soon as there's anything changed in the subject, the observers will get notify. It's more like a push notification on your cellphone apps. And whenever there's a change, you receive a push notification. Well, but you have a twice to react word, right? So we have this later server app created. We run this control F5, we see the default later chapter. We're going to change this counter page to use a Store instead of a local state. So if you look at the counter page right now, the counter component, and as a local state and its local status referenced in here in the markup here. And the increment, the click, Click Me button caused this increment method to increment the count. And then it's displayed here. What if we want to display the cans not only in this, in this place, but we also want to display a right here, right? So we need the state to be centralized somewhere. And thus, when we want to insert store, so we have, we may have multiple stores. So let's create a store folder. Call it scores, so that it may have multiple stores. And let's create a another folder. And we need another folder. Yeah, so we may have different actions. So let's create a store folder. And for now let's just create a class. And let's call it score. And that Conor's store. It. Nice to have a state. So a class that represents the state. Let's call it conquer state. And then here we just need a variable that has a integer type. So we would want to have a tutor type code, and I didn't want it to have a setter. So let's initialize this in a constructor. That's it. So we have this only has this getter. So our state is immutable, which is, which is better than immutable host this we're actually using that in the central place. In number store, will have to use the counter. So counter stain this. Well, let's just call it a state, doesn't matter. We'll stay with this. So our Conor's state here, and then we expose a state and a third will get for cones. This method. Return the state. Here comes the observer pattern we have to implement on me up, we have to have a listener, will have a private member, which is a listener. Listeners. We have this action, the kind of lucky button handler reuse action so that it doesn't have extra parameters. So have this private action listeners. And then I need to implement a registered, the listeners, right? Call it as state change. Listener. Because it's listening to the store for change. So let's call it this way. We're adding the listener and do is just say on the severe. Then we have another method for removing the listener. Does this. And then whenever it there is a change in the state or Restore will broadcast. I'll teach it so we need a method to broadcast that change. And then this group, we come over here. So instead of using this local state interdependency and Jack the corner store, right? So if we go to our startup class, computer services scoped. So because we don't want to share to date with all of the users. Scope is scoped to the connection. Still can restore. Corner store that here. We're not implementing the interface just yet. So adding this one instance associated with that connection. So as long as the connection is not broken, it won't be the same instance of this kind of store. And that's good enough. So here we just say Kroger store. Actually important as namespace so that we don't want to see that namespace imported. And then just so this corner store, to store, this corner store where he, so we can delete this angle over here and say Go to store. State of gas called recurrent store were also also. So let's actually use a region here because this is boilerplate code. See it all the time. Do you let's call it the repower server. Through close this. We're here for we got a code that occurred in increment that coenzyme and it will create another state is mutable, so adequate new one. And then we'll call coast called broadcast change. Same thing will be synchronous communication for decrement. So we decrement. And then only difference is right here. Okay, increment columns here, we'll say store dot increment. This law cost thing. I wanted to be I were to be private. So then we have to register our component to listen to the store, right? So for it that will override from the HSL eyes are automatically format the things hidden where you say her score. The register, state change listeners. And we would just add an inline function. We just say, you know, whenever there's a change, I want to call this stage change. That third, right? So we have an increment and then we stayed in that set because we want to also display that in a minute. So go to the shared folder and find the menu, navigation menu where there is a corner, right? So in here we also want to inject store and we own, let's call it P over those cold from here. So according to the mandible. So at those and listen to the change, right, so we're registered and we add a listener so that the component will become another observer. Right over here. We'll add a colon and then we'll say or do state. And let's go ahead and look at our page. Refresh our page, no reference point. So the problem is, right here, we forgot to initialize the state. And to do that, we'll come over here, say kill the constructor. And then we will say each state to state 0. So initial value is 0 and there are five. Alright, so we have our counter number displayed right here and here. And if I click on it, it increases both places. All right, So our observer pattern works. I have to add or remove state change listeners there, but that didn't use it. I want to emphasize that this is very, very important because the corner store is a dependency in dependency injected into our components. And the corner store is added as a scope. A scope which is scoped to the connection, right? This is blazer with this the server-side, the laser. So ASCO is scoped to the connections. So if you don't refresh your page to kind of store, well, we're left as long as the connection. So unless you click on the Refresh button, then recreate it. So that means that because we registered to the counter story, essentially we make the component has the same lifespan as the store, which is a sculpt, right? As long as the connection. So when you navigate a way, latest frameworks opposed to dispose it, but it cannot dispose it because the store has a reference to the component. So it cannot dispose it. And when we come back to the Counter, component will recreate, create another instance of this. So because it cannot dispose it when you navigate away and never get back and navigate a way though, that it will create multiple instances of the same component, right? It will never released that whenever. Recollect that. So this is a memory leak that we have to do with. So in order to do that, I want to emphasize that that we have to do with that. And the way to do that is we need to implement the IDs post mooc interface. And then inside of our code block, we need to implement the dispose method where we have to say counter store. Instead of using inline arrow function. So it's private void, they do. And in here we're going to call this state change. And then instead of doing this, which is just bring up a view here. And when we remove, we also removed view. So this is this when the component is disposed, this dispose method will be called. And then a will deregister the listener what detach the counter from counter store, which in turn allows garbage collector to collect the instance of the counter deployed. 32. 4.1 Dependency Problems: Hey, and clean architecture. One of the most important things to achieve loosely coupling between the different rings is dependency injection. Without dependency injection, clean architecture is impossible, therefore, this section is all about dependency injection. First, I will quickly go over what dependency injection is. So we will have two modules or two classes. At one is higher, the other end is lower, and the higher one depends on the lower class. For example, the customer surveys class needs to use the functionality of the customer data access class in order to get data from database. Then we say that customer service as a dependency upon customer and data access code. In order for the higher motto to use of the lower model, we had different ways to do it. The first obvious way is to have a history of this custom class right over here, red. And then we just call it customer VA. And then in the constructor, say custom da equals new customer. That axis probably with a connection string, right? And then you can do that to, for example, get a customer, customers. And then year. Because they say customer return, customer got customers. And that's actually all have merged. All right, so we've got a list of customers. So this is one way to make use of the functionality of our motto. But as you can see that the customer services is tightly coupled with customer data access. It, it's aware of the definition of this class and there are many problems with this. For example, if you want to have different teams, One team work on higher-level module, the other team worker, lower-level motto because this tight coupling, it's very, it's very difficult to work in parallel. And also, if we were to change this name of this class, then you have to go to change the code over here. You're going to change, you're going to teach this is going to change this. So you need to read, recompile the higher modules in order to do that change, right? So the maintainability is not good. And later, if this data access layer is going against a file system as great an error class. And that's going against going guys, database, SQL database, for example, like this. Then you would have to go inside and change to cope. So that's a extendibility is also not good. So there's many different disadvantage of doing this kind of tight coupling. 33. 4.2. Dependency Inversion Principle: Dependency inversion principle, which says higher-level models should not be dependent on the lower level models. Both should be dependent on abstraction. So what is abstraction? Abstraction is because the dependency there is the dependency between the service class and the data access cost. So that dependence cannot be removed. Instead, what we need to do is to check that dependency and that dependency is the functionality. So dependencies of functionality and we need to abstract that functionality. And in C-Sharp, the way to access to abstract that functionality is to use interface. So we can create an interface like this, right? And we can say customer did Access. And in there we can just say, no. All we wanna do is to have to get a list of customers. This is the abstraction. So basically it just says, I have a way to get customers. Notice that this method doesn't have a body, doesn't have any implementation. So whoever actually implements this interface, they need to have that implemented to implement this in concrete class. In this way, we're not actually using concrete class here, we're just doing this and that takes the dependency on it. 34. 4.3. Inversion of Control: But again, it's still having the same problem. We're actually creating this instance of this concrete class right here means that the higher level object is still aware of the lower level object. We have to take this responsibility away from the customer service. And the service possibility is the instantiation responsibility and we need to take that away. And this is called an inversion of control. How do we do that? We need to create it from offside. Simplest way is just to, just to create for low side. That's the aim is to use a different variable name. You can just do it this way. And then when this class is instantiated, or we can just do electives. And you say da, da, and that's it, right? So our private instance has this and then went from our side because when we instantiate this class, then then we get into it. These are the main two steps. First, we need to use a abstraction which is integrated C-sharp. Secondly, instead of the rapidly instantiating the concrete implementations of the interface, we use constructor, then pass that instance from ASA integer. So this is the path dependency injection in C troponin st conserving every other language. Of course, there are different ways to do this is through the instructor can also create a property of that. Just to say, if we were to correct create a property instead of doing like this and just say constructors here. Public. So in that case we don't need this access and data access equals because there is both sets of property in C sharp. And then when you use it like this, you can just say, instead of doing like this, we can distribute this. And then from here customer service. And then you can say customer ID access woes. And then, then you can use it in other. So that's dependency injection in general. And then next let's go into Visual Studio and see how Dependency really works in later component. 35. 4.4. Dependency Injection in Razor Components: Let's see how dependency is injected into blazer components. First, let's look at service app laser. Create a plus. Let's call it customer service. This customer servers will have a public method that returns a customer. And for that, let's first create a customer class as well. And that's it. Simple. In here, will return, a customer, will say, Okay, customer by ID. And the parameter is a integer, which is the ID 0. And this constructor, let's initialize a list of customers. And then the here. Okay, so we have this service, we want to inject it into blazer components. Unless inject into index component, which is a page component that has a routing path here. Let's delete this survey prompt. Let's play, let's use this in a recall. So one way to do it is to declare a customer service and then we're just say customer service. Customer service. So this is not, this has, this has this dependency problem. That is, that is making the index component tightly coupled was the customer service. Plus, that's not what we wanted to. So we have learned what dependency injection really is for two main steps. First is we need to use interface so that our next component is dependent on interface. So we need to do as you create an interface. And to create an interface, we come up here and right-click. And then we choose quick actions and rectory, which is Extract Interface. And then click on Okay, so there's only one behavior here as already extracted in the interface. Second main things you do for dependency injection is to do the inversion of control, which is 2, gave it the control of instantiation to the infrastructure, in this case is Core Platform. And core platform provides us with a mechanism so that we don't have to manually use the new keyword to create an instance of the customer service class. We can go to the startup class and there to configure services method. This is a place where we need to map the interface, which is the abstraction to the concrete implementation. And the way to do it is to go over here and there to configure services method against services stop at trends them. 36. 4.5. Lifetime Management in Blazor Server: There's different ways to do it. So one is transit, the other one is sculpt, and another one is singleton. For all of them are doing dependency injection, the only difference is each one of the three method has different lifetime management. And let me just point out right now. So here if I have say I Customer Service, and then provide the concrete implementation class over a year. That means when within the component, if we ask for a customer service interface, the abstraction Core Platform, well provide us with a instance of customer service. And whereas transient. Every time we ask for a implementation of this abstraction, and we'll create a new instance of the customer surveys class. And was, instead of using transient, if we use sculpt every time we ask for the abstraction implementation of this AI Customer Service, it will give us not new instance, but i instance that is scoped to the connection because in place or service at later sculpt instance is associated with the lifespan of the SignalR connection. Which means if the connection is not broken, then it will always have the same instance. Finally, if we are using the singleton, singleton ice, customer service, customer service, that throughout the lifespan of the applications will always give us the same instance. Let's first examine the transient. In order to examine the lifespan of the injected objects, Let's go to our customer service. In this year, we're going to add a public property which is going to be a unique, It's going to be a unique ID. And then within this constructor, I'm going to say UID equals bleed, new good and to string. Okay, so every time this class is instantiated, we're going to add a new GUI. Okay, So this is to examine the lifespan of our dependency injection. And since we added this UID, we also need to put the UID into the interface so that we can use it. So we can go to click on this magic one. Shows the poll UID up, pull your ID up to the interface is right here. So next, we need to dependency in Jack, the customer service into our index component. And to do that, first we come to the top of the component and then we say act, and then we use the interface. Can say customer service like that. Then when the component is instantiated, laser application framework, we're actually use the dependency injection, this mapping, and create a new instance of the customer service class and give it to our index component. So because our customer service currently returns a customer by its ID, and we have the three records here. So what we can do here is go to our index component and state here. Is going to be a customer. And then override the initialized method here. Then what we can do here is to use the injected customer service to customer ID, customer by ID. And let's see the second one. And let's assign it to the state. So we initialize the state right here. And then we're going to show some information. And we're going to make sure that the state is not now. And then we're going to show no customer say customer info. We didn't display the customer dot name. Okay. The other thing I want to display as the good and that's within customer. And I want to use, I want to directly use the customer service. So this, we can put it outside around here, go to the line break here, give another library. Here are two line break here. Great to language here. Then there's customer service. Again. Display the DeGroot right here. And the last thing I wanna do is to implement this component, implements the eye disposable interface. Within the ideas of Basel interface, we can implement this dispose method. I'm actually not going to implement anything, but I'm going to set a breakpoint here so they can see the tangent. So I'm going to debug. So if I move away, you can see a move away. It actually disappears. All right? It creates again move away. It is poses and a movable bar. And if you pay attention to these numbers, right, 767 more when I remove that point and move back, number changed from 7776721. B7 is every time I do this. Number changes, every time I move away, consider the suppose method, and never get away from the index component. You can see the dispose matter. That's called Interesting. The x component corresponds to this homepage. Okay? So this, this pole disposed miser gets called, which means that every time I move, move away, this component is actually stored, right? And when I come back, this component is created. Whenever it's created, this dependency injection injects the method, sorry, injects the class to our component, then we can use it. Right? So this is an every time it changes and this is the behavioral trends transit and says, I register service to a container and every time I ask, for instance, the container will create a new instance of that class and inject that into our component into where we want to use it. So that's what we call transit. That's least see what singleton. So let's change this singleton. And this time I'm actually going to use Control F5 to debug it, also for the covenant without debugging and Ashlyn, I'm not debugger. See that we have this number here. And if we move away back in sit, the number does not change. So that's singleton. Singleton means there's only one single instance of the object, the customer survey object in the container. Throughout the lifetime of the application. Evenly you refresh, which actually resets the connection. You can see the number does not change and that's the behavior of singleton. Singleton, there's only one instance. And if we wanted to look at how scope works, Let's change this to sculpt and come over here, refresh the screen because we use controller 5. So this whole Hot Reload works. See the number change right then. But if we never get away and navigate back, you can see the number still the same. It doesn't change. So it seems like it's a singleton but it's not. So if I refresh and which by refreshing there's a disconnect that connection and re-establish the signal our connection, right, because this is laser server-side. So, so then the connection is broken and reestablish. So you can see this time number changed after I refresh. And that tells us that the sculpt lifetime configuration makes the service live as long as as long as the connection does not get disconnected, you will always have one instance. 37. 4.6. How to Choose the Lifetime Management: You have to choose the best suitable lifetime configuration for your services class. Because some of them may want to use transit and some of them you want to use sculpt for better performance or for whatever reason. And something you want to use singleton, right? For example, if you want to use some classes to contain some data to try to implement state management. That way, you don't want to use singleton because that way you are sharing the data across all of the users. Users from different browser sessions, from different parts of the world. I'm gonna see the same data. And unless that's your purpose for state management, that is very specific to particular user. You can use scoped and that's related to that one particular connection, which cannot be shared between different browsers. But for very light services, you want to probably use trends in for services that is not thread safe, which means concurrency doesn't work. For example, DB context from Entity Framework. You don't want to use singleton. You'd only use Scope. Even for transient is created every single time. It may still have problems. So you really want to consider the different services and different scenarios. So this is blazer server-side. 38. 4.7. Lifetime Management in Blazor WebAssembly: Next, let's look at laser web assembly. We're going to have another instance of registered. It isn't 19 and click on laser up. This time. We'll see that startup file. That's, this is why the centrally, so it doesn't actually have it. And you can see that they are register right here. So we can do a similar thing, okay, say builder services. So basically you're saying for this interface, this class implements the interface. And then when we ask for instance of this, the beauty criteria is actually going to create a instance for us by instantiating this customer service. And what we wanna do here, same thing we're going to do here is we're actually going to copy this code from right over here. Here we registered fund it. So let's run it in 2005 within. So we have this running and we can see the number is C to D or move away. Number change. When number change again, if we refresh, number change, refresh again. Never changed again. All right, so, so this is trended reds. Basically, it's the same thing as later server side, where every time the components or class instantiated new instances associated and I injected into the component. So that's that one. And then singleton actually basically works the same way, which is also, every time you ask for it, you're going to have the same instance. Refreshing, downloading that again. So you can see that it's C9 seven. And then if I move away loop axiom seven and I refresh. See that this works differently now, refresh actually changes. Change changes the number. Every time I refresh I get a different number. So I explained us a little bit later. But we just take a look at the scope. I be able to again come over here, refresh the melting 949, remove a mole is the same. Right? The same number but when I refresh and also JV. So it looks like the singleton and the scope are working exactly the same way, right? Only trending works differently. And the reason for that this because this is WebAssembly. So the whole service at COS actually downloaded. All of the DLLs are downloaded to the client side in that, inside the browser. And inside there we have this WebAssembly contacts. And all of them are actually hosted within that context. So, which basically means that as per one, this console application here is actually running inside the browser. That's why when every time you refresh it, it creates a new instance of this program, right? Because this program is, the replication is basically this quite and then recreated. And the main method is run again. And that's why you see the, even with singleton hits, it gets different number, different ideas every time you refresh the browser and the scoped, because there's no connection and there's no request. So a blazer WebAssembly doesn't actually have a scoped lifetime management configuration. If you scope is going to work the same way as singleton. 39. 5.1 Reorganize Projects to Reflect the Architecture: Before we start implementing the complete E sharp project, I wanted to take some time to organize the folders so that it makes more sense. So this is the first solution that I created to demonstrate the simple search product page. I have the core business and use cases and the hard-coded data store implemented. But I want to take some time to reorganize this. So let's go ahead and do that. So I'm going to copy this three things. And I'm going to go into the source folder. And I have a project folder there. So in here, I'm going to create a sharp folder. And then I'm going to place these three products here. And I like the way that I named use cases and the core business. But the thing regarding the hard-coded thing, I wanted to be under a plug-in folder because later on may have multiple polygons. So I'm going to copy this and place it into here. Okay? And the next one is, I'm going to introduce something that is called a modulus. For the UI modules, I will have definitely have a blazer application project here, but I don't want to put all of the UI screens inside the same project. I want them to be separate so that it gives you a more macro front-end fill in. And it comes with SS benefits of parallel development. In our case, we'll have a admin portal, Customer Portal. And obviously the customer portal allow user to search products and place orders. And the main portal allows the admin users to manage the warriors. So and then I'll have a common on projects as well in which some of the common elements, for example, search bars, error message components, maybe spinning wealth can be placed in that common project. And for that, I'm going to create a, another folder. And I'm going to name it as sharp WACC module. So this mother modules are for web application. So now let's go ahead and create them in Visual Studio. So I'm going to create a new project. And it's going to be up laser advocation. And I'm going to place that into source project and solution will be sharp and the project, so because this is a later application, so we're going to name it as eavesdropped on lab. So this represents the blazer web application. So I'm going to click Create, I'll click on Create. And I'm going to select the blazer server application. And what that did is it created a shop that web folder. And The blazer or server-side application under this folder, and that's good, that's exactly what I wanted. And next thing is I want to import core business as well as the Use Cases Project. And I'm going to select the existing project. And I'm going to choose the core business as well as the use cases, okay, so I'll have this two. And next step is to create the plugging folder here. By creating this folder in Visual Studio, it doesn't actually create a physical folder. So you already have this plugins folder physically on the dr, r dr. But we're going to have to add them under here, which we're going to go in the plugins folder. And then adding this one hardcoded data store implementation here. Next we're going to create a folder that's called the shop lab. Well, just pick corresponding to the one on the hard drive. And I'm going to create eight, the customer Porto and the mean Porto then comma. And those projects are going to be Razor class library. So where are you in Orissa class library and your location? This location will be under modules. So select this folder and I'm going to have one product that is So this is commonly sharp razor components and Razor class library. And click on Create. So how one under the e-shop, but Mongos and let's go to our folder and make sure it's created in the right place. So go into here. And yes, so it's created under here and that's that's good. And we'll create the customer portal as well as the admin portal in the same way. All right, so we have them created and the next thing we need to do is to move our components into these corresponding modulus, right? So we had our search products components. So this is the original solution. So I'm going to move these components into the newly created customer customer portal. And I'm going to also move these, these two-component and I think the search bar component will go into the common model and then the product item component will go into the custom report portal. So that would take some time. And then when it come back, How show you what it looks like. Alright, so I have moved all of the components into the corresponding, their corresponding voters have controls on pages and they're the customer Porto, and we'll demo but there and also I adjusted the use cases. So the new product screen, I multiply the new product and its interface, and they're the new products screen instead of a nerd, a search product screen, I think it makes more sense. So and then I just said the namespace because the folder structure changed. So I just namespace now when I compile it, they can pop. The next step is to make sure the page, the routing works. For that under the runner, There's the app assembly reference here. Currently is only referencing the program where the program is, which is the shoved up something. So we need to add other assemblies to make sure that the page components can be found by the lay their application for that, where there is a additional attributes, additional assembly attributes here. And we'll add a list of assemblies that contains the components that we want to use. We have, currently we have only one, but later we'll have the amine quarter as well, right? So so have the shoved our Customer Portal, their laptop. So I guess I first I have to add the primary reference and who will for now, we won't important. And then we should have the cosmic Bureau over here and, and their pages. Well, we'll just choose whatever, whichever one comes first and preference the assembly of that. And that's it. And now let's give it a try and see whether it works or another thing that I want to change. I want to change all of these services. So these use cases to have a use case word at the end of the file name and class name. So I wanted to do that. Some new products use case like this and then change. And their 1901. And also these ones, the interpreters as well. This one and this one. And then, and then before we run them, we have to go to the startup class to dependency injection. So we're going to inject for their store because we're mimicking a database. Database is basically singleton. It's available to her. So we're going to add singleton for the product byproducts repository. And for that we need to reference implementation. I'm going to use them limitation for the backward pass through. And then they'll have to do Control Data important interface. And that's it for the datastore. For services we have, we can use target, which means every time we require, for instance, it'll create a new instance for us. And for doubtful world. The more important the product as well as the Surge product, product. In the first, import, the namespace, and then sort of search program. In this case, it's just save everything. As far as whether or not, as you can see, it's still looking for I search product instead of my search product use case. And that's pretty weird, but my experience was this was blazer, the italicize, and everything is not completely correct yet. So what I do is I close my Visual Studio, partially closed everything, and then we open and that usually solve the problem. And then we'll come over here where this dereferences list the owner name. So change that to let's go to File. Right? So our product space to work for searching your work. So the searchers and everything works. So now we have already regarded as though moderns. In the next lesson, we're going to implement new use cases. 40. 5.2 Order Entity and Business Rules: So next step is to implement the next use case, which would be the add product to shopping cart use case. Originally, I have it the add product use case under the shopping cart. But then I figured that the AI product actually happens on the Product Detail screen. So I moved it over here. But before we actually implement it, Let's think about it. That product has to be added to a shopping cart where the products are temporarily stored within an order. And that order is not an order yet. It's not a order. Yeah. But we can use order to store it because it's going to turn into order, All right, into an actual order. So we will so let's think about it. We will have a shopping cart and then we need to store the order. So we have to have the order object implemented first in order to implement that everything, right, in order to implement and shopping cart. And then, and then after we implement a shopping cart, we can implement the add product to shopping cart use case. So let's start with the business object. All right, so this is the business object that the entity, the business entity, which is the order entity. So let's implement the order entity first. So for that, we need to go to the core business layer and go to the models folder. And we're going to create a new class. And we'll call that new class order. And I'm going to copy. The codes don't have really created just to save some time. Alright, so let's take a look. So we have our Order ID. So because of the order object are going to be used in shopping cart. So at a time it doesn't have ID, that's why it's a nullable integer. And then it will have data placed when the order is placed, day processing and they process. So these three fields can be used to indicate the state of the order. And then it will contain the customer information, and then it will contain the the order line items. And it will have a unique ID. That unique ID is ID that is created for every order. And then we can send that ID to the customer and then they can use that to track in order status. Because we're not implementing user logging. Basically anyone can go to the website and place orders. So we will create this kind of unique ID which is going to be queried. And that ID can be used to track their orders. They can just use that idea to truck. All right. Here we have the order line items, of course, and the order will have several line items and each line item will have products of one product in it. And let's go ahead and implement that as well. So we'll create another class then. Actually I just deleted the initialization here. So let me recovered that. And then let's create a new class that call it line order, line item. And again, I'm going to copy from so Lion and we'll have a LAN ID. And again it's going to be nullable. And, and we have a product ID and price quantity Order ID. Order ID is to indicate the association between the lion and then the order, right product idea is to, again, as associated between the order line I'm on the product. And then thus is a navigation property. If we're using NEC Frameworks term. So we have that and we'll go back to the water and it's good. And then the next thing is, we think about it. What do we need? So there's some kind of business rules here. And first we'll have some helper functions here to help to help us to add product or remove product to an order. And that we can implement whether they are within this order class. Usually, I would like to separate the rules or the functionalities from the, from the data itself, from the data model itself. Just so that it's less imperative and will have less tends to mess up. Was the state. But in this case, I have, I'm totally okay with was having a collection of data and then being able to and create the master within the collection class itself to add or remove elements, Items 2 or from that collection. So for example, if you implement an array, so it's natural to have add, delete, insert those kind of functions in it. That's why I'm okay with implementing the product and remove part product in the order class. So we'll add those implementation here. Again to save time. I'm just going to copy what I have already here. Alright, so the first or default is System.out link belong to a system Delhi. So we're going to import that. And so we're going to add product and will provide the product, product ID, quantity and price. And then we're going to find out whether we have the product already. If we do, then we just simply add the quantity. And if we don't, then we will create a new order line item and add it to the line and collection and remove product or simply simply find the product and then remove it. Not that I'm looking at this. Why don't I use link? So I'm going to implement that right here. So I'm going to need to find the line item. And so line item, the clothes line items first or default where the product ID, product ID. And if I do not know, so if we find it, then obviously you're going to remove that. So I'm going to copy this over. And I'm going to remove this and just put it over here and the now delete this everything, and that's it. So we implemented the AI product and then remove product. And then let's think about a little bit deeper that order when it's being placed. It has to be valid order. Right. So that's a part of business logic that will go under the services layer, services folder, right? That business logic will go to under the services folder. So let's implement that one. So it's going to be order service. What do we need? So we need to validate we need to validate a different different things, right? So water contains customer information. So we need to make sure that, you know, at the front end, we can implement some validations. But whenever we should never trust a friend and completely. So that's why we need to also implement a validation of the customer information. The backend at the Beckett, where the order is because the customer is because every information is for placing the order. So let's implement that. And again, I'm going to just copy that over and that's review it. So we have this valid customer information, and I have a list of information here and then as a parameter. And then here I'm just going to talk. Everything is not know. And if it's if it is not, then I'm going to return false. Otherwise it's going to return true. The other thing is I'm going to validate order creation. So providing the order, I need to make sure that order is valid. And for that, I'm going to have another function that is called a valid, validate, creating order or create order, and that I will have a tear. This not useful. And order, important and namespace and order here. First of all, it can, they'll be known otherwise it's going to be false. And then it has to have order lines otherwise false. Basically everything it doesn't. Everything I can think of for this is for demonstration purpose and may not include everything that's supposed to be there for production ready products. And so I go into each line and make sure there are reasonable. And then also I call the Ebola the customer function to make sure the customer information is also a valid. And then the next one is I'm going to validate ladder. They'd update order, right. So updating order means that water is already there, but we'll try to update it. In this case is usually what we mean is, you know, same kind of validation, SD, validly created order function. But there are some extra things where we would have things like the date placed has to be there, right? And that they'd process and tick processing shouldn't be there, things like that. And then the last but not least, we'll need a validate process order. We need to make sure that when the main process the order, it will have to provide the admin user and also the process information. The admin user has to populate, date processed while developer need to do that. And also developer need to make sure that the username is also in place. So those are the business entity, the order entity, as well as the validations. And laughing as we need to create an interface out of that. And for that, we need to do right-click here. And then when we select Quick Actions, and then we'll just click Extract Interface to a new file. There will be granted here. And what I need to do is I need to create a folder. So make sure that movement over here. Make sure everything is tidy and clean. That's it. Next. Next lesson where we'll talk about shopping cart. 41. 5.3 Shopping Cart Abstraction: So let's talk about shopping cart. Shopping cart. It's a place where we template store products that we want to purchase. For clean architecture. It does not actually care about the implementation of shopping cart, cares about the logic behind it. And it uses abstraction to do it. So it doesn't matter how we implemented. First we need to implement the interface, and then we can just go ahead and implement the use case without even implement the shopping cart. So let's actually do that. So let's go to our use cases and go under plugging interfaces. So we're going to implement a nicer plugging, right? So later, whether we want to use our local storage from the browser or you want to use a database to implement the shopping cart. It's up to us. And then we create another sub folder. And we call it UI because it's, it's, it's kind of related to UI UX and UI stuff. And I'm going to create an interface here. And I call it I shouting card. And that should contain some kind of behavior here. And what behavior do we need? We will need to be able to get order, right? Because the shopping cart contains a order, although it's not the actual order is not placed yet, but it's a temporary order. So we'll need get order function. And I'm going to use asynchronous programming here because I know I foresee that I'm going to have implementation later to implemented. Whereas local storage and that we need, for that we need JavaScript interrupt. Within Razor components. Javascript interop is an asynchronous call. That's why I'm implementing task and so that it's available. And we're going to name it after async at the end. So I'm going to have another one that also allow me to add a product to the shopping cart. And I would need to provide a the product. And next thing is, I need to be able to update the quantity of a product order. And then I will say update quantity. And I will provide the product ID as well as the quantity. And what else do I have? I will have a update order allowing the sorry, I forgot to sink. They think I've got spelling error there. So up to order a sink as well. And order. All right, so I'm updating what are we. X1 was a new order object and then I will also delete order. And it didn't you order will return me. So each one of those will return me that 100 that I'm operating on. And this one does not return me because, well, you'll have that as well. And it makes more sense to have done and then the DDD order will also give me so not delete or delete a product. So dilute product will allow me to delete a product from the shopping cart and then another one, place order. Alright, so we'll go into our shopping cart screen. And when you do place the order, that's where we need to call this function. And then after order is successfully placed that we need to empty the shopping cart. So we need to have an empty function as well. Alright, so this is, this is the abstraction and was abstraction. We can just go ahead and implement the use case. 42. 5.4 Add Product to Shopping Cart Use Case: So which screen or use cases on? It's going to be the view product screen where we have a button and we click on that button. We add a product to the shopping cart, right? So we will create a new class here, and we'll call it, we'll call it add product to a cart and so called Add to Cart use case. And I want to organize the interfaces into a different folder. So I'm going to drag, actually I'm going to capitalize this over. And we can public. And from here, and we're going to execute this use case. And when that happens, I will need to add the product to shopping cart. And for that, I need to provide a product ID to know which market to enter. Again, we need to be able to grab the whole product and to the shopping cart. And for that we need to, to grab the product repository object. We need to dependency inject that into here. So I would say product repository and to control that important namespace. And then here I'm going to data and create this. And was, was that I will have to return me the product. Got products. Now, I will say shoving card dot product, right? And for that GIN dependency in Jack, a shopping cart, cart interface here, implementation here. And it's going to be from this namespace. And I'm going to initialize the field. I would say, you know, shopping cart, that product, async, and then I would add that product and we're returning an order. Yeah, let me let me away to make sure that It happens. Okay. So so we'll have the product and then the shopping cart interface there. So, you know, I don't need the implementation of the shopping cart, Nimes limited. This is logic. And the good thing about this, as the QA team can come here and implement a mock shopping cart and be able to test the business logic. And then we can test, all right, palpitation of the shopping cart separately. So this is good thing about the clean architecture. Or in next, we need to be able to use the product to shopping card, use case and the customer portal on the view product page. So here within this postcard div, I'm going to add a plotting. I'm going to say PET, CT and MRI. So these are bootstrap classes. And that will give us a nice button. And then I'm going to say Add to Cart, I'm going to copy this. And then tax will be added to cart. And then I'm going to go down and implement this card thing in here to dependency inject the use case product to heart, use case. I forgot to add an interface. So let's add our interface. So I'm going to just, instead of doing that, I'm going to say right-click here and doing those. And then I'm going to extract the interface. Click on Enter, and then I'm going to move this interface into the interviews folder. And let's examine what we have and they're here. So that's example. We will want just that I guess Q method there. And then we're going back dependency injection to inject us, change this 2D of a nicer name year. And then we're gonna go and NOR, and they're here. And I'm gonna say, we're gonna say add a product to use case and I'm going to execute the method. Was the the product. See this product here, right? So because this is a view product pages has a product that is initialized in the parameter set here. So, so here it would definitely have the product because we're actually looking at that product. So we'll have that product ID and put it in here. So what did we next? After we add a product, we need to go back to the product catalog page, right? So for that we need to, again, dependence in jacked. Well our, so let's actually dependency injected on the top, but that's because this group of dependency injection is going to be the system of providing ones. And I'm going to have this down here, and I'm gonna say navigate to the root folder, root paths, right? And that's going to be product catalog. 43. 5.5 Implement Shopping Cart Plugin: So before I implement our shopping carts screen, we will have to implement a shopping cart like otherwise, we won't have any data to display. Although at this point, the QA team can come in and do the testing, or we can actually do our unit testing with a mock shopping cart object for teaching purpose, I'm going to go ahead and implement this shopping cart plugging. The way I implemented it is to utilize the local storage on the browser. So I'm going to go ahead and go under the plug-in folder. I'm gonna create another project, and this one will have to access the local storage. So it's not going to be a class library, the estate or in Cloud library, it's going to be the Razor class library. Razor class library provided me with the ability to access local storage by using JavaScript interop. So I'm going to go and do that. And here I'm going to go and select a plug-in folder as the footer. And I'm going to name this as E sharp shopping cart, just to make it make sense, right? And local storage, just to indicate what kind of implementation it is based on. And later you can, you can even change that to a database, write a shopping cart based on database. It makes sense in some cases, but shrub and car based on local storage makes sense too. And sometimes you need both implementations because, you know, some business need to know that what kind of product that customers are really interested in. So they need to have that as part of their big data solution. So they want to collect that data. So in our case, we're going to only implement the local storage. So I'm going to go ahead and do that. And then I'm going to click on Create. So it's under my plugins folder. And then here I'm going to delete this two files. I'm going to add a dependence because this is a plugin. So I have to reference the interface, the abstraction. So I'm going to go ahead and add a project reference to the use cases. And then I'm going to create a new class. And I'm going to call it a shopping cart. The shopping cart will have to implement the AI shopping cart interface. So I had a public and then implement the AI shopping cart interface. Okay, So hopped up and then I would have to do, you don't have to implement all of that. So I would say implements interface, then it will automatically generate this and not implemented. So it's all of them. But before we go ahead to do the rest, what we need to be able to access local storage, and that's where we need to be able to get in and save our order into the shopping cart, right? So for that, I will need to do dependency in jacked the JavaScript runtime into here, right? So I'm gonna do see toward. And then so this is constructor, constructor and I'm gonna dependency in Jack that. So you're going to be IGS runtime and I'm going to use import the interface. And I'm gonna say JS Runtime. And I'm going to initialize the field. So let's go ahead and implement the product, the first one, right? So our products, so we need to get an order. But before, actually, before we implemented any of this, Let's, let's implement the getting and setting the order into the local storage first. So it's going to be, going to be two helper functions. So we're going to be private. And then I'm going to get order, right? So it's because we're gonna be using JavaScript runtime. So it's going to be asynchronous call. So I'm going to have async task and then the order and call the get order. I'm going to have order. The initial eight is going to be like this. And then I'm going to use the JavaScript runtime to do, to get it. Initially. It's, It's a vein from the local storage. It's a string. So I'm going to call this and I'm going to call invoke. They sink and they're going to be returning a string. And then I'm gonna say, I'm gonna call what local storage dot get item. And what I'm going to go, I'm gonna got the shopping cart so I don't want to be misspellings. So I'm going to implement a C stream, so comes to string. And we're going to call it a shopping cart. And then I'm going to define this at the top. So I'm going to say private string. Then I'm going to say dot the shopping cart, right? So was this, I'm going to be able to use JavaScript interrupt to get the shopping cart value from this key, this E sharp dot shopping cart key, from the local storage. And once I have it, I need to make sure I truly habit. So if it's not now or whitespace, whitespace, then I'm going to use JSON, convert to, convert it to. So I'm going to control, control dot. I'm going to import Newton solved some little deserialize this into a order. Deserialize this into an order object. And then if it is empty, right? So if it is empty, then I'm going to create a new order. And then I'm going to actually save this order into it. We're going to call set. So this is going to save the order into local storage. Then we are going to return this order. And I'm going to implement this at order again here. I'm going to say set order this here, and this is going to be simple. This is going to be a weight JavaScript runtime in MOOC. Void. And I'm going to say local storage dot psi item is going to be the same key. See STR shopping cart and Jason convert dot serialized object. And I'm going to serialize the order 2 to string. So that's order. Hello in a sterilized our toString. So that's why I need a weight here. Once I got the order, it's going to have a long list of line items. And each line item will have the product ID in there, but it doesn't have the actual product. So for that, I will actually need to get all of the product object loaded as well. So, and I'm gonna say product equals product repository, which we don't have yet, but I'm going to dependency injector ain't right now. So I'm going to go up to the constructor and we're going to say I product or a ponds. And we're going to do Control dot. And then I'm going to import that and control data gain to initialize the field. And then I'm going to go down and then I'm going to say it got product. And then I say item dot. So I have this product ID, so I'm going to load the product from the repository and then I'm going to assign that to the item dot-product. All right, so I'm gonna save this. So this is our get and set. So let's go ahead and implement the functions here that the first one is product. To add product, we need to get the order first from the local storage, right? So we've got an order was the function that we just implemented. So we have that. And then we'll say Add order dot product. Remember we implemented this. So it will say product dot product ID go. Okay, so we have that. I don't like the product dot ID. I'm going to change this to product DD. And this may create some problems first, but I think it would be better this way. So let's implement this for now. And then we'll fix that problem later. So we have this product out price as well. And we're gonna say a weight set order was save it back to the local storage, and then we'll say return order. And here is complaining about not using the async keyword. So and that's good. Next one is going to be delete products. So when the product, when we click on the delete button, what we want to delete from the local storage. And for that, Qin, we will need to be the same type of logic. But instead of using ad, we're going to say Lu product and then we'll provide the product ID. Product ID is the parameter of the function, will provide that and use the async keyword. And that's it for delete and an empty, we want to be able to empty the MTD. The second card, you'll return. This does order and I'll just provide a null. And if I provide a null, it's going to actually stay in the same key. So if you go over here to the set order is going to stay. So this is actually not going to delete that. It's going to put the word N-U-L-L in the, in the local storage corresponding to this key, right? So the value is going to be N-U-L-L. So and that's not good and that's going to be creating the issue for us. And how do we resolve that issue? We're going to come over here and say, if this is not null, as well as if the street is not, it's not N-U-L-L, then we are going to go ahead and deserialize. So that's should solve the problem. And so we have that empty cart implemented, right? Empty the cart implemented. And next one is, I'm going to get the order. We're going to get the order. And that's a simple implementation. We're going to say var order goes, oh wait, I got to order. All right, and now we're going to return us are going to have to say, actually let's simplify that with just returning directly. And then we will need to do placing water. Actually, let's skip this and let's go ahead and do the update quantity as to update quantity. So this is a little bit complicated. We need to know first we need to add the ordered used the async keyword first about stop. So we'll stop yelling at me. So I'm going to say if quantity, if it's 0, then I'm gonna do anything. I'm just going to return the new order. Otherwise, I'm going to say if the quantity is 0, so that means I'm going to actually delete the product. So I'm going to directly tunneled to the product which we have just implemented and then providing the product ID. And if it's either, Sorry, It's got order. If it's either this or dot. So it's going to be, quantity is going to be greater than 0. Then in that case, we are going to first gather line item is a lion items that scene go, skiing go or the fault. So this is from the link extension method. So I'm going to import dot byte isn't controlled God, and as a product ID, product ID. And then, so now we have it and we have to check whether we actually have it or not. So clear if it's not, no, then we're going to say launch item.quantity. The quality passed in. And then we are going to save the wonderful begin by Colleen, set order. And that's it. And then I'm going to say return pointer. And that's that one. And we have the get order, we have set order. Let's see whether we have any scene missing here. Yeah, we have this update order thing. So and this one is going to be really simple. We're just going to say do a weight this. So unless save this into localStorage, then I'm just going to return this to order is the keyword that should implement our shopping cart, the audit, and make sure it compiles. 44. 5.6 Test Add Product to Cart Use Case: All right, so with all of that implemented, we should build a test. What we already have. So far. The only functionality we actually implemented as the add product to shopping cart use case. And let's test out. So I'm going to do Control F5 and see whether we are able to have that working. And it's showing me some errors. Yes. Remember we have changed the product change the ID to product IDs, so we have to we'll have to fix that. So I'll go ahead and fix that and they'll come back of the worst. All right, so the errors are fixed. I'm going to again press Alt Control F5 and trying to launch the browser. So we would need to go to products. We have. Let's choose this one. And it's giving us an error. And it will look at the era in the developer tool. We can see that we forgot to do the dependency injection in the startup dot CSS file. So let's go ahead and do that one. And it's going to start up. And they're configure services. This article into another use case, which is product to card use case. Reductive car to implementation. Start. Hopefully it's going to work and Control F5 again and again. And it's complaints about probably the shopping cart, we did it. So we'll have this loop a few times that the shopping cart is not going to be singleton. It's going to be scoped and wide sculpt because we don't if it's single tendon, everybody, all of the logging is or would be able to see that obviously for four, for shopping cart and you don't want everybody to see it. You only want to see your own shopping cart. You want to, you don't want to see other people who are shopping cart. So I'm going to say sculpt shopping cart. And the Skulpt is to scope to the current connection and was server-side with servers at blazer, the connection is your own session. It's the signal, our connection seminar channel dot. And then to control that important namespace. The shopping cart implementation. And the shopping cart implementation is the one that we just implemented. And we need to add that as a product reference. And it's going to be shopping cart. Local storage does project. So once we have that, we're going to go here important in namespaces. And I don't know why it's doing that. So let's see whether we believe it's right. So let's see. Shopping cart, local storage dot shopping cart. So I don't know why it doesn't recognize it. I don't want to use it here. I want to keep it clean and tidy. So I'm going to put a little bit here and oh, okay. So it's probably okay. So I guess it's probably has to have a shot and Carson, where else? Is it? Right here. Okay. And that's give it a try again. To refresh. Again, we're going to go and choose one of them and click on the See, we implemented that to cart button. And it looks pretty nice. And we're going to click on this to add the product to our shopping cart S and order, right? So we're gonna do this and it's good that it's going back to our product catalog, which is supposed to be under the root, but we haven't implemented that yet. But that's fine. What I wanna do now is to show you the shopping cart and there were local storage. So we're going to go to Application, go to local storage, open up on a C. This, we see this shopping cart. And then we're seeing this seekers serialize the whole order. Of course we don't have any of this information, customer information users. But we need to have is this line items. And that's exactly what we have, right? We have the price, we have the product ID, we have the quantity. So that's good. And we try to add another one. So we just choose another one. We add another one. And then he will look at the Lyon Homes again. We have two. So which means it's working. 45. 5.7 Improve Web UI: All right. Before we go ahead and do anything else, I want to fix the UI. We don't want them to have this home counter and fetch data today. I want to have a top bar, so I have it implemented here. So I implemented this top nav bar. And it's very, very simple. It's just these classes, Bootstrap classes. You can go to and look at the menu documentation and just copy one of them and you can modify it. In my case, I just wanted to have navbar was present when it's going to have a brand and spread just shows E sharp, navigates to the root. And I need to look it up to the main layout. Right now the main layout is using the lab manual, which is the sidebar, right? So I'm going to change that to the top navbar and should just work. And another thing is I want to go to my customer portal and their search product component. I want to have the page directive. I want to add a route to it so that we are able to navigate to it directly. So let's test where we have implemented 0, so it's completing its own index. So like I said before, you can have multiple rods, right? On a single component, but you cannot have the same rod on two different components. So let's go ahead and actually delete those toes pages. We don't need them anymore. So these pages don't actually need them anymore except para pages. Kid does permanently and DAS should fix our problem. Let's go back and see whether we can just refresh. All right, so we have that. Something's weird though. We have this left side still there. So we go back to our main layout file and we can see clearly the problem is, I put it, I put a top nav bar under the sidebar, which is absolutely wrong. So I'm gonna delete a sidebar so we don't have the sidebar. I can just put it right here. Sorry. I can just put it right here. The top bar. And then I would have my I don't need the about. I only need the body and thus should. Well, let's see. All right, so that works. Now the other thing is I don't want to have the product displayed this way. We go to Amazon or any other e-commerce website, you would see the product is played nicely. So i'm I want to have those pictures listed in a card. I'm going to take this tends to create a better experience because our research product currently uses a table to display it. So I don't want to use table, I want to use a list of card. So under a. So we just use the bootstrap row. And we should be able to implement a pretty good user interface that way. So let's go ahead and create a product card components, right? So this one is what I'm currently using product item component, which is just a table role. And when I got to do is I can create another reader component. I'm going to call it product. And up implementation right here. So the state, state parameter here, which is a product. And then we're going to display the product link. So this is the cart component in Bootstrap, which is very similar to the view product component. The view product component has more information. The product car component has less information. That's probably the only difference, right? So I'm going to have a link that goes to the real product component, right? So I'm going to have this. So as you can see, if we go to the View product component, we have this, the raw template like this, right? So here we are going, they're providing the name and spring the price. So this is, this is a product Carter component. And if we go to our search product, so instead of displaying all of this, I'm going to change it to be, to be different. So I'm going to actually delete this table to do this whole table. And then I'm going to say, so we have a list of products here, right? So I'm gonna say if products, it's not null, and then a product start count is greater than 0. That's when I display the list of cars, parked cars. Otherwise, I'm going to say and when I say text, just to make laser know that I'm not trying to put any C-sharp here, it's text. So I'm going to say no products. And while we have it, then loop through, we're looping through all of the product in products and product card components and protocol article born and to provide a current product. And that's it. Let's go ahead and take a look. Dead here. And that depth takes the role. So again in this class, role as a bootstrap class. And then let's see, let's run it. Actually, we already heard here. Let's refresh. Alright, so we have 100 products displayed in the Card View and it looks pretty good. And I hope I've researching functionality still works. It still works. And if you have time, you can actually implement into furnishings with the Enter key. So I don't have time to demonstrate that. So yeah, so that's everything I want to do before we go. How was the next was the next use case. 46. 5.8 View Shopping Cart Use Case: Now let's go ahead and implement the view shopping card use case. And we'll go to use cases. We don't have the shopping cart screen yet, so we'll create a shocking Karsh screen and then we'll add a view shopping car use case. So have shopping cart. And from here, we're basically just getting the order object from the shopping cart, which is we haven't implemented from localStorage, important namespace support namespace. Again, I'll just do a dependency injection and should be from I shopping cart and dependency injection. And here, control data again to use Visual Studio to help me to initialize the field. And then I'm just going to say returning got order async. So that's my use case. And now let's think about how to use this use case. Basically, we need to display the order and all of the information on the screen. 47. 5.9 View Shopping Cart Component: So for that we need to go to the models, the UN modulus, and then we go to under Customer Portal, it's supposed to be belong here. And then we're going to create another page component. It's going to be called troubling card component. And we will need to be able to navigate to this shopping card component by going to slash Cart. And here we're just going to call it a shopping cart, removing the component cart. So we can use this rod to come to this component. We're kind of a state. Do we need to warn you the order for sure. So that's basically everything we need because the shopping cart is implemented was local storage. And local storage, it's using JavaScript interrupt. And for blazer server side to use JavaScript interrupt, you cannot use it within our initialized because I'll initialize, it's triggered twice the first time when it triggers, it cannot do anything like JavaScript interrupt. It has to be used in after render for this. So that's why we're going to use up to render here. And then we're going to override, of course going to override on off to render. And it has to be asynchronous. Because we used asynchronous, we're not going to call it over and over. So that's why we're doing that here. And here we need to use the shopping cart, the shopping cart use case. And for that we need to dependency and jabbed into our component. I'm going to say I shopping card, use case, going back to the shopping cart, use case control, calmer shopping cart, use case around us. Just do this. Extract the interface, and that's good. And we'll create a border color interfaces. This and over this surprising here because we may have some other use cases and their shopping carts screen and going and bagging here. We're going to say shopping cart and use case. Yeah. I was even smiling. They're wrong last time. So yeah. Supposed to be w shopping card use case. Will we need to do here is we need to call the execute function to get the order. And because it's a available. So we're gonna we're gonna get the order here, but using a weight. And it's good that we need to say async so that we can use a weight. After that, we have to tell our screen to refresh. Because this is after render, it's already render. Even you assign a value to order, it won't display it. So you have to say status change, right? Because this is the state with all the components status change, then a will refresh the screen. I mean refractive component. So over the shopping cart page, I wanted to be like this, right? This is under and it basically displays a list of items that I've selected. Then on the right-hand side I have this kind of like an order summary, a component displayed like this. So I want to implement something like that. So let's go ahead and do that. So first I need a line break, and then I need a row. So this is again Bootstrap and I'm not gonna go too deep into this. So a role is a role. And the end there, the rows and columns and different columns can different size. You can specify the size as we saw from that page, we have two columns. One is on the left-hand side is display a list of products that you selected. So that one's supposed to be wider. So I'm going to give it six. So a mix that whiter. And the other one is there on the right-hand side. That one I'm going to make it not as wide. And I'm going to create a Order Summary component under here. And for this one, I'm going to use a list element. And then I'm going to have, Yeah, I'm going to loop through, loops through. We're going to use the for-loop instead of for each. And I'll tell you the reason later. So this then I do I plus, plus. And here I'm going to use, I'm going to create a line item component, right? And then each component will have a separation. And to implement that, I'm going to use, I'm just going to use the HR under a line item and the item, the list items, sorry, the list item has to be the mystyle has to be none. And I don't want this to show up. I don't want this HR to show up at the last, like after the last product. So I'm going to say if I is less than minus one. So this will provide a two from showing up after the last product. And now let's implement. So we have two product components, sorry, we have two components to show, right? One is here, which is the the line items, the other one is here. That's the order summary. And let's implement those two components. 48. 5.10 Order Line Item Component: Okay, so let's go to, go to our controls folder and then click Reserve component. And let's name it line item component. And we will not have anything less title here. And upstate is going to be actually the state has to be passed in, right? So it has to be a perimeter. And and then it's going to be a public property. Has to be ordered line item. And what are line items? And we'll just call it line item. And that's, that's our state. And now let's think about how we can display our state. And for that we will have to make sure, first of all, or a state is is there. Otherwise, it's going to throw exceptions. So it has to be there. I also wanted to double check that the product, as it's not null. And then it's going to be a list item, right? It's going to be yeah, it's going to be auto role of the list item. Within that. I'm going to again use columns. So columns within columns, which is nested. And that's allowed. I want it to be displayed right here on the left-hand side. So up to image link. And then I have another one. And this will contain the rest of the stuff. So I'm going to use it to display the name of the product, okay? And then I'm going to have a deaf contains the quantity. So I'm gonna say qualm about today, quite a t. I'm going to give it some spacing here. And I'm going to put an input field and think would fill will be a number. And the numbers minimum is supposed to be 0. And the value we are not going to bind was, was the like the line volume. We're not going to do this. Because if we do it, then we wouldn't have control over that change, like the onchange event handler. So there's couple of ways to go around them. I'm going to choose one of the way which is I'm going to manually bind this. So I'm going to do one-way data binding a year. And then I am going to depend only on change here. All right, So handle change. The other way to implement this is to go into this line item property and implement the center. So whenever the value changes is going to actually assign a new value to the property that you binds to. If, if you were to use the The byte value attribute. So that's that center is going to be triggered and you can do something there. But for, in our case, we are not using new state where directly using, sorry, we are not using ViewModel were directly using the model from the business layer, just so that we don't have to work too much for demonstration. So I'm not going to do anything within the business model. So I'm not gonna do that. And, and, and then after this, I'm going to have another place to display the price. And again, I'm going to have some spacing here. And then I'm going to say line item, dot product, price, and a toString to currency. And, and I think that's pretty good. Yeah, So here I also want to have a delete button, because the user can delete. The user can delete it in two ways. One way is to change quantity 200. The other way is to click on the Delete button using the light. And then to so that we don't highlight the Delete to encourage the user to not buying. So here we're going to say the product to the product. So remember, if you want to use any expressions or any expressions or any function calls, you gotta use this as psi and then parenthesis. In our case, we are going to have to call the function with a parameter. That's why we're doing an arrow function is like you in play there. You can't do Gilead product and then provide a parameter. It wouldn't work that way. So you would have to do this. And then here, you can provide the the product ID in order for you, for blazer to know what are you trying to delete. So I have this two and have to implement those for non not implementing. I'm just going to have to place holders. And so I'm gonna copy this over here and then I'm going to say void. And this was wildly product. And I'm going to do this, this, this. So it's going to be just empty. And here I need a product ID. Should make it stop complaining. Stopped complaining, right? So I think that's good enough. And then we can have other line items to be to be here. And I'll just delete this. No need to comment because because it'll be pretty obvious if we do this. And then our light item is going to be the current order line items and index here. And it 49. 5.11 Order Summary Component: The next one is we need to order summary component to show us the summary of the order. And I want to display how many items and a total price. So it's going to be a simple implementation of God that I'm going to go in here and I'm going to go under the control and create another razor component. And I'm going to call it order summary. And again, we need to think about, first of all, delete this. And when you think about what kind of state do we need? If we are displaying the price and the total count, then yeah, those are the stay. We need still going to have this and I'm going to initialize that to 0. And I'm going to have the items total price and initialized to 0. And thus also, we need a parameter to tell us what is the, what is the water we're dealing with? The depth parameter has to be public and just call it order, right? And, and that's our, that's our state. And so we need to use this order to calculate these numbers, right? So what we can do is we can again overwrite the perimeter site, perimeter set. And when we do that, we can, we can test our just do double, double. Just really make sure that the order is not know. So when it quarter is not know, then we can we can just say, you know, items count. It goes to order dot line, dot com, and then items, total price. That goes to 0. Because what we need to loop through the items too and see whether there is an easier way to do that. And see, Let's use link. So we're going to order dot land and stuff for IQ. And you're going to say Adams Toto, cause items total plus x-dot price times quantity, right? Because each line item can have multiple, multipole. You can order more than one product per line item. So that's should do and, and yeah, and then let's implement the HTML markup. And that's, again, it's going to be a card. Yeah. Because we have seen the page looks like a car. So again, we're going to use Bootstrap cart, cart. And I'm going to copy something that I've already implement here just to save time. So as you can see, I think I'm close properly. As you can see, I have this card here, It's cart blot body and then have Tidal order summary. Using the items column right here to show how many items are here are in the cart. And then the total price. And then the shipping and handling and estimated tax and everything is going to be hard-coded. I'm not implementing done. And order total is the total price. So yeah, it's, it's better than what you have seen in Amazon. So another thing is that within this order summary, we need to Place Order button. That's what's displayed. All happens on to. And for that we are going to have a button over here. And we're going to say the class is going to be, we're going to be this and onclick. Because a list order and just say place border. And I think what they say is place your order. And then I'm going to do the place holder right here and we'll implement later. I don't know why this indentation is wrong, like dot. And then I'm gonna say, you'll probably will place order. And that should do it. And then let's go back to our order summary place. And then I just say Order Summary component. And the border is our word order. Let's give it a test. I think. Importance, view, shopping cart, I mean, dependency injected. Otherwise they're going to fail again. So do I have that here? No, I don't. Services at transient. I use case. And then do this one here too. Let me do the code here. So the page is loaded. I'm going to add some product to the shopping cart. And then we are going to manually navigate to the shopping cart page. Okay, so we get some arrows and that's troubleshoot. So SS line 10 is null. So let's go to line 10. So line 10 on the Shopping Cart component is now so basically that water is null. So I think we need to add some condition Africa to this testing. So you need to make sure that order is not. No. And also the quarter line item is not known. Also, if you order line items, don't count is greater than 0, otherwise, there's no need to display anything. And you can choose to display in our message saying the cart is empty or the basket is empty. So putting that here, I'm not going to display that message. Just to save some time. I was studying there. Let's see whether we will be able to solve this problem. All right, so we have everything nicely displayed, have three items. We have place water, we have the order summary component. 50. 5.12 Shopping Cart State Management: So before we go any further of implementing the next use cases, we are going to England, a shopping cart component, I mean the card component that displays the number of items in the cart. Right. So it's usually on the top right corner as what's on Amazon. And as you're adding products to the shopping cart, you're going to see the items change. So for that, we need to use the knowledge that we learned from previous section where you have learned, you think the flux architecture to implement that subject and observer pattern. So in this lesson, Let's go how to implement a simpler version without the dispatcher. So that's going to be under the use cases. We need another plugging into pieces because it's going to be a plugin to, right? So that's state management is like the session state. If you have worked with an older technologies, session stayed can't be implemented within memory, within the database, within anywhere, right? So we are going to have a abstraction in the interface. So our use cases can use the interface uses abstraction. We're not blocked by any concrete implementations. So let's go ahead and create a folder and let's call it date instead of Datastore. And then within that folder we are going to create a interface. And let's call it, let's call it a steady store. And the store is going to contain three methods that I've showed you before that change listeners. So I'm gonna just going to just copy what I had before. So I'm going to copy this over. So this is the store, right? So this one is to register as a listener, and this removes the listener and this is the broadcast to all the listeners. And we'll have another one for another interface. And this one is specifically for the shopping cart. So I'm going to call it the shrub in-car state store. And the shopping carts they store will have to derive from the eye stay store. But it's going to have somebody new abstracting here, right? So we need to be able to guide the line items. And so this got like GOT lion has gone is to get the state, right. So this is the only state, but then it has to behavior. And that behavior is going to up the line items count. So we have this function for getting the items count. And then we'll have that update line and I'm secant to change the items gone. So if we have these, let's think about where we need to use this. We need to use this. Well, we, when we add the product to the shopping cart. So for that we need to go to the. The product screen, the view product screen. And we have this product to a cart use case. And here, when it executes, we need to do to say, Hey, the shopping cart state is changed. When either say that the light atoms can't have changed. Where are we going to do it? We're gonna do it right here, right? Before we do that, we need to dependency in Jack that in. So we don't care about what the implementation is. We are going to use abstraction. So I shopping cart, state store to control that, to import a namespace. And then we're going to use this, initialize it. And over here we can say shopping cart stays store dot, update line items. That can't. Because when we adding it to the shopping cart after these atoms can't actually teach. That's why we call it here, right? And where else do we, do we need to do this? We need to do it when we delete a line item. And that's going to be the shopping cart use case, which we haven't implemented yet. So let's just do it like this. And then we're going to implement the state store, the shopping carts they store in Africa that we need to go to the plugins folder. And over here, we need to create the plug-in project. And that implementation for the stay store is going to be because the state, we're not storing that stayed within anywhere. We are status storing this day within memory. And that's going to be dependency injection based, right? So if we're saying at sculpt, so that object is going to be held in memory. We're gonna take advantage of that feature to implement our stage door. So we are going to say right-click. So this is going to be a class library and less tender and click Next. And then here it's going to be and there are plugins. And we're going to call it state store. And this is a dependency injection based, right? So he's going to be memory. You're going to have to change the class name. And we're going to have to implement the state store base. And what are we going to do in this store base storage, they store base. So what we are implementing that I state store, this is going to be. So we have this and then I'm going to implement the interface. So we need to do this and we have to have another class, which is going to be, we're going to call it a shopping card, State Store, right? And this one is going to be implementing shopping cart store. And important that we are going to derive from this disk or base. Here we are implementing the interface, since we have already implemented in the other interfaces, stay store space so we don't need to implement those. Register and list, like removing listeners, adding listeners and broadcast messages, right? So we just need to implement them. So let's go ahead and implement this stays for a base. And basically here we're just saying, we just have the listeners held here. And we're saying this is our listeners. And then we're doing a lot of critique. So basically we're just saying this dollar less nervous plus listener and then removing same thing. This listeners minus listener. And I don't want to be here output over here. And then the broadcast stay change is going to be this dot listener. If it's not known. And listeners woke. So this is the implementation of that. And then we go back to shoving cars. They store in the shopping cart stays store is going to be when to implement their gut line items. And for that, we need to access the shopping cart itself. And for that we need to do the dependency injection first, where we can have the shopping cart shopping cart interface here. And I'm going to do Control DOD, use this shopping cart and then control that. And we do the initialization. I need to implement this, get line items count now. So first we got the right, so we'll get the shopping cart. The shopping cart got border, so we're going to get the order. Right. So once we have the order to test, if the order is not know and order line items, not know and order it online, I don't start code is greater than 0. Then returned ordered outline items dot count, just to be really safe, otherwise, we are going to return 0, update line items count. Well, basically this is simple. We're just going to broadcast a message to all of the listeners to tell them that, hey, this line items column has changed, right? So I'm going to call res.end broadcast state change. And this is our implementation of the state management system. And to use this, we are going to, because we have already, I think let's go to, let's double check. Let's go to our product to a cart usage. So we already using this, right? So we use those. We need to go to startup to do the dependency injection, which is going to be scoped because this is per user session, right? So it's going to be scoped. So I'm going to say passcode. And then we're going to say shopping cart, state. And then shopping cart, state, stay store. Because I think it's the store. And then we are going to use this reference to that implementation. So we have this dependency injected and we have already hook it up in the ad to product use case. And the next one is we need to implement the card component where we can display those information. 51. 5.13 Shopping Cart Items Count Component: Alright, so let's go to implement our card component that displays the number of line items while we are adding and removing products to the shopping cart. So go to custom portal because part of charisma portal, and we're going to add another component. And I'm just going to call it the card components. In the car component, we're just saying we're just displaying the number of items and the number of line items and the state is obviously B items. I'm going to initialize that to 0 and then again, have to override the after render instead of only initialize. Because the shoving card, the shrugging car in general as local startup. Although in this case a may not be completely true, but that's good. We have a habit of using the after rendering instead of uninitialized. And women need to do is to inject the eye shutting card. Stay store. And for that, I IntelliSense does not work. And I'm going to have to say, isn't dot, dot, use cases, use cases. Plugins. Thus they store. Go back. So let's go in here and then let's use this shopping cards they store. All right, so here we can just add this as a listener. And I'm going to say hadn't DO shopping cart state. And then we're gonna get this from the shopping carts. I'm going to call the get line items, go and get the state, right. And then I'll have to say state has changed. And why this is complaining, because the async keyword is missing. And then we're going to implement this handout shopping cars change lettered, and it's going to be private. And what it does is it's going to update our lie Adams, good. And we need to call shopping carts to cut the line and then it's current. And this is again, it's going to be async, await a pole. So we have to wait that the async keyword here. And once it's updated, or we're gonna say, say, state has changed. So as we know that there are four different conditions when the component is a re-rendered. So this is none of those four conditions. So we had to call the state has changed to refresh the component, reflect the change of the line items. All right, and last but not least, actually very important that we need to, we need to remove the component as a listener when he removed this method as the lesson. And for that we need to implement, we need to implement the ICT is opposable interface. So in here we're going to say implements this opposable. And then we're going to implement that interface right here. We're going to say public, void, dispose. So this is when the component is disposed. We actually I registered as listener. Otherwise, it's going to cause a memory leak. So otherwise this car component will never be released. And we collected by the garbage collector. Okay, So this is good enough. And then we're going to use this Shopping Cart component in the top navbar, right? So I'm gonna do Control comma and then top up. And then we go there. We wanted to display on the right-hand side, right? For that. And we're going to say nav item. So this is margin-left auto. So when we say margin left auto, it's going to, sorry, it's going to be on the right-hand side. And here we're going to display this as a navigation link. And so it's going to read link and go to where you go to cart. So when we click on it, we're going to see the shopping cart. And here we're going to do the shopping cart. So not going to import interface to save some time. And I think that's what we need here. If we try this. So we're gonna see how it looks like, right? So I'm wondering why is now showing 0 and it's not showing any number 0. That's because we didn't put the numbers here. So you're gonna have to say line items. And that's, that should fix our problem and go back here and refresh the screen. All right, so now we have our number displayed. And if we add more, product was probably already there. That's why it's not showing. So if we choose this one and we add to it, and so the car number becomes six. And if we do this again, it will be still six. Because this number, the quantity change. So next we need to work on the quality and delete. 52. 5.14 Delete Product and Update Quantity Use Cases: So next we need to implement the delete product from the shopping cart use case and also update the quantities in the shopping cart. Or need to go use cases and enter the shopping cart. And we need to have the lead product use case so that we create a class and I would call it the lead provider use case. And what do we need here? We need to use the shopping cart interface to delete the product from the shopping cart, and then it will return, we needed to return new order that doesn't contain that product. So we're going to have a method here. And then we're going to it returns a new order. And we need to provide the product ID or a namespace. And then here we need to use the shopping cart. So before he uses troubling go, we have to do the dependency injection, right? And that's going to be the shopping cart interface. And important namespace here. And we're just assists to control dark and do the initialization. And here we're just gonna say stop shopping cart, lead product. And there were provided Product ID. And this, again, this is going to give us a product, right? But that's available so we have to win it in order to get it. And so in that case, we'll turn those into as well. And then were important tasks, namespace. And then we're going to see the southern guys stay store, right? So because we're deleting so the state store how to sing or delight at Lyon EMS content. So for dad and when you do dependency injectors, shopping, cart, state, store, control, DOD namespace. And then here in this one, we're gonna initialize it. And after that I can just use notice I think probably has some ross spelling here. So it's going to be shutting card, stay store. And then I am going to call this update line atoms can't because the line items has just changed. And then I'm just going to return this order after I delete the product, again, need to add a sink here. And that should do it. So I have this delete, and so let's go over here and then right-click. Extract the interface. Still forget to do that. And this interferes and there's this folder. Don't prompt data again. And then I'll create another use case, which is to update the quantity. So I need to update a quantity for that will create another class, which will be called update quantity. Use case. And then here I'm going to say update quantity used. This one. We'll, we'll call the shopping cart update quantity method. And again, it's gonna return a new order that contains the updated quantity for the line item. So again, I will provide the ID and I will provide the quantity. Quantity. First, we need to import the namespaces. And I'm gonna say go wait, shopping cart. I forgot to do the independency injection again. So we're going to have the shopping cart and then neutralized. What else do we need? We also need shopping cart store. And so we're going to import our namespace as well. Initialize. And same thing here and do shopping cart dark, outdated quantity will have the product ID as well as the quantity purchased in time. Then we'll have the shopping cart stay store. And will say, yeah, we didn't implement anything. So this is not a line items. We would need to implement another interface here we would say another method here. We say void, update, quantity. If their product quality. We need to implement this in the shopping cart STA Store. So omega do a controlled Dart and then shopping cart, state store. And then I'm gonna go in here. And now it's screaming, I haven't implemented. So I'm going to press on those. And then I'm just gonna say, hey, I've changed. Things, have changed. I'm going to broadcast. The real way we need to do this is because when the quantity changes the item con me, That's why we need to do this. Because if we change to a quantity to 0, then the atoms can't continue. That's why we're doing this. Otherwise, we don't need to go back. And we are here and just call this update inequality lightly. So that works every single time. And again, that's because I did not add this async. And now it's good. And I need to go over here and extract the interface and just work. And I'm going to move this interface into here. 53. 5.15 Delete and Update on Order Line Item Component: All right, So in order to use that first we need to dependency in Jack that use cases. Copy this over here and say, I wanted to call delete product something to lead product use case. In this case. And then another one will update. After the quantity use case. Update quantity use case, good and good. So we have both dependency injected and now we need to go to our UI. Well, at this moment, I just wanted to talk about the architecture again. At this moment, our use cases already implemented. So we can start testing unit testing. We can provide the ID and quantity, and then we can also mark the, mark the state store, right? We can mark everything, and then we can test whether the order comes back correctly. And we can also test whether the state store has everything, we need it. But I'm not going to do that. I'm going to go directly to the customer portal and I'm going to implement the update. I mean, going to use the update quantity as well as the lead product in the shopping cart component, right? Because in a shopping cart component, actually the Shopping Cart component uses the line items component and the light Adams component, Ally Adams component, and this component tab. And they'll coordinate change as well as the products. So let's use is a delay product first. And then again, dependency in the eye. The lead product use case. And I didn't delete, update and give them nice names. So how do you know the the product? So execute this and we're going to provide the product ID and the line item. So basically deleting the product and then it will return back a new order, right? And then we have to order is in the parent component, which is the shopping cart computers. So we need to update that order. And how do we do that? This is a good place that we can use the event callback. And let's actually do implement both before we add the event callback that's handled quality change, right? So when we're actually last implement the event callback for. For telling the parent component that we have deleted and order as our we have deleted a product. Let's say product. And then there's a callback. And this would be an update quantity. So we implemented them. And then here we're just gonna say delete product anymore. Sink. Provide that order so that the parent component will receive that. Okay, so this is a async. Async await this. And this. I also have to say how we implement that. And this handle quantity d change. So this handle gonna do, like I said before, we're not using a regular data binding. All right. We're burning that manually. So this is a one-way door handle the yard away when the number of changes. So for that, we will have to provide a parameter here, which is the change event argument. Argument. And this, from this event our limit will have, will know whether the, whether we will have to say no. So if it's not now, and I mean, if it's null or empty space, we're going to return. And then I'm going to choose a quantity declared here. And I'm going to say F. Try to parse, parse that value to a string. And then I'm going to give it to the quantity. Quantity is less than 0, then we need to display an error message. But as that parser podo is going to be less than 0, yeah, it's probably possible unless you're using that spinner go up and down. So we have to distribute our message here. But before we do, we are going to say, okay, so if it's error, then we're going to return. And if it's not airing out, we are going to get the turn those into a single point and you use that update. In this case is up the quantity use kisses going to execute this. And we're going to provide the product ID, product ID. And then we'll provide that new quantity. And here we're going to say update quantity in woke, right? So this is a Event callback. And again with heart will give me a new order, right? So that's about it. We have implemented that. And in the use cases, we are able to Borneo to call the stay store to indicate potential stays store change. Right? So let's give that a try. All right, so let's see whether the Delete works or not. No, it's not working. And if we refresh oh, actually has worked. So whatever I do this and then I refresh and works too. So then what has gone wrong? So what has gone wrong? Because we didn't register they even call back. Yeah. So in the parent component, which is the Shopping Cart component, Shopping Cart component, we have N'T register that even callback. So the event callback, which is a dependency, IntelliSense, is very slow on that. So we have to go into it. I can't wait. It's going to be an update on the cell. Quantity and product. Here. I'm gonna say a 100 DO. And I believe now it's back. So in this update and in each one takes a parameter which gives us the sodium here on the product. We are just going to say this dark winter. And then because this is the band callback, so we don't need to say status changed. And again here we're going to update quantity, the quantity and returning a pointer. And then again, we're going to say this, that should work. Let's refresh our page. Well, first of all, let's observe whether the compilation has done. Okay, it's done and then we go back to refresh over pitch. That's pretty fast. So now let's delete and see whether it works. No, that works. Then our card, the number of items also change. Because we have brought a broadcast message. Right here. I'm gonna say, I'm gonna increase. And if we decrease to 0, let's see what happens. Yeah, that works. So we put 23. We have three, okay, so that's persistent, D, the numbers. And if we decrease to 0 and we delete it without warning message, all right. 54. 5.16 Order Repository: So next we are going to implement the Place Order use case. But before we do that, if we think about it, when we place orders, the orders need to be created. And we haven't implemented the data store or even the Datastore interface hasn't been implemented yet. So we need to do that first. So in this lesson we're going to create the data store for, for order. So we're going to the and their use cases and you're plugging into emphasis, we need to create the interface first, right? So we need to create a new interface. And that's call it I, what our repository. I wonder. Positive charge. And under here, we need whole bunch of matters to her low creation, the crowd options, as well as some other stuff, right? So to save some time, I'm going to copy the things that I've already done. And we're going to import a namespaces that salt everything. So we have got to wonder where I've got order by uniqueID this, if we're tracking this status, we obviously we have create. So we have read, read, create, update, and we don't have delete. We don't need to. We can use the update for marking the order as, as processed. And we're not implementing less soft the elite for discourse. And we have get orders to get all the orders and we have got all standing orders and process to wonder. So these are going to be full for future for them important. And then we have getline items by Order ID. And we are going to implement this right away. We're going to go to plugins. And this is going to be Ender hard coded. So we're going to implement the hard coded first, later, or we'll actually go to a real database. So we're going to a class and then we're going to implement it, report it. Plus. And this is going to reference the pointer that we're going to import dot. And then we are going to control that and say implement interface. So he didn't want to miss everything wore me. Again. What I'm gonna do is I'm going to copy what I've implemented just to save some time because you guys have already gone through the product one. So I don't want to do to have duplications. Duplication is bad. So I'm going to go over here. And it looks like we have some duplicate predicates here, right? So let's take a look. It's complaining about this. We need to import the namespace. And then let's take a look, right? So we have a dictionary of orders. And the reason why we have a dictionary is because I want to use the order ID as the index because this is a hard-coded. I wanted to be fast. So I want to use the order ID as the index and then the object is saved to that key and value as the order object. And then in the constructor, I'm just grading mainly creating a dictionary. So again, this is a hard-coded with sort of means. The heart related means that the products are hard-coded, right? But here it's basically in memory. And yeah, so Harcourt is probably a bad name, maybe is a better name. Anyways. So we're creating order, it's empty list and then create border. I'm just generating ID based on account. And then I'm generating a unique ID. And then I'm adding this to those collection of waters, the waters, I mean the addiction, new borders, providing the key and value. And then they get orders were just get the actual orders, all of the values. Right? I'll standing orders will actually filter it by the date process and got a process also filter by date process and get water will just provide the ID, will use the dictionary to get the order object. And the same thing is happening here where I think I can improve this by. It's hard to improve this because it's a dictionary. So I'm going to use for each and return the one that has the unique ID. And then we have this update order, which will find it order first, and then we would place it. And then we have the line items which, which I'm not implementing and the reversion or hard-coded version. So let me save all of that. So that's our implementation of the data store for up, for order. 55. 5.17 Place Order Use Case: All right, Next, we need to implement the place water use case so the user can actually place the order and byproduct. But one of the most important thing. So for doll, we go to our use cases and dark place water should be entered shopping cart. So we're going to create a new class and call it Place order. This order use case, and it's going to be public class. And here, what we need to do as we need, and we need the order to be passed in order to come to import the namespace. Next thing we need to do, we need to look at the order service. I want you to validate and for that we need to import water. So remember, we have implemented this is actually our core business rules. So we have implemented those validations. So we need to make sure that when we are placing order, we need to make sure that we're validating. And I'm going to validate create a border around it because we are creating an order. So we provide that water over here. And then we'll say if this is valid, all right, if the water is valid, we deal with the order. We first thing we need to do is we need to say no. They placed it given a date, go to date. And then we are going to give it a unique ID because we are going to use this ID. I'm going to actually return this ID to the user to use that, to track the status of the water, right? And then what we need to do is we need to use them in order repository to create an order. And for that we need to again go over here. And I ordered repository. So dot. So what happens now as if it's valid, then we're given that they placed a unique ID. Next, we need to call the the order repository to create a border and that it is stored right wherever that Datastore is. We're not giving the order ID. We're going to return the order ID. So we don't have the order and put it here. And then it's going to have to give us the order ID back, right? And then we are going to go back and delete this because I think it's wrong to have this unique ID generated within this function. Because eventually when we implement a database version, database is not going to generate this for us or a nicer we specify that, but I don't think we need to. We can just use C Sharp code, generate that. So we shouldn't rely on this function to keep us. In that case, we don't need the order ID. We can just turn, we can just use the unique ID to generate here. So we have this order and we create a water. And then next thing we need to do is introduce shopping cart. Oh, we need to clean the shopping cart, empty the shopping cart. So for that, we need to import a shopping cart. And then we can import a namespace and then initialize it. Go over here. You can say shopping cart dark, empty, right? And sorry. And this, we need to, again, we need to await this, refer it happens. And then we'll use the shrugging card. We'll also import. Because once we empty the line items number change trans. So we need to update the line items. We needed to tell the shopping cart stays store to update. So we need to import something. I mean, dependency in Jack, namespace initialization. And over here after we import, so we're not going to change this to a sink. And word. We are not just doing void. We're returning a unique ID so that we can provide to the user to guide the status of the current order or, or get everything or the current order. So, so here I'm going to say shopping cart, state store, dot, update, line, Adam's count. And then over here we're just going to return the order dog uniqueID. And if this is not a valid order, we're not actually doing the validation properly because there's this should give us information about what's wrong. To re now I'm just returning null for everything. For production environment, of course, we need to do better job. So we have this implemented and we need to create interface, do that. And then I'm going to drag this into the interfaces. So we have this order use case, and I'll place what are use cases implemented. And again, to use it, we're going to go to our startup class and we are implementing, adding right here, do the dependency injection. And what we need to, as I place order, use case and business Place Order, use case. Good. And thus Place Order button supposed to be on that shopping car screen just below the order summary. So let's go to order somebody Control comma order summary, right? And we'll go to the order summary component. And then here is the Place Order. So we have a placeholder please order function that is empty, which is a place holder and the Place Order placeholder function. All we need to do is to navigate to the Place Order screen where we need to collect the information. I mean the customer information about the name and address and never take in order to make the payment. Right. But we're not going to movement the plate making payment, but we do need to navigate to the place order page component. We're going to inject a navigation manager. And then we're going to use the navigation manager to navigate to the place order component. 56. 5.18 Place Order Component: All right, So let's continue as you implement the police water component, where it should belong to customer portal and then it should be a page component. So we are going to create a razor component right here, and we're going to call it Place plays water component, order component, and the place where a component will be collecting the user information. So we are going to call it placing order, placing order. So placing order, we will have a line break here and the state will be at least the water. So how the order here, I have to wonder if not now, then we'll have a rope. And then we'll have two columns, two columns in the first column, World War, collect the customer information, right? So in here I'm going to collect the customer information. And in here, we are going to display the summary just for the user to view. And that's initialize the state, which we are going to pick in, override the chapter, render async like this, and make sure it's the first time. I didn't wanna do it over and over again. So we're going to elite. So for that we need to have got pacing. So we're going to await shopping card use case. So again, we're going to use the shopping cart use case for this purpose. So we're going to enact the shopping cart use case. So we have this information, we can use this use case to get the order. And then we can say state as teams. And then, and then we need to implement this collect customer information component, which is going to be a edit form. For an adult form to work, we need a view model. I don't want to directly use the automotive because that's not really appropriate. So I'm going to create a V01 mono folder. And then under here, I'm going to create a customer view model. And I will copy what I have. Turned this into a public class. And then here I'm gonna gonna give. So we need to collect the customer name, address, city, state, province, and country. I'm looking at him. Postal code or ZIP code. So I don't have that. And for demonstration purpose, I think it's okay to not having done. So I'm going to import the namespace. So we're going to use the annotations to Edit Form knows what is the requirement is not required. What is the, how to validate the model? So ViewModel. Next we're going to go into our control and we're going to create the customer form component, right? So it kind of collecting the customer information. So we're going to call it Customer form, component form. And before we do that, I think this placing order thing when a page directive just realized, they call it plays wonder and save, gleam back to the customer form components and we're going to call it. So this is not a page component, right? So this is a reusable component. It's a non page component and a state of doubt. It's going to be a customer of your customer and forgot to. I'm going to import the view mono is namespace and then going bug supposed to be valid now. So we need to initialize this. So if it doesn't, then we need to make sure that we need to create a new one. So when they say allies, and here say customer. Okay, So and over here, the hips, we need to implement the edit form. And before we implement out, if we need to make sure we have the customer, otherwise they're going to fail. And again, I'm going to copy what I really just to save some time. So turmeric, customer can note and put the forgotten. So if customer is not null, then run this. So I have this adult form. The motto is the customer. And so when it's valid, then we know that bothers some credit. And then we have this good annotation validator and the validation some rain display here. And then we have the feud, right? And data bind to the customer, each one of the feuding customer. And then we're using the Bootstrap classes to style the form. And at the end we have this Place Order button here, type I submit a when this summits and when the valid information about many formation that is valid. We're going to call the vomit some minute method, which will implement right here. We're going to say it's a product. And if it's valid, then we will pass the information back to our replacing order component, please order component. And for that we will need a public perimeter. Is going to be a callback. Done this a few times. So there were any event Kovach and provide the color order, customer view mono block. And then we'll say customer beautiful, submit it. And then here we're just going to trigger dot, dot and providing the customer. All right, so now we have that, we go back to our replaceable plays a water component. We're going to use that. The customer form completed. And then we're going to have on customer info submitted. And this is on bottom. And here we're just going to say a no handle customer. So copy this and we are going to implement this function. The word cloud, the customer mono input here, here's the thing. We have, the customer model. We need to map it to the order. So let's use the auto member. So we are going to go to the NuGet package and then we'll automized wrong to me, bold garden. And then I say, okay, alright, so we have that. And there's different versions of mapping. One of them is to map to existing object. And we're going to say map. Remember configuration, configure it. Create a map between the customer and the customer model. Because border, because the order has those customer information and it's a function. And then we are going to call create mapper. So we have a mapper and then in order to map to existing order, because we haven't existing order, we cannot create a new order. So we're gonna say member dot map and then we need to provide, so this is a new right. So this one, assume mapping from source to destination. This one as two existing designation. So we need to do to provide this type and existing type. And then we can say customer, and then we're going to map it to existing order, right? So that should work. So we collecting the, we ar