Blazor WebAssembly & Web API on .NET 6 – Full Course (C#)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
blazer web assembly is a single page app framework for building interactive client-side web apps with net it uses open web standards without plug-ins or recompiling code into other languages this course will teach you how to use blazer web assembly and web api on.net 6. you will learn step by step how to build a shopping cart application this course also provides a guide on how to integrate a payment gateway into your blazer webassembly component so that a user is able to pay for products through your application using a debit or credit card or even a paypal account gavin lawn teaches this course gavin is a senior software engineer with over 20 years of experience i encourage you to leave a comment with the most interesting thing you learn for the benefit of other campers who are watching this course please join me as we build a very basic shopping cart application using blazer webassembly a few of the significant technologies we'll use for building our application are as follows the latest version of visual studio which is visual studio 2022 and we'll use the community edition for windows dot net 6 which is at the time of creating this video the latest version of dot net it was released in november of 2021 sql server 2019 laser web assembly we'll use bootstrap version 5 for layout and styling purposes we'll build a restful mvc web api project for handling database related functionality and returning relevant data from the server to our client side blazer application all technologies used for the development of this application can be downloaded free of charge please see below in the description the locations of where you are able to download the relevant technologies for free we are going to integrate a payment gateway powered by paypal into our application so that a user can use their paypal account or a valid debit or credit card to pay for the items that are purchased through our online shopping cart application blazer is a relatively new feature of asp.net it offers two hosting models a server-side hosting model and a client-side hosting model we are going to use the client-side hosting model for the development of our shopping cart application the significance of this hosting model is that the c-sharp code runs directly within our browsers what makes this possible is a technology named webassembly in recent years the creation of spa applications or single page applications have become very popular as web solutions up until fairly recently javascript frameworks like angular or react have been the available choices for the creation of spa applications with blazer we are now able to create our single page applications using c-sharp we don't necessarily need to depend on javascript for the creation of our interactive ui code we can create this code using c-sharp in this application however the payment gateway provided by paypal is coded in javascript so we will use blaze's interoperability functionality with javascript to interact with the relevant javascript paypal code so let's get started let's create our blazer solution let's fire up visual studio 2022 select create new project let's choose the appropriate project template blazer webassembly app let's name our solution shop online solution let's name the blazer project shoponline.web great let's add a new project to our solution where we'll create our restful web api functionality so let's ensure that we choose the correct project template let's name our project shoponline.api notice that for the authentication type we are choosing none we are not going to implement membership functionality which of course includes login and registration functionality we'll focus purely on the shopping cart functionality we want to run our application on the latest version of.net.net 6. note that we have enabled open api support by doing this the swashbuckle nuget package will be automatically installed and the appropriate swagger middleware will be automatically configured appropriately within our project one of the advantages of this is when we run our web api project interactively we'll be able to test our web api code through our browsers even before we have developed any front-end code so a basic ui will automatically be created for this purpose for us when we run our application interactively we'll be able to test each of our action methods through the relevant automatically created web-based ui note that you can also use a tool like postman to test your web api functionality i won't be using postman during the development of this application we are going to build our database using codefirst migrations and entity framework core migrations allow us to evolve our database without losing data or database objects so by using plain old c-sharp classes we can build the database entities that we wish to include within our shopping cart application once we have created relevant related c-sharp classes we'll look at an entity relationship diagram that represents our shopping cart applications database design let's add a folder named entities to our project this is where the classes that will represent our database entities will reside so let's create a class named cart to represent the cart entity so let's add two public properties to this class id as integer and user id as integer let's add a new class named cart item this entity represents an item that has been added to the user's shopping cart so let's add an integer property named id let's add an integer property named cart id this property represents a foreign key field and is used to join the cart entity to the cart item entity so the cart entity has a one-to-many relationship with the cart item entity this denotes that many card items can be included within one particular shopping cart let's include an integer property named product id lastly let's include an integer property named qty representing the quantity or number of a particular product that may be included within a particular shopping cart let's create a new class representing the product entity the product entity will have a one-to-many relationship with the cart item entity this denotes that a product can be included many times across many different shopping carts let's add an integer property named id let's add a string property named name let's add a string property named description let's add a string property named image url let's create a property of type decimal named price let's create a property of type integer named qty lastly let's add a property of type integer named category id the categoryid property represents a foreign key from the product category entity the code for which we are about to implement so let's create a class named product category this entity has a one-to-many relationship with the product entity let's add a public property named id note that when a property is named id by convention entity framework core will designate the id property as representative of the relevant entity's primary key let's add a property of type string and name this property name and lastly let's create a class to represent our user entity which of course represents a user of our application note that i've included this entity as a temporary substitute for a membership facility like for example microsoft identity so that we can focus on the shopping cart workflows and not be distracted by the membership functionality so let's add an integer property named id let's add a string property named username so if we look at this entity relationship diagram we can see the relationships between our entities the cart entity has a one-to-many relationship with the cart item entity the product entity has a one-to-many relationship with the card item entity the product category entity has a one-to-many relationship with the product entity the user entity has a one-to-one relationship with the cart entity so this basically means each user can only have one shopping cart within our application if you look at the sql server management studio that is installed on my local machine you can see that i've already generated a database through ef core this was done when i was developing the prototype for this application so we are now going to use efcor to generate a database for our shopping cart application the classes that we have just created representing our entities will be used by ef core to generate the corresponding database tables within a database that ef core will create for us in order to generate our database with the relevant tables through visual studio let's install two nuget packages to do this right click the dependencies node within our shoponline.api project click the manage new get packages menu item click the browse tab on the new get package manager dialog let's search for entity framework core dot sql server and this is the package we want to install let's click the install button then the i accept button great let's search for the second package that we need to install the reason we are installing this package is because we want to run our migrations from within visual studio as opposed to using the.net cli for this purpose note that you would use different commands when running migration commands using the.net cli as opposed to the commands you would run when using visual studio so let's search for entity framework call dot tools and this is the package we want let's install the microsoft dot entity framework core dot tools nuget package the next step is we must configure a connection string in order to connect our application with the database that we wish to create using entity framework core code first migrations so let's open the appsettings.json file within our shoponline.web project within the connection string that i'm configuring here i'm including my server name which is gavin lon's pc the database which i wish to name shop online and we are going to use a trusted connection to connect our shopping cart applications web api to our database so let's include trusted underscore connection equals true within our connection string note that i have named my connection string shop online connection let's create our database context class let's first create a folder named data within our shoponline.api project let's add a class named shoponlinedb context to our new data folder so in order to make this class represent our ef core database context we need to implement code so that our shop online db context class inherits from ef course db context class you can see there's a red squiggly line under db context this is because we haven't yet brought in the microsoft dot entity framework call namespace an easy way to include the appropriate using directive through visual studio is to press control period and then select the appropriate menu item from the menu that is presented to us through visual studio let's create the constructor for our shop online dbcontext class we must add a parameter to the constructor that we have just generated the parameter is named options and is of the generic type db context options which has the data type shop online db context passed as an argument to it we can then write code to pass the argument that will be passed to our shop online db context class constructor to the base class from which it inherits i.e the db context class now because i want to focus on the shopping cart workflows at this stage and don't want us to be distracted by the implementation of administrative crowd operation functionality we are going to seed our database with certain data this is data that i've already prepared so we are not going to include create read update and delete functionality regarding the creation and maintenance of product data at this stage we are going to seed our database with product related data we are going to seed our database with the relevant data so that we can move directly to the creation of our shopping cart functionality so in order to seed the database appropriately we can override a method that exists within the db context base class this method is named on model creating an easy way to generate the relevant override code for this method through visual studio is to type in the word override and then press the spacebar we can then select the on model creating item from the drop-down list presented to us within visual studio i have already prepared the code for seeding our database and this code can be found at this location on github so let's go to the appropriate github location and copy this code to our clipboards let's then paste the code from our clipboards into the on model creating method the next step is to let entity framework core know as it were about our entities so we can do this by using the entity framework call dbset generic type so for each of our entities we need to appropriately include a public property of type db set within our shop online dbcontext class to register our shop online db context class for dependency injection let's open the relevantprogram.cs file then we can simply add this code here to register our shop online dbcontext class for dependency injection note that our code is reading the connection string that we configured in the app settings.json file we are now ready to generate a migration using ef core so let's launch the new get package console manager window from within visual studio like this we can then type the appropriate command to generate a migration so let's type in add dash migration followed by the name of the migration we wish to create so when i run the add dash migration command i get an exception i've found out that this exception occurred because at present the shoponline.web project is set to my startup project within the relevant solution so if you get this exception all you need to do to fix this is make the shoponline.api project your startup project like this so let's try again and now we don't get the exception and it works as expected and you can see code within the up method of the migration class that we have just generated this code creates our database and the relevant tables this method also contains code that seeds the relevant database tables with the data that i prepared prior to creating this video the down method contains code to undo the changes made by code contained within the up method to run our migration all we need to do is type the update database command within the new get package manager console window like this and then of course press enter and now if we look at sql server management studio we can see that the shop online database has been created the database tables have been appropriately created based on the entities we created using c-sharp classes the relevant database tables have been seeded with the data created from the code we included within the on model creating method which resides within the shop online db context class the data with which we have seeded our database contains product and user information this has been done so that we can focus on the shopping cart functionality and not worry at this stage about implementing code or create read update and delete functionality regarding products sold by our fictional online store here are just a few notes about running migrations please note that if you have run a migration or more than one migration and are not happy with the changes made to the database you can undo the changes made by running this command update dash database followed by a zero the number zero is a special case that means before the first migration and causes the effects of all migrations to be rolled back you may wish to remove the migrations after this you can remove a migration that has not yet been used to update the database by running the command remove dash migration the remove dash migration command will remove the last migration that has not yet run note that if for example you have updated the database with multiple migrations and you wish to roll back the changes to before a particular migration was run you can roll back your changes to that particular state by running the migration that was run directly before the migrations that were run that contain the changes you wish to roll back this is the second part in a series of videos dedicated to building a shopping cart application using blazer and a restful web api in this video we are going to start with the workflow that involves retrieving product data from our database and returning the data to the client blazer component the code for this functionality will be implemented within a web api component so in this tutorial we'll start to develop our web api component before we do this let's create the classes that represent the data that will be passed between the web api component and the blazer component you might be thinking but we have already created the classes to represent the data for our application for example product product category cart cart item etc yes we did create these classes that represent our entities in the previous part of this video series these entity classes directly map to the database tables that were generated when we ran the relevant migration the function of these classes can be seen as blueprints for their corresponding database tables when we pass data between the web api component and the blazer component we don't necessarily want to pass the exact data defined by the properties in the classes that represent the database entities for example in this tutorial we are going to create code that returns the product data from the web api component to the blazer component the product class contains certain product related properties one of which is the category id a particular category id value could for example denote that a particular product falls under the electronics category and could for example be a laptop or for example the product could fall under the furniture category and could be for example a couch the category id property within the product entity is a foreign key from the product category entity from a human perspective the category id property does not have much meaning because it contains a numeric value so it wouldn't for example make much sense to display the category id to the user we may want to pass the relevant category name in addition to the product information defined in the product class so to facilitate this we can create a new model that contains all the relevant products data as well as the relevant category name which is included in the product category entity and not the product entity so it makes sense to create a new model to represent the data that in this case we wish to pass from server to client we need a model that includes all the product information as well as the category name the type of model i am referring to is known as a dto or data transfer object this type of model includes the data that needs to be passed between server and client so a dto is an object that defines how the data will be sent over the network the classes that represent our entities that we created in the first tutorial directly map to their corresponding database tables these classes represent the structure of certain tables in our database we can create dtos data transfer objects that are based on the underlying entity classes but may be differently shaped based on the data that needs to be passed between client and server we are going to create a standard library project to house our dtos so let's create a new project within our solution let's select the appropriate class library project template let's name our new project shoponline.models let's delete the default class generated for us by visual studio let's create a folder named dtos so let's create the dtos that we are going to use in our application now the only dto that we are interested in at the moment will be named product dto but let's create the other dto classes that will be used later on in the development of our application as well as the products dto class the dto classes will be explained in more detail at appropriate points during the development of our application let's create a class named cart item dto let's make sure our new class contains the public access modifier let's create the properties for the cart item dto class id as integer product id as integer cart id as integer product name as string product description as string product image url as string price as decimal total price as decimal and qty as integer let's create a new class named cart item to add dto let's ensure that our new class contains the public access modifier so cart id as integer product id as integer and qty as integer let's create a new class named cart item qty update dto let's ensure that our new class contains the public access modifier cart item id as integer qty as integer let's create a class named product dto this is the dto that we are going to use in this tutorial let's ensure that our new class contains the public access modifier id as integer name as string description as string image url as string price as decimal qty as integer category id as integer and category name as string great so we have created the classes that represent our dtos data transfer objects let's go to our shop online.api project so we are now going to start coding the logic for our first workflow starting with the web api component this workflow simply involves retrieving product data from our database and returning the data to the client blazer application the blazer application will contain code that displays the relevant product data to the user so now our shop online db context class has been registered for dependency injection we'll see in a bit how we are able to implement code to ensure that an object of type shop online db context is injected into relevant classes we are going to use the repository design pattern to abstract our data handling layer repositories are classes or components that encapsulate the logic required to access data sources we can use repositories to centralize common data access functionality which has the benefit of facilitating better maintainability easier unit testing extensibility and cleaner code the best way to understand the repository pattern is to implement the relevant code so let's write the code for our product repository functionality so let's create a folder named repositories within the repositories folder let's create a folder named contracts within the contracts folder let's create an interface named i product repository let's create four method definitions within our new interface we want all these methods to run asynchronously so all the method definitions within this interface will return generic task objects our first method is named getitems and returns an i enumerable collection of type product so the i enumerable collection is passed as a type argument to the task object as discussed this is so the method that implements this method definition can run asynchronously the other methods follow a similar pattern let's define the method definition for a method named get categories let's define a method definition for a method named get item which contains a parameter of type integer named id let's define a method definition for a method named get category which contains a parameter of type integer named id so we have defined the interface that we want a class named product repository to implement so let's create a class directly within the repositories directory named product repository and the first thing we need to do is write the code to implement the i product repository interface so let's do that we can see a red squiggly line under i product repository this is because we need to bring in the shoponline.api.repositories.contracts namespace a quick way to do this is press ctrl period and then select the appropriate item from a list provided by visual studio like this the red squiggly line is still there this is because visual studio is telling us as it were that we need to implement code for all the method definitions that we have defined within the i product repository interface so let's press ctrl period once again and select the appropriate item from the list presented to us and visual studio generates the relevant code stubs for us so visual studio generates default implementations for the relevant method definitions so at this stage we only want to implement the code logic relevant to the workflow that is the focus of this video i.e returning a collection of product data to the client side calling code in this case our blazer component we are going to need to use the shop online db context object to interact with our shop online database as you will recall earlier we registered the shop online db context object for dependency injection this means that we are able to gain access to an object of type shop online db context by defining an appropriate parameterized constructor in our product repository class so let's create the code for this an easy way to automatically generate a constructor within visual studio is type ctor and then press the tab key twice like this then in order to indicate to.net that we want an object of type shop online db context to be injected into this constructor all we need to do is define a parameter within our constructor of type shop online db context like this let's bring in the appropriate namespace and we can get visual studio to create an appropriate private read-only member variable to reference our shop online db context object by pressing control period and selecting the appropriate item from the list presented to us by visual studio great so for the workflow that is the focus of this tutorial we only need to implement code for two of the method definitions within the i product repository interface so at this point we are only going to implement code for the get items method and the get categories method so let's implement code for the get items method all we want this method to do is return all the products from the products table so let's write the code for this note we want our code to run asynchronously so we must include the await keyword here notice how once we have typed in the await keyword that the async keyword automatically appears in the method definition for the get items method if you include the await keyword within a method the method in which you include the await keyword must appropriately contain the async keyword note that to include the to list async extension method here in our code we must bring in the microsoft.entity framework core namespace and that's it we have written the code to return an i enumerable collection of products data from our database so let's implement the code to return the product categories from our database we can do this by implementing the appropriate code within our get categories method like this great so we have now implemented the code for retrieving product data from our database the next step is to write code to return the appropriate data to the calling client so to do this we need to create an appropriate controller class before we create our controller class let's delete these classes that were generated by default when we first created our web api project these classes are obviously not going to be used in our application so now let's create a class within our controllers directory let's ensure that we select the appropriate controller class template let's name this class product controller so the first thing to do is to write the code so that an object of type product repository is automatically injected into our controller classes constructor via dependency injection let's also ensure that we have a read-only private field that references the object passed in via dependency injection but we haven't yet registered our product repository class for dependency injection so let's write the code for this let's open the program.cs file let's implement the code to register the product repository class with the dependency injection system notice how we use the add scoped method to register our product repository class for dependency injection we could have used the add transient method or the add singleton method to register our product repository class with the dependency injection system but in our case add scoped is the appropriate method for this purpose very basically using add transient would mean that a new instance of the relevant object is provided to every class that requires the relevant object to be injected using add singleton would mean that the same instance of the object is injected into the relevant classes for every http request using add scoped means that the same instance of the object is injected into relevant classes within a particular http request note that in this case a new instance of the relevant object will be created for each http request let's create a method definition for an action method named get items we want our action method to run asynchronously the type that is passed to the generic task object is of the generic action result type one of the core benefits of returning an action result is that as well as returning the requested data from an action method to the client an appropriate response status code can also be returned for example a http status code of 200 means the request has succeeded a status code of 404 represents that a resource could not be found and a http status code of 500 represents that an internal server error occurred so we need to pass the type of data that we wish to return to the client as a type argument to the action result generic type so we want to return an i enumerable collection of type product dto to the client so the first thing we need to do is create a project reference to the shop online dot models project because this is where our product dto class resides then let's bring in the shoponline.models.dtos namespace great let's name our action method get items each action method in our controller must map to a particular http verb for example get post push delete etc our get items action method will be used for getting product data and returning that product data to the client so the appropriate http verb for this action method is get so to indicate this to dot net we need to decorate our get items action method with the http get attribute so let's implement the code logic for our get items action method let's first create a try catch block an easy way to do this in visual studio is to type in try followed by pressing the tab key twice so let's write code that calls the product repository classes get items method asynchronously to return an i enumerable collection of type product to our action method we want to include the category name associated with each product in our collection so let's write code to return a collection of product category objects to our action method we'll write the code that joins our collection of products with our collection of product categories in a bit so you may have spotted that the code in this action method is not ideal at the moment it is not ideal because we are retrieving a collection of products and a collection of categories in two separate queries to the database a more performant way for retrieving the product collection and related category data would be to appropriately use the include extension method within the relevant link query in the get items method within the product repository class the use of the include method would join the data retrieved from the products database table with related data retrieved from the product categories database table and allow for the products data and related category data to be returned through one query i'm going to leave the code as it is for now we'll optimize this code for performance by using the include extension method as i've just described toward the end of the course so if either the products variable is null or the product categories variable is null let's return a status code of not found to the calling client code so in this case our web api will return a http status code of 404 meaning that relevant data was not found or a relevant resource was not found so in this case it means that the client request failed and the reason for the failure is that an essential resource could not be found else we want to join the collection of product categories with the collection of products so that we can return a collection of product dtos to the calling client code which will include the category name remember the product dto definition contains a category name property in order to get the category name for each product in the collection we need to join the collection of type product to the collection of type product category we are going to use link for this purpose in order to avoid creating too many lines of code within our action method we are going to create an extension method to return a collection type of product dto to our action method so let's create a folder named extensions let's create a class within our extensions folder named dto conversions note that in order to create an extension method we need the class that houses our extension methods to be static let's create our extension method so the extension method must be a static method and we want to return an ienumerable collection of objects of type product dto to the calling code let's name our method convert to dto the first parameter in an extension method must be the type of an object on which we want to be able to call the convert dto extension method so by convention this parameter definition must also be preceded by this keyword so on an ienumerable collection of type product we want to be able to call the convert to dto method in order to convert an ienumerable collection of type product to an ienumerable collection of type product dto the logic for this method will using a link query join a collection of type product to a collection of type product category and return a collection of type product dto to the calling code so the second parameter of the convert to dto method is of a type that is an ienumerable collection of type product category let's write the logic for our extension method so let's write a link query that joins the collection of type product to the collection of type product category and return a collection of type product dto great so let's go back to the product controller class and finish the code for the get items action method so in order for the convert to dto method to be accessible on the products variable we must of course bring in the shoponline.api.extension's namespace then let's pass in the product categories variable as an argument to the convert to dto extension method then we can return a http status code of 200 to the calling code we can do this by returning the results of an ok method which accepts an argument of a collection of type product dto so this code returns a http status code of 200 as well as a collection of type product dto to the calling client code so if for some reason an exception occurs during the running of the relevant server side code in this case we want our code to return a http status code of 500 to the calling client code coupled with an appropriate error message let's keep the error message simple great so if we open our program.cs file you can see the configuration code here related to swagger and swagger ui swagger is an interface description language for describing restful apis expressed using json the configuration relevant to swagger ui here means that our web api project is equipped with a basic web-based user interface where we can see relevant information regarding our controllers and action methods we are also able to use the swagger user interface to test and debug our action methods when we run our web api code interactively through visual studio so let's run our code to see this in action and here we are presented with the swagger ui let's test our get items action method we can do this through our swagger user interface like this excellent in the next part of this video series we'll write the calling client code that calls the action method that we have written in this tutorial from our blazer component we'll also write the code to appropriately display the products returned from our web api component to the user so in the next tutorial we'll start to develop our blazer webassembly component so this is the third part of a video series where we are building a shopping cart application using blazer web assembly and web api we are building our application on.net 6 which at the time of writing this video is the latest version of net we are now at a stage where we have built our database using entity framework core code first migrations and have started implementing code for the first workflow which simply involves retrieving products data from our database and displaying this product's data to the user in part 2 the previous part of this video series we implemented the code that retrieves the relevant product data from our database and returns the data to the calling client this code was implemented in an action method within a controller class named product controller this class was created within our shoponline.api project which contains the code for our web api component in this video we want to start developing the code for our client-side blazer component so in this video we'll implement code within our blazer component to call the action method that we developed in the previous part of this video series and display the returned data to the user so let's get started the first thing we need to do is copy the url to our clipboards which is the url of our web api component when we run the shoponline.api project through visual studio we are doing this so that we can appropriately configure our blazer component to point to the appropriate local web api url so that we can easily test our application through visual studio during the development phase of our shopping cart application one way we can access the relevant url is to simply run our web api project so let's copy this part of the url which we can refer to as the base url or base address to our clipboards then let's open the program.cs class within our shoponline.web component so here is a block of code that was automatically included within our shoponline.web component whereby the http client object is configured for dependency injection this means that we will automatically have access to a http client object from appropriately written classes within our blazer component we will be using the http client object to call relevant action methods within our web api component so in order for our http client component to point to the web api component on our local machines we need to replace the argument that is currently being passed to the uri constructor here with the base url that we have just copied to our clipboards so let's appropriately paste the base url copied to our clipboards here great so we are going to wrap the functionality that handles calls to our web api component within services these services are simply c-sharp classes that wrap the functionality for handling interactions with our web api component so the first thing to do is create a folder named services then within the services folder let's create a folder named contracts let's create an interface named i product service within the contracts folder so we'll build up the methods for the product service class over time when appropriate during the development of our application we are just going to implement code for one method in this video so let's create a method definition for our method in the i product service file we want our method to run asynchronously so our method will return a task object in this case we are going to write code to return a generic task object because this method must return a value to the calling code the type of value that we want to return to calling code is an ienumerable collection of objects of type product dto let's name this method get items in a bit we'll implement code for this method to retrieve relevant product data from the appropriate action method that resides within our web api component we have a red squiggly line under product dto the product dto type is defined within the shop online.models project so let's create a project reference to the shop online dot models project let's then bring in the name space for the product dto type great okay so let's create the code to implement our i product service interface so let's create a class named product service directly within the services folder let's create a constructor so we want to tell dot net as it were that we want a http client object to be injected into our product service class so to do this we simply define a parameter of type http client within our constructor definition then let's generate a read-only member variable to reference the object of type http client that will be injected into this class at runtime the next thing to do is to implement the i product service interface so let's write the code for this let's generate the code stub for the method that we have defined within the i product service interface let's write the code logic for the get items method let's first generate a try catch block within the try block let's write code to call the get items action method that resides within the product controller of our web api component you can see we are using the generic get from json async method to call the appropriate action method within our web api component we are passing in a type argument which is an ienumerable collection of type product dto to the get json async generic method we are doing this because we want our get from json async method to return an ienumerable collection of type product dto so this method will translate the data which will be in json format returned from the web api component into an object of type i innumerable which is strongly typed with the type product dto notice that we are passing in texture which denotes where the collection of resources that we want to retrieve from our web api component can be found the web api component will know as it were to invoke the get items action method within the product controller class of our web api component based on this information passed as an argument to the get from json async method we have a red squiggly line under get from json async so to get rid of the error flagged by the c-sharp compiler we must bring in the system.net dot http dot json namespace this is where the get from json async extension method resides the get items action method that we are calling in our web api component will return a collection of objects of type product dto in json format the json data will automatically be translated into an i enumerable collection of objects of type product dto for us so our products variable here will reference the returned result which will be an ienumerable collection of objects of type product dto so we could add additional codes to handle the http response returned from the web api component we'll look at writing code for this when we look at exception handling in more detail in a later tutorial for now i just want to go through the basics of returning data from the web api component and displaying the data to the user from code created within the blazer web assembly component so now we are going to create our razor component where we will create the code to display the data to the user i.e the data returned from the service functionality we have just created razer components are fundamental to blazer simply put blazer apps are built using razer components so within the pages folder let's create a razor component named products.razer note that we are able to create our code to call our service functionality directly within our razer file within the code section here in the interests of creating cleaner code we are going to abstract the code for consuming our service functionality within a base class our raiser component will then inherit from the appropriate base class so let's create a c-sharp class named products base so in order for our base class to be inherited from our razor component our base class must inherit from a class named component base which resides within the microsoft.asp.net core dot components namespace so let's go to our razer file we want our products.razer component to be invoked when our application is first loaded so we can ensure that this happens by declaring information about our razor components root at the top of this page like this note that when a razor component with an at page directive is compiled the generated component class is provided a root attribute specifying the component's root template here we are just providing a forward slash this means that when the url contains only the base url for our blazer component that our products dot razor component will be invoked and now we can write code within our razor file that declares that our products.razer component inherits from the product base class like this so let's go back to our product space class let's create a property to facilitate dependency injection of an object of type i product service into our products razor component so let's define a public property of type i product service named product service so to indicate to.net that we want an object of type i product service injected into this property we need to decorate the appropriate property with the inject attribute like this and of course we mustn't forget to register our product service class for dependency injection so to do this let's open the program.cs class and implement the relevant dependency injection configuration code like this great let's create a public property to expose an ienumerable collection of objects of type product dto this collection will be accessible to the relevant razor code that we'll implement in a bit to output the product data so now we want our code that retrieves our product data from the server our web api component to run when the product's razor component is first invoked we can do this by overriding a function named uninitialized async so to override a method we can type override press the spacebar and then select the method that we wish to override we want to override a method named on initialized async so let's select the appropriate item here the on initialized async method is associated with a blazer lifecycle event let's read a little bit about lifecycle events on this microsoft docs webpage the razer component processes razer component life cycle events in a set of synchronous and asynchronous life cycle methods the life cycle methods can be overridden to perform additional operations in components during component initialization and rendering if the component is rendering for the first time on a request create the components instance perform property injection run set parameters async call on initialized async if an incomplete task is returned the task is awaited and then the component is rendered so within the uninitialized async method let's implement the code for retrieving our products data from our web api component like this we are using the object of type i product service that will be injected into this class at runtime to return the relevant products data to our product component let's implement code for outputting the product data so if the product property is null ie has not yet been retrieved from the server we can output a loading indicator to the user so while the data is being retrieved this loading indicator will remain on the user's screen else when the relevant product data has populated the products property we want code to execute that outputs the product's data to the user in an aesthetically pleasing style let's bring in the namespace of our product dto class we can include this using directive in the underscore imports.raiser file here and this means that this using directive will apply to the other razer files as well let's write a link query here that sequentially takes four items at a time from the collection of product dto objects images relevant to each of the products has been uploaded to github please feel free to download these images each image maps to a row of data in the products table in our database we seeded our database with the relevant data in the first part of this video series let's then implement code to appropriately output the product data bootstrap 5 is being used to output each item of products data as a bootstrap card later we are going to abstract this code further to clean up the code a bit the final code for this functionality is available on github the appropriate link can be found below in the description for now i just want to write code to display our product data appropriately to the user it was pointed out in the comments section that my spelling of the word furniture is incorrect both in the shop online db context class and the sidebar in the prototype shopping cart application that i created in preparation for this video series i don't know why i spelled furniture with an a like this for nature but clearly that's what i did the consequence is that after you ran the migration to create and seed your database the word furniture may be incorrectly spelt in your product database table and your products category database table of course you may have spotted this and fixed this before creating and running the relevant migration if not the good news is that this is easy to fix i thought that fixing this issue gives us a great opportunity to see how easy it is to fix issues like this during the development phase of our application using ef core migrations we can fix the relevant data simply by correcting the spelling issue within the on model creating method in the shop online dbcontext class we can then generate a migration that will contain the code that can be used to update the database with the relevant fix so if you ran your migration where the word furniture was spelt incorrectly within the on model creating method of your shop online db context class please follow along with these steps to fix the issue within your database please note that the appropriate spelling fixes regarding all instances of the word furniture have been uploaded to the relevant github repository of course the link to the relevant repository is included below in the description so let's open the shop online db context class that can be found in the data folder within the shoponline.api project let's go to the on model creating method so let's press ctrl f so that we can perform a find and replace on the incorrectly spelt word furniture okay clearly i can't even make the excuse that this was a typo look at how consistent i've been in spelling the word furniture wrong right let's replace the incorrect spelling of the word furniture with the correct spelling of the word furniture so eight occurrences and here are some instances where our find and replace did not fix the spelling because our search was matching the whole word so let's amend the relevant image file name references for these particular instances of course make sure that furniture is spelled correctly for the relevant furniture folder and the relevant image files on your local machines i did correct the spelling issue before i uploaded the image files to github so your file system should contain the correct spelling from when you downloaded the relevant files from github we can now invoke the package manager console window from within visual studio and create a migration to fix our issue so let's create a new migration by typing in the add dash migration command and you can see that the appropriate code to fix the relevant data in our database is generated for us in a new migration class if we are happy with the relevant migration code we can run the update database command to fix the relevant data in our databases so let's do that great so we are now ready to run our code in order to run both the web api component and the blazer component simultaneously through visual studio we can configure the shoponline.api project and the shoponline web project to start up at the same time like this but we want the shoponline.api project to start a little bit earlier before we run our code let's delete the index.razer file from within our pages directory this razer component is also configured with the same route as we have configured for our products razer component and we are not going to use the index raiser component that was generated by default in our application so now when we first run this code we are actually going to get an exception i'll explain why in a bit and then we'll take steps to resolve the issue let's press the play button to run the code you can see here that we have an exception coming from our blazer component if we press f12 while our chrome browsers are active we can examine the relevant error message here the exception is caused as a result of cause or cross-origin resource sharing cross-origin resource sharing cause is a http header-based mechanism that allows a server to indicate any origins domain scheme or port other than its own from which a browser should permit loading resources basically this error occurs because our blazer component has a different base url to our web api component as a result of this a security barrier prevents us from being able to access the relevant resources returned from our web api component let's copy the base url for our blazer component to our clipboards you'll see why we are doing this in a bit we are able to configure a policy within our web api project to explicitly allow for our blazer components to access relevant resources so to do this let's open the program.cs file within our shoponline.api project and include the relevant course policy code like this so where you see the urls in this block of code please paste the base url for your blazer component for the relevant url arguments note that we can configure both the http version of our url and the https version of our url in this course policy code and please ensure that you don't include a forward slash character at the end of these url arguments great let's run the code again excellent we now have our product data appropriately displayed to us when we first load our application so all is working fine but if we look at our product dot raiser file we can see that we have written quite a lot of code here we can make this code that outputs a row of products reusable by abstracting this code into its own component its own razor component by abstracting this code into its own razor component we are not only allowing for the relevant code to be reusable by other razer parent components we are also creating cleaner code so to do this we can create a child razor component to house the code that outputs the relevant product data so let's create a razor component named displayproducts.razer let's create a c-sharp class named display product base which will of course be the base class for our displayproducts.razer component let's make our display products base class inherit from the component base class we want a parent razor component to be able to pass an i innumerable collection of objects of type product dto to our display products razer child component we can achieve this by creating a parameter property within our display products base class like this it is important to note that a parameter property is decorated with the parameter attribute let's go to the display products.razer file and implement code to inherit from our display products base class then we can go to our products.razer file and cut the relevant code and paste it into our display products.razer file like this then we can modify the code appropriately so that the code within the display products.razer file is traversing the i enumerable collection passed to the display products child razor components products parameter a child component cannot be accessed directly through a browser and therefore does not contain a root declaration a child razor component must be invoked from within a parent razor component so let's go to the product's parent razor component and call the child display products child component through this declarative code notice how we are able to pass the relevant collection of objects of type product dto to the products parameter that we defined within the display products child component and the code for calling the child razor component from the parent razor component is very much like typical html code by abstracting the code for displaying a list of products to the user into a child razor component we have created cleaner code facilitated easier code maintenance and the display products child razor component can be reused from within other parent components this will be demonstrated in a later tutorial let's run the code great so let's say that a requirement arises where we need to display each product item under its appropriate product category so to answer this requirement we can create an appropriate link query to group our objects of type product dto by product category like this we can also include a category heading for each group of products and of course each row containing the grouped products must reside within the loop like this let's also include a dividing line between each product group let's run the code great we can clean up this code even further by abstracting the relevant link code within the appropriate base class like this great and let's say that we only wish to display four items for each product category we can achieve this by using links take extension method like this excellent the last thing i'd like to do is add basic animation effects to each of the bootstrap cards we are using to represent our products so to add a css class that only applies to a particular razor component we can add a style sheet with a name that adheres to a specific naming convention so let's add a css style sheet to the pages directory and let's name the stylesheet displayproduct.razer.css this naming convention ensures that the styles contained within this file will only apply to the displayproducts.razer component which is the component that outputs the bootstrap cards that represent our products this tutorial is not about css so i've pre-prepared the relevant css code so i'm just going to paste the relevant code into the display products dot file here this code is of course accessible from within the relevant github repository let's run the code and you can see that when we hover our mouse pointers over a card the relevant image scales and a box shadow appears these basic animation effects have been included to enhance the user's ux excellent so this is the fourth part in a series of videos dedicated to building a shopping cart application on.net 6 using blazer web assembly and web api we have now created our first workflow which involves retrieving product data from the database and displaying the data to the user in an aesthetically pleasing style we have built our database using entity framework core we have implemented code using the repository design pattern within a web api component in order to return products data from our database to a calling client in the last part of this series part three we implemented code for our blazer webassembly component to call an appropriate action method within our web api component using a http get request in order to retrieve product data from the server and display the data to the user in an aesthetically pleasing style we want to create functionality to retrieve data for a specific product from the server and display the details of that product to the user so when the user clicks on a particular product only the details for that specific product are displayed to the user the user can then decide whether or not to add the product to the user's shopping cart a button will be provided within the razer component responsible for displaying the relevant products details whereby a user can click this button and add the relevant product to the user's shopping cart we'll implement the code for the add to cart button in the next tutorial so let's go to the web api component let's open the product repository class and go to the get item method you can see that currently we have a default implementation for this method which was created when we generated the code stubs through visual studio of the i product repository interface that we are implementing in the product repository class so as the name implies the get item method returns data regarding a single item so we can use the find async method to retrieve the data pertaining to the product that matches the id value passed into the get item method through code like this the next step is to expose the functionality to a calling client by implementing code that gets executed in reaction to an appropriate http get request so we want the get item functionality to execute when a calling client makes an appropriate http get request for product data that can be identified in the system with the id value passed to our web api component from the calling client we can implement code that creates an appropriate http response through creating an action method within our product controller controller class so let's create a method within the product controller class to return data for a particular product to speed things up let's duplicate the get items action method that we created in the second part of this series and change the code appropriately so as to implement the functionality for the get item action method we only want to return data for one object of type product dto rather than an i enumerable collection of objects of type product dto to the calling client so let's change the return type appropriately let's include a parameter named id which is of type integer this id parameter denotes the id value of the product data for which the client wishes to have returned from our web api component within the http get attribute let's include the appropriate root template information our get item action method contains a parameter of type integer named id so for the get item action method it is appropriate to pass in an argument of type string to its corresponding http get attribute that denotes the appropriate root template for this action method so let's use the product repository object passed into our controller class via dependency injection to call the getitem method that we have just implemented within the product repository class so if the returned value is null this means that the resource does not exist so let's pass a response to the calling client that includes a bad request status code we can do this in code by returning the result returned from the bad request method like this so let's say we also want to include the name of the category under which the relevant product falls in the returned object as we know we only have the id of the category under which the returned product falls within the product entity we don't have the facility to store any other information pertaining to the products category within the product entity so we need to write code to get the category information from the product category entity we can then include the product information and the category information in an object of type product dto and return the relevant object of type product dto to the calling client so let's implement code for the get category method within the product repository class to retrieve data for our specific category based on the category id passed into this method let's then write code within our get item action method to appropriately call the get category method on the object of type i product repository like this the next step is to write the code that merges the data pertaining to a specific product with the data pertaining to the relevant products category into one object of type product dto in order to write the code for this in a clean way we can create a convert to dto extension method overload within our dto conversions class so the convert to dto extension method currently within our dto conversions class converts a collection of products and a collection of product categories appropriately into a collection of objects of type product eto and returns the collection of objects of type product dto to the calling code we want our new convert to dto extension method overload to convert one object of type product and related object of type product category into one object of type product dto and return the subject of type product dto to the calling code this is basically so that we can include the relevant product data and the category name within one object our product dto type facilitates this so we can write code to perform the relevant conversion like this we can now go to our get item action method and call the convert to dto extension method which is now available on this object of type product to return the appropriate object of type product dto to our action method we can then write code to return a http status code of 200 okay along with the relevant object of type product dto to the calling client by appropriately returning the result of the ok method and passing in the appropriate object of type product dto to the ok method if an exception occurs for some reason during the execution of the get item action method we have code here that will return a http status code of 500 denoting an internal server error to the calling client along with an appropriate error message great so let's write code within the blazer component to make an appropriate http call to the server side code that we have just implemented so let's open our i product service interface let's include a method definition for a method where we will implement the code to call the get item action method on the server we want this getitem method to run asynchronously so we are returning a task object the getitem method is returning a value so we must pass the return type as a type argument to the generic task type here this method contains a parameter of type integer and is named id this id parameter denotes the id value that is used to identify a specific product so let's implement the get item method in the product service class let's generate a try catch block in the previous part of this series part 3 we implemented code for the get items method that uses the http client objects get from json async method to call the relevant server side action method this method calls the relevant action method but also handles translating the returned json data into the appropriate objects type i'm going to use the get async method to call the relevant action method in our get item method this method doesn't convert the returned json data to the appropriate object type we need to write code for this separately we'll do that in a bit the get async method returns a http response object so we can use the returned object to first ascertain as to whether our http request to the server was successful so this code checks that the relevant status code falls within the success range so if the call is successful we want code to execute that checks if our http request has returned a response with content if there is no content returned from the server we want code executed that returns the default value associated with the product dto type like this so the c sharp default value for a user defines type which is a reference type will be null so this is just the way i'm choosing to handle the scenario where the call to the server is successful but for some reason no data is returned from the server so when the call is successful and content is returned from the server we want code to execute that translates the json data returned from the server into an object of the appropriate type else if the call to the server is not successful we want code to execute that handles the exception so here we are just going to throw the exception at this point and we can pass the message sent back from the server as an argument to the exception object like this within the catch block we could implement codes to log the exception or handle the exception in an appropriate manner that we choose let's implement appropriate code within the get items method to also include exception handling functionality so let's create a razor component within the pages folder let's name this component productdetails.razer so this is the component where we'll implement the code to display details regarding a specific product let's create the base class for our product details component and let's name this component product details base let's implement the code for our product details base class we want the id parameter that denotes the identifier for a specific product to be passed into the component so let's create a parameter named id that is of type integer we need to decorate this property with the parameter attribute we also need to ensure that our base class inherits from the component base class so we want an object of type i product service to be injected into our product details component so we can do this by including a property within our base class of type i product service and decorate the relevant property with the inject attribute let's include a property of type product dto within our base class and let's name this property product let's include a string property to store an exception message so we want code to execute when our blazer component is first invoked so we can ensure that this happens by writing the relevant code within a method that overrides the uninitialized async method to generate the appropriate uninitialized async method let's type in override followed by pressing the space bar and then let's select the appropriate method from the list presented to us let's generate a try catch block within the try catch block let's appropriately call the get item method on the injected object of type i product service the returned value is assigned to our product property which we can then access from our product details.razer file if an exception occurs we want the exception message to be assigned to the error message property let's implement code to output details regarding the relevant product so let's ensure that we include the appropriate root template at the top of the file we can use the page directive for this purpose and notice how we are including the id parameter here this is because an appropriate id parameter must be passed to this razor component when this razor component is invoked let's write the code logic so while the product property is null and the error message property is null we want a loading indicator to be displayed to the user else if an error occurs in which case the error message property will not be null we want the error message to be displayed please note that for the sake of this example we are writing functionality to display the error message returned from the server to the screen in a complete application it would be more appropriate to output a user-friendly non-technical error message to the user and log the actual error message returned from the server else we want to output the details of the relevant product in an aesthetically pleasing style to the user and of course bootstrap 5 classes are being used here to output the data in an aesthetically pleasing style great then let's go to the display products.razer file and include the appropriate value for the href attribute within the anchor tag that wraps the cards that represent the products sold in our online store so we want this link to invoke the product details razer component we need to include the appropriate id value denoting the identifier for a specific product within our href attribute value here let's run the code great let's abstract the code that outputs an exception to the user in its own razor component so that we can reuse this component from within multiple parent razor components this is also a cleaner way of implementing the code that displays an error message to the user let's write code to force an exception to occur so we know that a product with an id of 1000 does not exist in the system so in this case the server will send back a response code indicating that a bad request has been made let's run the code great lastly it would be better in terms of a user's ux if an appropriate animated loading indicator was displayed to the user while the user is waiting for data to be displayed so if we navigate to this site here we can copy the relevant html and css code for an animated loading indicator of our choice these loading indicators here can be used within our application free of charge so let's select this one let's copy the html and the css code for the loading indicator of our choice and integrate the code within our application the cleanest way to integrate this code into our applications in my opinion is to abstract the loading indicator code within a razor component as discussed in the previous part of this series part 3 we are able to create a css file that only applies to its corresponding razer component by naming the relevant css file in a way that adheres to a specific naming convention so if the name of the razer component is display spinner we can create a css file that will only apply to this razor component by naming the relevant css file display spinner.razer.css so we can now reuse the spinner functionality for multiple parent components i look forward to presenting the next video in this series where we'll create the functionality for adding products to a shopping cart this is the fifth part in a video series dedicated to building a shopping cart application using blazerwebassemblyon.net 6. so we have completed the implementation of two workflows the first workflow involves retrieving the data pertaining to the products sold by our online store and displaying the data in an aesthetically pleasing style to the user the second workflow involves displaying details for a particular product to the screen in response to the user clicking on a card representing the relevant product in this video we'll create the functionality whereby the user clicks the add to cart button which is available on the screen where details for a particular product are displayed this button click action will result in the relevant product being added to the user's shopping cart after the user has clicked the add to cart button the user will subsequently be navigated to a screen that displays data pertaining to the products currently contained within the user's shopping cart so let's get started so let's first implement the functionality for the server side code so let's go to our project that contains the functionality for our web api component in the second part of this video series we implemented the repository design pattern for functionality to handle database interactions regarding the products sold by our online store so we now want to create the code for handling the database functionality pertaining to the shopping cart so let's create an interface that contains the method definitions for the shopping cart repository class that we'll create once we have created its interface so let's create an interface named i shopping cart repository let's create a method definition for a method named add item as the name suggests the code that we'll implement for this method will add a particular product to the relevant user's shopping cart let's add a method definition for a method named update qty when a user first adds a product to the user's shopping cart the quantity of the relevant product added to the user's shopping cart will be won by default the implementation for this method will involve updating the quantity of a particular product that is currently contained within a user's shopping cart let's add a method definition for a method named delete item as the name suggests the functionality for this method will involve removing a particular product from the user's shopping cart the get item method will contain functionality for retrieving data regarding a particular product that is currently in the user's shopping cart the get items method will contain functionality for retrieving data for all the products that are currently in a particular user's shopping cart so let's create a class named shopping cart repository let's write codes to implement the i shopping cart repository interface that we have just created let's position our mouse pointers appropriately and press control period in order to bring in the appropriate namespace ie where the i shopping cart repository interface resides let's press control period and generate the code stubs for the method definitions that we included within the i shopping cart repository interface so in this video we are going to implement functionality for three of the methods that we have defined within the i shopping cart repository interface namely add item get items and get item before we do this let's create a constructor let's add a parameter to our constructor that is of type shop online db context by including this parameter we are indicatingto.net that we want an object of this type injected into our shopping cart repository class at runtime we have already registered the shop online db context type for dependency injection the shop online db context type is the ef core database context object that is used for handling data manipulation and data retrieval functionality in relation to our applications database so let's implement the functionality for the add item method let's first write a link query that ensures that the product that the user is attempting to add to the user's shopping cart exists in the products table so if the item returned from our link query is not null we want code to execute that adds the relevant product to the cart items database table this denotes that the product has been added to the user's shopping cart so let's implement the code to add the item to the cart items database table once we have called the add async method we must also remember to call the save changes async method then we can write code to return the entity that has been successfully added to the cart items database table like this if an item is not successfully added to the database we want code to execute that will return null to the calling code so in order to avoid a product being added twice to our user's shopping cart let's implement code that checks to see if the relevant product already exists within the user's shopping cart let's implement the code for this in a private method that returns a boolean value then we can use the private method we have just created like this to perform the relevant check so we have ensured that only one instance of a particular product can be added to the user's shopping cart please note that the user will be able to purchase more than one instance of a particular product by appropriately modifying the qty or quantity field we'll implement this at a later stage let's implement the code for the get items method let's write code that returns the results of a link query pertaining to the products currently stored within the user's shopping cart then let's write code for the get item method let's write code that returns the results of a link query which is data pertaining to a particular product currently stored within the relevant user's shopping cart let's add a controller class to the controllers folder let's name this controller class shopping cart controller firstly let's create a constructor that contains two parameters one of type i shopping cart repository and the other of type i product repository let's create two read-only fields to reference the objects that will be injected into our controller class at runtime let's of course not forget to register the i shopping cart repository type for dependency injection so let's implement the code for the get items action method let's use our shopping cart repository object to return the items currently stored within the relevant user's shopping cart if no items are contained within the shopping cart we want code to execute that returns a http response of no content to the calling client this is denoted by a http code status of 204 so this means the client http request was successful but no items related to the client's request are present in the system therefore no content can be returned to the calling client so we are returning a collection of type can't item dto to the client from the action method we have just written code that retrieves a collection of objects of type cart item we want to return a collection of objects of type can't item dto to the calling client the cart item dto type contains additional data regarding the relevant product we don't have the additional data at this point so let's use the product repository object to retrieve a collection of objects of type product we can then write code to join our collection of card item objects with the collection of objects of type product using a link query and return an appropriate collection of objects of type can't item dto to the calling client so let's keep this code clean and implement a linq query in an extension method to return the relevant collection of objects of type cart item dto to the get items action method before we do this let's write code to throw an exception if no products exist within the system because if there are no products in the system and the user is attempting to add a product to the user's shopping cart well this won't make any sense so this means an exception has occurred let's write code in a catch block that returns a http status code of 500 to the calling code so if for some reason an exception occurs during the execution of the get items action method we want an internal server error 500 http response to be returned to the client so let's go to the dto conversions class and implement another extension method overload named convert to dto we'll be able to call this extension method overload on an i enumerable collection of type cart item to perform the relevant conversion functionality let's go to our get items action method and call the extension method we have just created to return the appropriate collection of objects of type cat item dto we can then write code to return this collection to the calling client with a http response status code of 200 okay let's implement the code for the get item action method you can see here that the code is very similar to the get items action method but we of course are only returning one item of type cart item dto to the calling client instead of a collection of objects of type cart item dto so let's write code for converting an object of type card item to an object of type cart item dto to do this let's go to the dto conversion class and implement the code for the appropriate extension method overload we can then call the relevant convert to dto extension method on the relevant object of type cart item to perform the appropriate conversion functionality let's write the functionality for handling a post request from the client whereby a user is attempting to add a product to the user's shopping cart so let's write code to call the add item method on the shopping cart repository object that will be injected into our controller class at runtime we want to return the newly added item of type cart item dto to the calling client so we can call the same conversion code that we implemented for the get item method for this purpose it is important to note that it is standard practice for a post action method to return the location of the resource where the newly added item can be found this location will be returned in the header of the http response returned from this method we can use the create at action method to ensure that we are adhering to this standard practice so the relevant resource can be found at the uri universal resource identifier pertaining to the get item action method and we are including the id of the newly added resource here and for the final argument we are including the newly added object which we have now converted to type cart item dto if you'd like to read more about the create at action method i've included an appropriate link below in the description and we of course need to decorate this action method with the http post attribute let's run the shoponline.api project through visual studio and you can see the new action methods and relevant dtos are present on the swagger ui web page great let's implement the relevant code for our blazer component so let's go to the shoponline.web project let's create a new service class where we'll implement code that interacts with the action methods that we have created within our shopping cart controller class in our web api project firstly let's create the appropriate interface in the contracts folder for the relevant service class let's name this interface i shopping cart service let's create a method definition for the get items method and the add items method let's create a class named shopping cart service let's generate the code stubs for the methods defined within the i shopping cart service interface let's create a constructor for the shopping cart service class let's include a parameter of type http client as a parameter within our constructor this parameter indicates to.net that we want an object of type http client injected into this class at runtime let's implement the code for the add item method so basically this code calls the post action method that we implemented in the shopping cart controller class if the response http status code is within the success range let's check to see if any content was returned if no content was returned let's return the default c-sharp value for the cart item dto type to the calling code which will be null if content was returned from the server let's return the object representing the newly created shopping cart item to the calling code this will of course be an object of type can't item dto let's include the relevant exception handling code let's implement code for the get items method so i'm deliberately including an incorrect uri universal resource identifier reference here so that this will force an exception when we run the code we'll fix this a little bit later after we have run the code that tests how an application handles the relevant exception this code simply places a http get request to the get items action method and if content is returned returns the relevant content to the relevant razer component i.e the calling code let's go to the product details base class and implement a button click event handler method for the add to cart button let's name this click event handler method add to cart underscore click let's make sure that we have registered the i shopping cart service type for dependency injection let's implement code that ensures that an object of type i shopping cart service is injected into the product details base class at runtime then our code within the add to cart underscore click event handler method calls the add item method on the injected shopping cart service object to add a product chosen by the user to the user's shopping cart let's go to the product details.razer file and implement the code that calls the add to cart underscore click event handler method so we have started with the implementation of the shopping cart functionality we have not implemented user registration or login functionality ie membership functionality in this application we could implement codes to bring down user related information from the server when the user first logs onto the system the information could include the user's user id and the user's cart id so because we haven't implemented login functionality let's temporarily hard code the user's cart id and user id in a class within the project that contains our blazer functionality so that we can progress with the implementation of the shopping cart functionality so in the first video in this series we seeded the data with data for two users so let's say that we are going to run the code from the perspective of the user that has a user id of one and a cart id of one so we can now pass in the hard-coded cart id value here along with the relevant product id and a quantity of one when a user adds a product to the user's shopping cart by default one instance of that product is added to the user's shopping cart let's strategically add some breakpoints in the blazer project and the web api project and run the code and let's invoke the functionality for the workflow that we have just implemented incurred by clicking a product that we wish to add to the shopping cart and then let's click the add to cart button great if we look at the cart items database table we can see an item has been appropriately inserted into the relevant table let's test this again great let's create a razor component that will be responsible for rendering a collection of products data pertaining to products that have been added to the user's shopping cart to the screen so let's add a razor component named shoppingcart.razer let's add a base class for the shopping cart razor component let's name this class shopping cart base let's implement code for the shopping cart base class so our shopping cart base class must inherit from the component base class because we want this class to be the base class for the shopping cart raiser component let's write code for injecting an object of type i shopping cart service into our class at runtime let's include a property for referencing a collection of objects of type cart item dto this property will be used within the shoppingcart.razer file for code that displays the relevant data to the screen let's create the code to override the uninitialized async method where we'll implement code for assigning the relevant collection of items returned from the server to the shopping cart items property when the razer component is first rendered great let's implement the code for the shoppingcart.razer file let's include the page directive at the top to declare the root template for our shopping cart razor component let's use the inherits directive to ensure that we are using the shopping cart base class as the razer components base class so while the shopping cart items property is null and the error message property is null we want a spinner loading indicator to be displayed to the user if the error message property is not null we want the relevant error message to be displayed to the user else we want code to run that displays in an aesthetically pleasing style the data representing a collection of products that have been added to the user's shopping cart we are using bootstrap 5 classes for styling the html elements in our razer file now that we have written the code for displaying a collection of products data for products added to the user's shopping cart let's write code that navigates the user to this screen after the user clicks the add to cart button so let's go to the add to cart underscore click event handler method within the product details base class and implement the relevant code so we can use an object of type navigation manager to navigate the user to the relevant screen so let's write code to ensure that an object of type navigation manager is injected into our razer component at runtime let's then invoke the navigate to method on the navigation manager object to navigate the user to the shopping cart screen let's run the code and an error message is displayed to us this is because we are forcing a 404 not found error to occur at the moment we have included an incorrect path to the end point that returns the collection of card item dto objects within the get items method of the shopping cart service class we need to appropriately include a reference to the shopping cart controller name within this uri reference so let's correct this uri universal resource identifier by appropriately including the relevant controller name here great this is the sixth part in a video series dedicated to building a shopping cart application using blazerwebassemblyon.net 6. so we have created three workflows let's recap the first workflow involves retrieving products data from the database and displaying the products data to the user in an aesthetically pleasing style the second workflow involves retrieving details for an individual product and displaying the relevant details in an aesthetically pleasing style to the user the third workflow involves the user adding a product to the user's shopping cart and the user being navigated to a screen that displays a list of products contained within the user's shopping cart in this video we'll create the workflow that involves a user removing a product from the user's shopping cart let's get started let's start by implementing the server side code let's go to our shoponline.api project and open the shopping cart repository.cs file let's implement the code logic for the delete item method so we can use the id value that will be passed into this method to find the entity that we wish to delete from the cart items database table we are using the find async method to find the relevant entity using the primary key field which is the id field if we find the relevant entity if the item returned from the find async method is not null we can use the remove method to remove the relevant entity from the cart items database table then we mustn't forget to call the save changes async method to commit the relevant change to our database in order to make this delete functionality available to calling client code let's create an appropriate endpoint within our web api component so let's go to the shopping cart controller class and create an appropriate action method that will call the relevant delete item method that we have just implemented in the shopping cart repository class let's decorate our delete item action method with an attribute that declares that this action method corresponds to the http delete verb so far in the development of our application we have created endpoints that correspond to both the get and post http verbs we are about to implement the logic for an endpoint that corresponds to the delete http verb let's declare the relevant root template information for our action method by passing an appropriate string argument to the http delete attribute this information includes a definition for the id that needs to be part of the uri universal resource identifier pertaining to the entity that a client wishes to delete so we are essentially enabling a calling client to delete a specific resource from the system let's create a try catch block a simple way to create the relevant code for this is to type try followed by pressing the tab key twice let's call the delete item method on the shopping cart repository object that will be injected into the constructor of this controller class at runtime if the entity that the client wishes to delete cannot be found we want code to execute that returns a http response code of not found 404 to the client the information that we want transferred across the network for the relevant entity that the client wishes to delete is of type can't item dto and not the type cart item that is returned from the delete item method called on the shopping cart repository object in the previous part of this video series part 5 we implemented an extension method overload named convert to dto within the dto conversions class this extension method can be called on any object of type cart item before we appropriately call the convert to dto extension method we must retrieve the relevant product entity from the database so let's write the code to achieve this then let's call the convert to dto method on the object of type cart item returned from the shopping cart repository classes delete item method to convert the relevant object of type cart item to an object of type cart item dto then let's write code to return a http response code of ok200 to the client along with the relevant object of type cart item dto let's complete this method by writing code that executes if for some reason an exception is thrown during the execution of the code logic within the delete item action method let's go to our blazer component so let's go to the shoponline.web project let's add an appropriate new method definition to the i shopping cart service interface named delete item let's open the shopping cart service class and implement the code logic for the delete item method if the http response code returned from the server falls within the success range we want code to execute that returns an object of type can't item dto to the calling code if the call to the server is not successful we want null to be returned to the calling code let's open the shopping cart base class within the pages folder let's implement code for a method that handles a button click event so this method will be called when a user clicks a delete button that we'll create in a bit in the shoppingcart.razer file let's appropriately call the delete item method on the shopping cart service object that will be injected into our razor component at runtime so this code will call the appropriate action method on the server side that will delete the relevant entity cart item from our database so we want the results of this deletion operation to be reflected on the user interface which means we need the shopping cart razor component to re-render once the deletion operation has completed successfully we could call the appropriate get items method and retrieve all the relevant shopping cart items that are currently saved to our database for the relevant user and assign the results to the shopping cart items property and the result of the deletion operation would then appropriately be reflected on the ui however we can implement code for a solution that will be more performant for this purpose than the solution that i've just expressed i.e that involves an additional call to the server-side code we can reflect the results of a deletion operation on the ui by simply deleting the relevant cart item object from the client side collection of card items referenced by our shopping cart items property by deleting the relevant item from the client side collection we are avoiding a trip as it were to the server side this could result in a significant performance benefit so let's create a private method responsible for removing the relevant item from the client side shopping cart items collection we first need a variable that references the object within the shopping cart items collection that we wish to delete so let's create another private method that contains code for returning a specific object within the shopping cart items collection let's then call our new private method to return the object that we wish to delete from the shopping cart items collection to our remove card item method we can then implement code to delete the relevant item from the relevant client-side shopping cart items collection but there is a problem with this at the moment our client site collection stored within the shopping cart items property is currently of type i enumerable the i enumerable type is fine for when we need to traverse through the items in the relevant collection but we don't currently have an easy way available to us to remove an item from the relevant client-side collection one solution to this problem is that we can change the type of our client side collection to type list we must also appropriately change the return type of the delete item method definition in the i shopping cart service interface and of course we must also appropriately change the return type for the implementation of this method in the shopping cart service class let's go back to the shopping cart base class and use the remove method on the shopping cart items collection which is now of type list to remove the relevant item from the relevant client side collection let's appropriately call our remove cart item method from within the delete cart item underscore click event handler method let's create the delete button within the shoppingcart.razer file let's use blazers at on click syntax to ensure that our delete can't item underscore click functionality is triggered when the user clicks our new button let's run the code and test our method great okay so i don't like this empty screen displayed to the user here when the user no longer has any cart items saved to the user's shopping cart so let's ensure that status information is outputted to the user for the case where the user's shopping cart is empty so we can do this by using the count method so if the count method returns a value greater than zero we can output the data contained within the shopping cart items property as well as the relevant shopping cart summary information else let's output a basic message to the user informing the user that the user's shopping cart is empty let's run the code great so i think rather than display the text remove on the relevant button i think the standard trash icon would look better let's use font awesome for this purpose i'm going to use an appropriate cdn cloud delivery network link to reference the relevant font awesome css file so if we go to this website we can copy the relevant link here and we can then paste it into our index.html file in order to include font awesome icons within our application we are now able to reference the font awesome trash icon like this to display the trash icon on our delete button excellent i hope you've enjoyed this video i look forward to presenting the next video in this series where we'll continue to develop our shopping cart application we are going to implement the update quantity functionality in the next video this is the seventh part of a video series dedicated to building a shopping cart application using blazerwebassemblyon.net 6. so in the previous part of this series we created functionality whereby a user can delete an item from the user's shopping cart in this video we are going to create the functionality whereby a user is able to update the quantity of a particular product that has been placed within the user's shopping cart a notable feature that we'll add is the showing and hiding of the update qty button so we only want the update qty button to appear when the user changes the appropriate value in the field denoting the quantity of a particular item in the user's shopping cart when the relevant field is changed the relevant update qty button appears once the user has clicked the update qty button to update the quantity of a particular item in the user's shopping cart we want the update qty button to disappear to achieve the appropriate showing and hiding of the update qty button we are going to invoke a javascript method this brings us to an important question how do we integrate javascript into our blazer webassembly component in this video we are going to look at how we can use blaze's javascript interoperability feature to interact with javascript code from within our blazer webassembly component we'll implement this functionality toward the end of the video so please stick around to the end to learn about javascript interoperability with blazer to start with let's create the server-side code for the update qty functionality so let's get started let's go to the shoponline.api project let's open the shopping cart repository class let's implement the code logic for the update qty method first thing to do is reference the item that we wish to update so if we are able to find the relevant item within our database and therefore the item variable will not be null we can then update the qty field with the value passed in from the client and to commit the change to the database we must of course call the save changes async method let's write code to return null to the calling client for when the item is not found within the database let's expose the update quantity functionality to our calling client through an action method let's open the shopping cart controller class let's create an action method named update qty let's appropriately call the update qty method on the shopping cart repository object to update the relevant resource with the qty value passed into our action method by the client let's use our convert to dto method to appropriately convert the cart item object into an object of type cart item dto we can then write code to return the relevant object of type cart item dto to the calling client along with the http code status of 200 ok let's include the appropriate exception handling code so we have so far created action methods that correspond to the http get verb the http post verb and the http delete verb the other two most common http verbs are the http put verb and the http patch verb the http put verb and the http patch verb are both associated with the performance of resource updates the difference between these two http verbs is that the http put verb is associated with action methods that modify a resource where the client sends data that updates the entire resource the http patch verb however is associated with action methods that partially update the respective resource so we want our update qty method to update only the qty field for a cart item resource so this means it is appropriate to associate our update qty action method with the http patch verb we can write declarative code to indicate that this action method is associated with a http patch verb to do this we can appropriately decorate the update qty action method with the http patch attribute like this note that we are passing in data to the http patch attribute that provides necessary route template information this indicates that the uri for the relevant endpoint must appropriately contain the id of the resource that the client wishes to modify right let's write the appropriate code for the blazer component so let's go to the shoponline.web project let's open the i shopping cart service class let's open the shopping cart service class to implement the code logic for the update qty method let's first serialize the dto that we wish to pass to the server into json format let's create an object of type string content so that we can appropriately pass the relevant data in the appropriate format to the server let's call the patch async method on our http client object and pass in the appropriate uri as well as the relevant data to the patch async method if the http response status code falls within the success range let's include code that returns the appropriate data returned from the server to the calling code let's go to the shopping cart base class let's create a method that will handle the update qty button click event so the calling code will pass in the id of the shopping cart item that the user wishes to update as well as the relevant quantity value if the quantity value is greater than zero meaning that the quantity or qty field value is valid we can appropriately call the update qty method on the shopping cart service object to call the relevant server side code in order to update the database appropriately else if the calling code passes in an invalid quantity let's set the quantity field for the relevant cart item to one let's go to the shopping cart dot raise a file let's add an input field that will allow a user to modify the quantity of a particular item in the user's shopping cart note that we are using blazers at bind syntax to bind each quantity input field to the corresponding property of the appropriate object of type cart item dto stored within the shopping cart items collection this means for example that if the qty property for a cart item dto object stored within the shopping cart items collection is modified that this modification will immediately be reflected on the ui in the appropriate quantity input field let's create the update qty button that a user can click in order to update the quantity of a particular item let's use blazes at onclick syntax to call the appropriate event handler method that we have created within the shopping cart base class let's stand by our convention to use the underscore click suffix for these type of event handler methods so let's change the name of the relevant method from update qty cart item to update qty cart item underscore click then we can write code to pass in the appropriate values to our update qty cart item underscore click method let's test the code great so we haven't yet written code so that the total quantity and total price is reflected within the cart item summary information displayed to the user on the right-hand side of the user's screen let's implement the code for this so firstly let's include two properties within our shopping cart base class let's include a property to store the total price of the items within the user's shopping cart and the total quantity of the items stored within the user's shopping cart let's create a private method named set total price which is responsible for calculating the total price of all the items stored within the user's shopping cart and assigning the result of this calculation to the relevant property let's create a private method named set total quantity which is responsible for calculating the total quantity of items stored within the user's shopping cart and assigning the result of this calculation to the relevant property let's create a private method named calculate cart item summary totals let's call the set total price method as well as the set total quantity method from within the calculate cart summary totals method we want the total price of all the items stored within the user's shopping cart as well as the total quantity of items stored within the user's shopping cart to be reflected on the ui whenever a user action results in the state of the shopping cart changing so let's appropriately call our calculate card summary totals method from within the update qty cart item underscore click event handler method the delete cart item underscore click event handler method and the on initialized async method that is called when the razer component is rendered let's go to the shoppingcart.racer file and implement the code that will result in the appropriate summary totals being reflected appropriately on the ui before we run the code we must also include a method in the shopping cart base class that updates the total price property on the relevant object of type cart item dto when the relevant quantity property is updated for a particular cart item by the user so basically if for example a cart item has a price of 50 dollars and the user updates its quantity property from one to two we need to change the cart items total price from fifty dollars to a hundred dollars to calculate the total price is simply a mathematical operation of price multiplied by quantity so let's create a method named update item total price let's call our get card item private method to reference the relevant cart item then we can update its total price property with the result of the calculation that we have just discussed we want our update item total price method invoked every time the quantity for an item within the user's shopping cart changes so let's implement the code for this appropriately great let's run the code excellent so let's look at javascript interoperability in a blazer webassembly component let's implement the code so that our update qty button is only shown to the user when the state of the relevant input field changes so let's first create a css file for our shopping cart razor component so let's create a css file named shoppingcart.razer.css as discussed when we create a css file that only applies to a specific razor component we must adhere to a specific naming convention let's create a css class named update dash qty that contains the code display colon none so we can apply this class to the update qty button like this to ensure that when the relevant razer component first loads that the update qty button is not displayed to the user so the next step is to create a javascript method that is invoked when the quantity input field is changed by the user this javascript method will be responsible for appropriately showing and hiding the relevant update qty button let's create a folder within the www root folder of our project named js let's add a javascript file named shoppingcartfunctions.js to the js folder let's create a javascript function named make update qty button visible this function accepts two arguments one denotes the id of the relevant cart item and the other denotes a boolean value so in order to be able to identify the relevant button within our javascript code we can apply a data attribute to the relevant html element so let's go to our shoppingcart.razer file and include a data attribute named data dash item id and set its value to the id of the relevant cart item the code for the javascript function is fairly basic let's use our data attribute to reference the appropriate button element we are using the data dash item id data attribute to identify a specific update qty button if the boolean value is true we want code to execute within our javascript function to make the relevant button visible if the boolean value is false we want our function to make the relevant button invisible let's appropriately reference our new javascript file from within the index.html file then we need to write code to detect when a quantity input field or qty input field is changed by the user we can use blaze's at on input syntax for this purpose one might think that the at on change syntax should be used for this purpose but a method executed in response to the at once syntax will only be invoked when the relevant input field loses focus we want our method to be invoked immediately when the relevant input field's value changes so let's implement a method within the shoppingcartbase.cs class that will be invoked when a quantity input field is changed so we want our make update qty button visible javascript function to be invoked when a quantity input field is changed so how can we call a javascript function from within a razer component the answer to this is that we can use the built-in js runtime type for this purpose so let's create a property of type i js runtime let's decorate this property with the inject attribute so that an appropriate object of type ijs runtime will be injected into our razor component at runtime we can then use the object to appropriately call our make update qty button visible javascript function like this let's go to our shopping cart dot race of file and appropriately call our update qty underscore input method lastly let's write code that calls the relevant javascript function to make the relevant update qty button disappear once the relevant button has been clicked let's run the code excellent this is the eighth part of a video series dedicated to building a shopping cart application using blazerwebassemblyon.net 6. so at this point we have achieved quite a lot we have created the functionality for displaying grouped products to the user we have also created most of the functionality for the shopping cart a user can now add a product to the shopping cart remove a product from the shopping cart and can update the quantity of a product that is contained within the shopping cart so we now need a way for a user to be able to navigate to the shopping cart from anywhere within the application we also want the user to be able to see at a glance how many items are currently contained within the user's shopping cart currently the user is only able to navigate to the shopping cart through our application by adding a product to the shopping cart we want the user to be able to see how many items have been added to the user's shopping cart at a glance no matter where the user is within the application for example the user may be viewing the grouped products displayed to the user when the application is first launched and wishes to know how many items are currently contained within the user's shopping cart we also want the user to be able to navigate to the user's shopping cart through our application from anywhere within the application simply by clicking a button so we want to make this button accessible to the user from anywhere in the application so in this video we'll provide an appropriate solution for this we'll provide a button in the header part of the ui that when clicked will navigate the user to the user's shopping cart the quantity of items stored within the user's shopping cart will be displayed on the text of the relevant button so the quantity value displayed on the relevant button must be kept up to date so we must facilitate the change of the relevant quantity value whenever the number of items within the shopping cart changes the code for the button containing the text representing the number of items in the user's shopping cart will be contained within its own razor component a razor component we'll name cart menu so this means we need to find a way to send data to the cart menu razor component from other relevant razer components like for example the shopping cart razor component whereby code must execute that updates the relevant quantity value when a change to the number of items stored within the user's shopping cart is made in this video we'll see how c-sharp events can be used to facilitate communication of data between the loosely coupled razor components within our application right let's get started let's go to our blazer client component so let's go to the project named shoponline.web let's open the i shopping cart service file let's create a definition for a c-sharp event note that the action type is a delegate that doesn't return a value so any method that the relevant delegate points to will be able to accept the arguments defined within the relevant delegate but the method will not return a value in our case any method pointed to by this delegate will accept one argument of type integer let's create a definition for a method that is responsible for raising the relevant event to subscribed components if what we are doing here is unclear to you don't worry it will become clearer to you as we develop the code in this video okay so let's open the shopping cart service file let's implement the code for the interface items that we have just created let's implement the code for the raise event on shopping cart changed method first we need to check if our event has any subscribers we can do this by evaluating the on shopping cart changed event object so if the on shopping cart changed object is not null this means that the event has subscribers so if the event has subscribers we need to write code that raises the event to those subscribers we can do this by implementing the invoke method on the on shopping cart changed event object then we can send the appropriate integer value to each of our subscribers by passing in the appropriate integer value to the invoke method so in the context of our application an example of a subscriber will be a method within the cart menu razor component that we'll create later in this tutorial when the quantity of the item stored within the user's shopping cart changes the event is raised and a custom method that will be created within the cart menu razor component will be invoked in response to the quantity of items stored within the shopping cart changing basically when the quantity of the shopping cart changes the event is raised and any subscribed methods are called this will be clarified with code that we'll create in a bit so this event being raised will result in the new quantity of items stored within the user's shopping cart being displayed from within the cart menu razor component let's open the products base dot cs file let's write code so that an object of type shopping cart service will be injected into this razor component at runtime so the product razor component is loaded when a user first launches our application we want the user to be able to see how many items are currently stored within the user's shopping cart when the application is first loaded so let's first appropriately call code on the server to retrieve the shopping cart items currently stored within the user's shopping cart i can feel the comments flowing my way already so i think i'll be preemptive and just say that i'm aware that this may not be the most performant way of doing this but i want to focus on events in relation to razer components in this tutorial we will be optimizing the code in later videos for example by including local storage functionality i don't want to make my videos too convoluted so this is why i sometimes first create simplistic code in certain scenarios so that momentum is gained in the development of our application and then as i said we can always optimize the code in later tutorials right let's write code to calculate the number of items currently stored within the user's shopping cart we can then use the shopping cart service object to raise the appropriate event which will in effect send the quantity of items stored within the user's shopping cart to any subscribers so this will result in the appropriate quantity value being displayed to the user in the header section of the layout of our application let's open the shoppingcartbase.cs file so we want our event to be raised each time the quantity of items stored within the user's shopping cart changes let's create a private method named cart changed let's rationalize our code a bit so that the card summary totals private method is called whenever this card changed method is called and we want our events to be raised whenever the cart changed method is called we want our cart changed method to be called whenever the state of the user's shopping cart is changed so let's appropriately call our method from within the uninitialized async method the delete card item underscore click event handler method and the update qty cart item underscore click event handler method notice that each time we write code to invoke the cart changed method we are replacing the call to the cart summary totals method with the call to our new cart changed method because the calculate summary totals method is now being called from within the cart changed method so let's create the code for the cart menu razer component this component will be displayed in the header section of our layout for our application so let's create a race component called cartmenu.razer within the shared folder let's write code so that an object of type i shopping card service is injected into our cart menu razor component at runtime let's open the underscore imports.razer file and include a using directive that references the shop online dot web dot services dot contracts name space so we are not using inheritance for this component so we can instead include code logic for this razor component within the add code section of our razer file this is because our cart menu razor component is not likely to contain a lot of code logic so we don't necessarily need to abstract the code logic into a separate base class let's define a variable of type integer named shoppingcartitemcount let's create an override for the razer component's uninitialized method this method will be called when our razor component is first rendered so we want our razor component to subscribe to the event that we created in the shopping cart service class to achieve this we can implement this code this means that every time the relevant event is raised the shopping cart changed method will be run so we haven't yet implemented code for the shopping cart changed method so let's do that so all we are doing is updating our shopping cart item count variable with the quantity value passed into this method from code that executes to raise the relevant event note that we are calling blazers built in state has changed method here this is an explicit way of telling blazer as it were to re-render the relevant razer component so we are explicitly telling blazer to re-render the component after the shopping cart item count variable has been assigned a new value from code that is raising the relevant event the shopping cart item count will be used in the ui user interface code that we are about to create for displaying the new quantity of items stored within the user's shopping cart so let's write the ui code and this must exist outside the at code section so we want a button displayed to the user that displays a value representing an up-to-date count of items currently stored within the user's shopping cart we also want a user to be able to navigate to the user's shopping cart when this button is clicked in order to prevent possible memory leaks we can write code to unsubscribe from the on shopping cart changed event so to do this let's implement the i disposable interface then we can implement code for the dispose method to unsubscribe from the on shopping cart changed event like this so you can see that the plus equals operator is used to subscribe to an event and the minus equals operator is used to unsubscribe from an event let's open the main layout razor component from within the shared folder this component is responsible for displaying the main ui layout of our application we can ensure that our cart menu razor component displays within the header section by including the appropriate tag for our cart menu razer component here so let's run the code excellent so notice that when we are using a mobile view when running the application we are not able to see our header menu item so let's write code to allow for users that are using our application in a mobile view to be able to see the count of items currently stored within the user's shopping cart and also to be able to navigate to the user's shopping cart from anywhere within the application we can do this by adding an appropriate menu item to the application's main menu for when the application is being used using a mobile view so let's open the nav menu.razer file from within the shared directory this file contains the code responsible for creating our application's main menu let's add a new menu item to the main menu like this let's write code so that an object of type i shopping cart service is injected into this razor component at runtime in the add code section let's create a private variable of type integer named shoppingcartitemscount let's implement the code to subscribe to the on shopping cart changed event let's implement the method that we want to executed when the on shopping cart changed event is raised let's go to the appropriate menu item code and include the shopping cart item count variable so that the user is able to see from this menu item how many items are currently stored within the user's shopping cart now we only want this menu item to be shown to users that are using our application using a mobile view so we can ensure this by including the d sm none bootstrap class within the appropriate html element that represents the relevant menu item lastly let's write code so that before this razer component is garbage collected ie before.net frees the memory taken up by this razor component that the relevant method within this razor component is unsubscribed from the on shopping cart changed event let's run the code excellent so we have now completed all the functionality that enables a user to add items to the user's shopping cart as well as remove items from the user's shopping cart a user is also able to update the quantity of products within the user's shopping cart so of course no point leaving the products hanging around in the user's shopping cart the next logical step is for a user to purchase the products in the user's shopping cart so we are going to create a razor component in this part of the course that denotes a checkout facility whereby the user can purchase the products within the user's shopping cart so how do we create a payment facility so that users can purchase the items in the user's shopping cart the answer is we must integrate a payment gateway into our application so if we navigate to this website we can see here some useful information regarding payment gateways what is a payment gateway a payment gateway is a service that authorizes and processes debit slash credit card or paypal payments for online merchants and traditional brick and mortar businesses a payment gateway facilitates these transactions by encrypting sensitive data and transferring it between a payment portal a website or a mobile device and the bank slash front end processor if we scroll further down this page we can see a list of the most popular payment gateway providers you've probably heard of a few of them like for example paypal and stripe paypal stripe square secure pay worldpay authorized.net to checkout.com braintree i have a business account with paypal so i'm most familiar with paypal in this video i'll give you a very basic guide on how you can integrate the paypal payment gateway into your application even though i'm specifically using paypal the same fundamental principles will apply for other payment gateways please see the relevant instructions provided by your preferred payment gateway service provider on how you can integrate your preferred payment gateway into your applications the payment gateway service provider will provide developers with information on how to integrate the relevant payment gateway into your application it's not as difficult as you might think all of the heavy lifting as it were is done through the third party payment gateway so this tutorial is not a definitive or comprehensive guide on how to integrate a payment gateway into your application but it will hopefully give you a very good idea of how to integrate a payment gateway into your applications it all depends on your application's requirement on how you go about implementing relevant payment gateway integration functionality in your applications let me first present a brief disclaimer before we start this tutorial this is not a definitive guide on integrating a payment gateway into your application this is certainly not a final e-commerce solution the purpose of this tutorial serves to give you a basic idea of how you are able to integrate a payment gateway into a blazer webassembly application if you wish to create an application that uses a payment gateway in a live environment you'll need to research relevant information provided by your preferred payment gateway provider in order to gain a thorough understanding of how to create an e-commerce solution using the relevant payment gateway right let's get started let's create a razor component named checkout.razer within the pages folder let's create a c-sharp class named checkoutbase.cs within the pages folder let's write code to ensure that the checkout razer component inherits from the checkout base class as the name of our razer component suggests a user will navigate to this razor component in order to purchase the items within the user's shopping cart paypal makes it easy for us to integrate the payment gateway functionality within our applications by providing us with sample html and javascript code in order to copy the relevant html and javascript code let's navigate to this paypal web page if we scroll further down the page paypal presents us with a few options i'm going to use the first option here let's click the start setup button let's select the variable price list item here let's select the desktop option here then to copy the relevant javascript and html code we can click the copy code button here let's navigate to our index.html page and paste the html and javascript code currently stored within our clipboards here you can see here we have a javascript function named init paypal button this method contains callback methods like for example create order and on approved the create order method is called by paypal when an order is created and the on approved method is called after the relevant order has been approved by paypal note that within the on approved method there is code that logs information about the order which is sent back from paypal after an order has been approved to the browser console window the relevant information is sent back from paypal regarding the relevant order after the order has been approved by paypal so this gives us an idea of how our code integrates with paypal we also have a script tag here that references a script file at a specific paypal location the way in which we are able to link a paypal account to our application is through this client dash id parameter here at the moment we only have a placeholder value for the client dash id parameter i'll demonstrate a bit later how we are able to generate a valid client id value that we can paste over this placeholder value here i'll demonstrate this a bit later we have this html code here that contains various fields and a placeholder for the relevant payment gateway related buttons that the user can use to start the payment process the user will be able to pay using a valid debit or credit card by clicking this button or if the user has a valid paypal account the user can use the user's paypal account by clicking this button for a particular integration requirement we can tailor the sample code to our needs so we are going to simplify the code here and remove code that is superfluous in relation to our particular requirement so let's say that for a particular integration requirement we only need the description field and the amount field so we can delete the javascript code from the init paypal button method here that references the html elements denoting the fields that we don't need we don't need this code here so let's delete it we don't need this code because it is code used for validating user input code within our application will control what is entered into the appropriate fields namely the amount field and the description field therefore we don't need any user validation related code in the on init method there is a lot of code relevant to user validation that we don't need let's delete the honornet method within the onclick method we only need this code here that references the values that will be inserted into the amount and description fields at an appropriate time by certain code within our application so let's copy the relevant code from the onclick method here let's paste it into the create order method here then we can simply delete the onclick method you can see here in the on approved method we have code here that logs order information to the user's browser console window this information is sent back from paypal once a user's order has been approved by paypal and contains details about the user's order we'll examine the order information later when we test our code you can see here that the sample code that we copied from paypal includes a call to the init paypal button javascript method we want to control when the init paypal button method is invoked we'll implement the code to call the init paypal button method using c-sharp code and blaze's javascript interoperability feature from within the checkout razer component in a bit so let's remove the call to the init paypal button from the index.html file let's cut this html code here and paste it into our checkout.razer file this will allow the paypal buttons to be available to the user when the user invokes the checkout raiser component for our particular requirement let's say that all we are interested in is the description field and the amount field so let's remove the html elements that we don't need for the implementation of our integration code with paypal we don't need the html elements that label the relevant fields because we are going to make the amount field and description field hidden text fields we don't want the user to enter any payment information we are going to control the values that are inserted into these fields through c-sharp code that we'll implement in a bit we need this div element here because this tells paypal as it were where we want the relevant paypal gateway related buttons placed within our ui so for our requirement we don't want these fields to be visible to the user so let's make these fields hidden text fields so let's create the code for the checkout base.cs class we are going to want to call the init paypal button javascript method that resides within our index.html file from within the checkoutbase.cs class so we need to write code that ensures that an object of type rjsruntime is injected into our checkoutrazor component at runtime this is so that we can utilize blaze's javascript interoperability feature to call the init paypal button javascript method that we copied from the relevant paypal web page earlier we'll write the code to call this javascript method in a bit we need to reference the collection of shopping cart items so let's create a property of type i enumerable that is strongly typed with the cart item dto type let's create a property named total qty let's create a property named payment description let's create a property named payment amount let's create code to bind the paypal related hidden text fields we have implemented within the checkout.razer file to their counterpart properties by using blazers at bind syntax so this means that every time relevant property values change laser will automatically update their counterpart input fields i.e the input fields that contain the relevant at bind syntax in the checkout.racer file the payment description and payment amount properties will be bound to the input fields implemented within the checkout.racer file so this is one of the aspects involved in integrating our application with paypal we can communicate the total payment amount to paypal through the payment amount property and we can communicate whatever payment description we want by updating the payment description property the javascript within the init paypal button method references the fields that we have implemented using hidden text fields in the checkout.razer file i.e the amount field and the description field the fields are bound to their counterpart properties within the checkout base class we can use this description field to uniquely identify a particular payment there are of course many different ways to implement this type of functionality i've chosen this way for the sake of the example in the interests of keeping the example simple i.e for teaching purposes when we run the code and create a test order once our order is approved by paypal we'll be able to inspect the data within our browser's console window which is the data sent back from paypal after our order has been approved we'll see that one of the fields contains our unique description value we want an object of type i shopping cart service to be injected into our checkout raiser component at run time so let's create a property of type i shopping cart service and ensure that it is decorated with the inject attribute let's override the uninitialized async method let's implement code to retrieve the user's shopping cart items we'll look at code in a later tutorial whereby we can use local storage functionality so that we don't have to make so many calls to the server we can use local storage to improve performance but we'll write this code in a later tutorial so i'm writing code to create a new good here so that we can use this good value to uniquely identify a particular order let's assign the total payment amount to the payment amount property let's assign the total quantity to the total qty property let's create an identifier field so that we can uniquely identify a particular order as i said earlier i'm just doing this for the sake of this example it is up to the developer to modify the appropriate code so that it is adapted appropriately in relation to the developer's particular requirement so let's include an o for order followed by the user's id and then followed by the unique guide value within the payment description field let's override the on after render async method this method is called in response to the occurrence of a blazer lifecycle event that occurs after the relevant razer component is rendered we can use the first render argument passed to this method to ensure that our code within this method is only fired once after our razor component is first rendered so if first render is true we want code to execute that uses our js object to call the init paypal button javascript method so you can see how we are integrating our checkout razer component with the sample javascript code that we included within the index.html file this is of course the sample code we copied from paypal so as to perform our integration with their payment gateway so the next step is to generate the client id whereby we can link our paypal account to our application so we need to do this through paypal note that you are able to follow along with the next part of this tutorial even if you just have a personal account with paypal you will however need a business account with paypal if you wish to go live with the paypal payment gateway functionality paypal provides a sandbox feature that we can use for development and testing purposes but as i said if you wish to go live you'll need a paypal business account for instructions on how to create a paypal business account please navigate to this url so assuming you have a paypal account as stated you are still able to follow along even if you just have a personal account and you don't have a business account let's log in to paypal then let's click the developer menu option here so that we can use the sandbox feature to implement the server side part of the integration functionality so that we can integrate the paypal payment gateway into our application you can then navigate to the dashboard like this you can see here you have two options one for sandbox and the other for live we are going to use the sandbox facility if you want to go live with your paypal payment gateway you would use the live facility as discussed you will need a paypal business account before you are able to go live with the paypal payment gateway so to create the server side functionality that we need in order to integrate the paypal payment gateway into our application click the create app button let's give the app a sensible name and then create the app like this we now have this client id generated for us and this is the key to how we can associate our client-side integration with our paypal account so let's copy this client id value to our clipboards let's remain logged into paypal and let's appropriately paste the relevant client id value to our index.html file here for the client-id parameter great while we are here let's remove the enable dash funding parameter here let's go back to paypal so for testing purposes paypal allows us to generate mock credit card details when we test our code we are going to use the generated mock credit card details to make a test payment we can generate mock credit card details by clicking the credit card generator menu option here and then i'm going to select the united kingdom as my country first and then to generate the mock credit card details we can press the generate credit card button here so let's copy the relevant mock credit card details and save them somewhere so that we can access them a little bit later when we test our application before we test the code let's make sure that we can navigate from our shopping cart razor component to our checkout component so to do this let's appropriately update the code within our shoppingcart.razer file then we must also ensure that we have an appropriate at page directive at the top of our checkout.racer file a user needs to be able to navigate directly to the checkout raiser component so we must include appropriate root template information following the add page directive and now we should be able to make a test payment through our application let's run the code let's add some items to our shopping cart let's proceed to check out let's appropriately enter our mock credit card details along with some appropriate made up data regarding personal information like address and phone number excellent now if we press f12 within our chrome browsers we can see the data sent back from paypal in the on approved callback method defined within the init paypal button method we have code to log data sent back from paypal after an approved order has been made we could implement code that extracts the relevant data from the returned data from paypal and update our application's database in an appropriate way depending on our requirement that functionality is beyond the scope of this course but hopefully this gives you a good enough insight of how to integrate the paypal functionality into your application but please read the relevant developer related information provided by your preferred payment gateway service provider for information on how to create relevant integration functionality that best suits your requirement and you can see here our custom description value that we created earlier in code has been sent back from paypal along with the other order information which contains the user id value and a guide value that our code generates for each order that is sent to paypal so let's finish the code for our checkout raiser component let's say that we want to display a summary of items that the user is purchasing on the checkout ui next to the paypal buttons so let's write the code for this please note this code can be copied from the relevant github repository i have included the location of the relevant github repository below in the description let's test the code excellent this is the 10th part and the penultimate video in a video series dedicated to building a shopping cart application on net 6. so we are nearly finished building our shopping cart application in this video we are going to create functionality so that a user can filter the products in our stores product catalog by product category we will write codes to query our database for all the product categories within our database and display them as menu items in the main menu contained within the sidebar section of our ui when the user clicks one of the menu items denoting a product category data representing the products related to that category will be appropriately displayed to the user right let's get started so in the first part of this course we created our database through ef core code first migrations a requirement to update the databases seed data or structure may arise for example due to a decision to include new functionality within the application or perhaps just to correct a minor mistake made when the database was first created and seeded with data through ef core code first migrations we have the agility that we need to make appropriate adjustments to our database during the development and testing phases of our application so before we start writing code we need to address a database related requirement we need to add a new column to the product categories database table where we can store relevant css code that denotes an icon used to represent a product category we are of course going to use ef core code first migrations to address this requirement so let's first update the product category entity class to include a new string property and let's appropriately name our new property icon css we are going to need an appropriate dto data transfer object to house the data that we send back to the client for when a client makes a request to the server for a collection of product category data so let's go to the shoponline.models project and create an appropriate class to represent the relevant dto let's go back to the shoponline.api project before we generate the relevant migration code let's open the shop online dbcontext class and update the relevant code for seeding our database within the onmodelcreating method so here we are including relevant font awesome css classes within the new field named icon css these classes will be appropriately referenced within our code to render appropriate icon images for each of the relevant product categories so let's create our migration and give it a sensible name great let's look at the migration code that we have just generated great let's run our migration through the update dash database command excellent so let's go to our shoponline.api project so if we look at the product repository class we can see that we have already written the code for returning a collection of product category objects we need to expose this functionality to the relevant clients so to do this let's create an appropriate action method within the product controller class let's create an extension method to convert the collection of product category objects to a collection of product category dto objects this may seem like a pointless exercise because the shape of the product category class is exactly the same as the shape of the product category dto class it is important to understand that even though this step may seem unnecessary that we are doing this due to design best practices why is this the design best practice in the future a new requirement may arise for example where a client may require additional data to be returned from the relevant action method we want to maintain a clear separation of concerns between the dto classes and the corresponding entity classes the reason for this is that the relevant dto classes can evolve independently from the relevant entity classes if required without affecting their counterpart entity classes so a dto class can for example be extended without affecting its counterpart entity class let's finish off the code for our action method great so let's go to the shoponline.web project and write the calling client code for retrieving a collection of product category data let's create the relevant service code let's add an appropriate method definition to the i product service interface let's implement the code for the interface that we have just created so our code in this method is appropriately requesting a collection of objects of type product category dto from the server great let's create a razor component that will be responsible for outputting the product categories as menu items inside our blazer applications main menu that resides within the sidebar section of our applications ui so within the shared directory let's create a razor component named product categories nav menu let's create a class named product categories nav menu base let's write code so that an object of type i product service is injected into our razor component at run time let's create a property of type i enumerable that is strongly typed with the product category dto type let's create a string property named error message let's override the uninitialized async method let's create code within the uninitialized async method that retrieves a collection of objects of type product category dto from the server and assigns the returned collection to the product category dtos property great let's implement the code for the product categories nav menu razer file so we need to create a using directive that references the shoponline.web.pages namespace so let's add the appropriate using directive to the underscore imports.razer file we are adding this using directive because we are going to add appropriate tags to the product categories nav menu razer file that reference relevant child razor components that have been added to the pages directory for example the display spinner child razor component so notice that we are creating a link that contains a category id parameter we'll later write code that uses this parameter value to query the server for a collection of product data that is related to a particular category denoted by the relevant category id value so we haven't yet written the code for the products by category raiser component we'll write the code for this razor component a bit later this razor component will contain code for displaying a collection of objects of type product dto that are related to the category id value that will be passed as a parameter to the products by category razor component so the next step is to reference our new razor component from within the razer component that contains the main menu that appears to the user in the sidebar of the ui so let's add the appropriate tag to reference our product categories nav menu razor component let's run the code and we can see that our product categories are now appearing as menu items within the sidebar however as you can see the style of the product category menu items are different from the home menu item because the codes that produces the category menu item is contained within a different razor component so to solve this i'm simply going to copy the css code from the navmenu.razer.css file and paste it into a new css file that we must name product categories nav menu dot razer dot css so this will result in the product category menu items being styled like the home menu item so we are flagrantly violating the principle of dry don't repeat yourself here i'm doing this deliberately to keep up the momentum and creating the code for this application so that i can effectively keep the focus on the aspects that are the subject of this part of the course you can of course centralize the css code for the menu items in adherence with the principle of dry however for the reasons i've just explained i won't address this issue in this part of the course great so let's move on to create the code for filtering the products by category let's go back to the shoponline.api project let's go to the i product repository interface let's create a new method definition within the i product repository interface the code that we'll implement for this method will be responsible for retrieving a collection of product data that is related to a particular product category so let's implement the code for the method that we have just defined within the product repository class let's create an appropriate action method to expose this functionality to calling client code great right let's go back to the shoponline.web project and implement the service related code regarding the functionality for retrieving product data related to a particular category id let's open the i product service interface and create an appropriate method definition let's implement the code logic for the method definition that we have just created so here we are appropriately requesting a collection of objects of type products dto that are related to a particular product category right let's create a razor component responsible for displaying the product data filtered by category on the ui let's name this razor component products by category.razer let's create a class named products by category base let's implement the code for the products by category base class firstly let's create a property that represents a parameter that will be passed into this razor component the value passed into this category id parameter will be an appropriate category id value note that we are able to declare that a property represents a parameter by decorating the relevant property with the parameter attribute let's create the other necessary properties for our razor component so we want our collection of products to be retrieved for a particular category only when the category id parameter is set so we can do this by implementing our code within a method that is called by blazer in response to a life cycle event occurring when our parameter value is set so to achieve this we are overriding a built-in blazer method named on parameters set async so let's write the code within the on parameters set async method our code simply retrieves the appropriate products data from the server based on the value passed into our category id parameter let's write the appropriate ui code within the products by category.razer file so let's first use the add page directive to appropriately declare the relevant root template information for our products by category razer component let's write code to inherit from the products by category base class let's implement the code logic so as you can see we can reuse our display products razor component that we created in a previous part of this course to display the relevant products data to the user let's run the code excellent so you can see that our product category menu items appear differently when compared to the home menu item so let's fix this in code so that our menu items are displayed in a consistent way to the user great let's finish off by adding an appropriate logo for our application excellent i hope you have enjoyed this video i look forward to presenting the final video in this series where we'll optimize our code to potentially create better performance for our application hi and welcome i'm gavin lon this is the 11th and final part in a series of videos dedicated to building a shopping cart application using blazer web assembly and web api on net six so we have now built our basic shopping cart application but is software ever really 100 complete at points there may be bug fixes to make we may need to upgrade our application with the latest technologies a requirement may arise to improve the overall performance of the application there may be parts of the application where ux user experience can be enhanced in this video we are going to look specifically at how we can improve the performance of our application by optimizing our code there are two areas where we can potentially enhance the performance of our application item number one in the web api component we are currently making two separate queries to the database when retrieving product data our code is returning both product data and product category data to the calling client to do this we are currently calling two separate methods in the product repository class one for retrieving details about the products from the product database table and the other for retrieving details about the product categories from the product categories database table so in this video to potentially enhance performance we are going to retrieve the product and category details through one query to the database instead of two the other area where we can improve performance is by using local storage within the blazer component to store both the product data and shopping cart data so that when our application needs to retrieve relevant product data or shopping cart data our code can retrieve the relevant information from local storage i.e data stored on the client within the user's browser as opposed to making a trip as it were to the server every time the relevant data needs to be retrieved so basically the travel time and retrieving the relevant data can be shortened in certain scenarios the data can be retrieved on the client instead of the server for content like this and much more please consider subscribing and please ring the bell so as to be notified of future content if you like this video please hit the like button and please feel free to share this video with anyone you feel may benefit from its content so let's attack the first item let's go to the shoponline.api project let's optimize the code on the server where we can make one query to the database to retrieve both product information and related product category information rather than use two separate queries for this purpose so the first step is that we need to modify the class representing the product entity so we must first add a public property to the product class that is of type product category let's add the foreign key attribute to our new product category property we can then pass an appropriate string value to the foreign key attribute that is used for declaring which property in the product class must be used for joining the product entity to the product category entity so this code will indicate to ef core as it were how we want to join the product entity to the product category entity let's go to the product repository class and first modify the get item method to appropriately join the product entity to the product category entity in the relevant link query so to do this we can use the include method like this we are establishing the join between the two entities through this lambda expression notice the product category property that we recently created within the product class for this query we only want to retrieve one item so we can use the single or default async method to filter the product data based on the relevant product id passed to this method then for the get items method the code is similar to the get item method but for the get items method we wish to return all the products that are currently stored in the products database table with the related product category information to the calling code so we of course don't need to filter the data so that means we don't need to use a method like the single or default async method in this query then the last method that we need to appropriately modify is the get items by category method if we open the product controller class we can see that we can now simplify the code here but first we need to appropriately update the relevant extension methods responsible for converting objects of type product to objects of type product dto so let's first update the extension method that converts an individual product to type product dto great then let's update the conversion extension method that converts a collection of objects of type product to a collection of objects of type product dto great we can now update the relevant action methods accordingly we no longer need to query for the category items in a separate query that we are using here to get a collection of category items so we've potentially improved performance of the server-side code through an appropriate code optimization exercise we are only dealing with a small amount of data so the performance improvement would probably be negligible but if we were dealing with large amounts of data the performance improvement would be more significant so let's look at the second way that we can improve the performance of our application the second way that we can improve the performance of our application involves an update to our blazer component so let's go to the shoponline.web project let's see how we can reduce the number of trips to the server we are currently making for retrieving relevant product and shopping cart data through the use of local storage so we could use javascript and blazer's javascript interoperability feature and write our own local storage functionality it turns out though we don't need to go to this kind of trouble because someone has already made available a new get package that contains the local storage functionality we need so let's invoke the nuget package manager window let's search for local storage and this is the package we want to install so let's install the blazered.localstorage nuget package for more details regarding local storage please navigate to this url basically the javascript local storage object allows you to save key value pairs in the browser note the local storage object stores data with no expiration date the data is not deleted when the browser is closed and are available for future sessions so the local storage functionality provided to us within the blazid.localstorage nuget package abstracts the javascript code for managing local storage so we don't need to write the relevant javascript code ourselves we are now going to create two services to encapsulate our local storage functionality so let's first create an interface named i manage products local storage service let's create two method definitions like this let's create an appropriate method definition for a method named get collection let's create an appropriate method definition for a method named remove collection let's create an appropriate service class to implement the methods defined within the interface we have just created let's create a constructor whereby we indicate that we want an object of type i local storage service and an object of type i product service injected into our constructor at run time note that the i local storage service type is a type provided by the blazer.localstorage nuget package that we have now installed so this type will be used to implement the necessary local storage functionality let's create a private method named ad collection this method simply retrieves the product data from the server and saves the relevant product data in the user's browser using local storage okay let's create a string constant to store the key that will be used to identify the relevant value in this case the relevant value is a serialized collection of objects of type product dto let's implement the code for the get collection method so this method first tries to retrieve the relevance data from local storage if the relevant data does not exist in local storage we can call the add collection private method to retrieve the relevant data from the server and save the relevant data to the user's browser using local storage the remove collection method simply removes the relevant data stored within the user's browser using local storage right let's create an interface within the contracts folder named i manage cart items local storage service let's create an appropriate method definition for a method named get collection let's create an appropriate method definition for a method named save collection let's create an appropriate method definition for a method named remove collection right let's implement the relevant code for the interface that we have just created so let's first create a class named manage cart items local storage service let's create a constructor whereby we indicate that we want an object of type i local storage service and an object of type i shopping cart service injected into our constructor at runtime let's create a constant to store the key that will be used to identify the relevant items stored using local storage the local storage item in this case will be a serialized collection of card item dto objects let's create a private method named add collection this method simply retrieves relevant data from the server and appropriately saves the data to local storage this method attempts to retrieve the relevant data from local storage if the relevant data does not exist in local storage the code retrieves the relevant data from the server and appropriately saves the relevant data to local storage let's implement the code for the remove collection method which involves appropriately deleting a collection of objects of type cart item dto from local storage notice that the key constant is used to identify the relevant local storage item let's implement the code for the save collection method which involves appropriately saving a collection of objects of type cart item dto to local storage so we haven't yet registered the ilocal storage service type provided in the blazer.localstorage package with the dependency injection system so let's open our program.cs file and apply the code to register the ilocalstorage service type for dependency injection so we can use the add blazer local storage extension method for this purpose we must then also register our two new service classes that we have created to abstract the relevant local storage functionality with the dependency injection system so let's now implement the relevant local storage functionality within the relevant razor components in order to hopefully increase the performance of our blazer component let's open the products base class this is the base class for the razor component that first loads when our application is first launched let's create the code to ensure that our two local storage services are injected into this razor component let's say that when the product's razor component is loaded we want to clear the relevant local storage items from local storage this will force our code to retrieve the relevant data from the server at this stage then subsequently we want the relevant data retrieved from local storage to enhance performance so let's create a private method named clear local storage and use the relevant functionality we have created within the relevant services to remove the relevant data from local storage let's call this method from within the uninitialized async method then instead of going straight to the server for our data let's use the appropriate local storage service object to first check to see if the relevant data resides within local storage of course in this case we are clearing the data before this method is called which will force our code to retrieve the data from the server however our code will subsequently save the data retrieved from the server to local storage which means that when other razer components retrieve the relevant data the data will be retrieved from local storage on the client side which means an unnecessary trip to the server will be avoided so this gives us an idea of how we are able to increase performance of our application using local storage we can also use our manage cart items local storage service object to retrieve any cart item data that may be saved to the user's shopping cart like this so in this case this code will retrieve the relevant data from the server and save the data to local storage any data retrieval of items within the user's shopping cart can then be done from local storage and therefore trips to the server are saved and the performance of our application is potentially enhanced let's appropriately update the shopping cart razor component let's write the code so that an object of type i manage card items local storage service is injected into this razor component at runtime in the uninitialized async method let's replace the code that retrieves the relevant cart item data from the server to get the relevant data from local storage when a user updates the quantity of a particular item saved within the user's shopping cart we must update the relevant local storage item this is because of course the relevant shopping cart has now changed we can appropriately implement the safe collection method for this purpose we must also use the appropriate local storage service to implement the code to update the relevant local storage item when a user removes an item from the user's shopping cart let's implement the relevant local storage related code for the product details razer component so this component is responsible for displaying details for a particular product this razer component also contains functionality for adding a product to the user's shopping cart let's first create a private property to reference the shopping cart items collection here because when the user adds a product to the user's shopping cart we want our code to update the relevant local storage item we no longer only want the code to update the relevant shopping cart on the server we need to keep the client side local storage data up to date as well so let's first write code to update our shopping cart item's private property with data retrieved from local storage within the uninitialized async method so within the method responsible for adding a new item to the user's shopping cart we need to write code that not only updates the data on the server but also updates the relevant local storage item so we can implement the desired functionality in code like this we can also now implement code that gets data for an individual product from local storage great let's appropriately update the products by category razor component to include local storage functionality let's write code so that an object of type image products local storage service will be injected into this razor component at runtime let's write a private method so that the products filtered by category id are retrieved from local storage let's appropriately call our new private method from within the on parameters set async method lastly let's appropriately update the checkout razer component with our local storage functionality great let's run the code excellent that definitely seems to have made a positive difference to the performance of our shopping cart application if you've made it to the end of this course well done you have learned quite a lot about laser web assembly and web api we have also learned how to create a basic spy application where the vast majority of the code is implemented using c-sharp i hope you have enjoyed going through this course as much as i enjoyed creating it for content like this and much more please consider subscribing and please ring the bell so as to be notified of future content if you liked this video please hit the like button and please feel free to share this video with anyone you feel may benefit from its content i really enjoy engaging with you in the comments section so please feel free to leave a comment the latest code can be found on github a link to the relevant repository has been included below in the description thank you and take care
Info
Channel: freeCodeCamp.org
Views: 219,716
Rating: undefined out of 5
Keywords:
Id: sHuuo9L3e5c
Channel Id: undefined
Length: 336min 44sec (20204 seconds)
Published: Thu Apr 28 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.