MEAN Stack: Learn by doing a Ecommerce App with Angular 12, PrimeNG and NodeJS [2024] | Alex Bakker | Skillshare
Search

Playback Speed


1.0x


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

MEAN Stack: Learn by doing a Ecommerce App with Angular 12, PrimeNG and NodeJS [2024]

teacher avatar Alex Bakker, Web, A.I. and Mobile Development

Watch this class and thousands more

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

Watch this class and thousands more

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

Lessons in This Class

    • 1.

      What Are We Going to Do

      5:40

    • 2.

      What is MEAN Stack

      3:38

    • 3.

      Who can take this course

      3:13

    • 4.

      Installing Nodejs

      1:55

    • 5.

      Configure MongoDB Atlas

      1:57

    • 6.

      Installing PostMan to Test our API's

      1:50

    • 7.

      Starting With The Backend

      2:44

    • 8.

      Overview to our RESTful API

      3:26

    • 9.

      Creating the Backend Server with Express

      6:38

    • 10.

      Reading Environment Variables

      4:59

    • 11.

      Create First API Call & Parsing Json Data

      6:47

    • 12.

      Logging API Requests

      2:38

    • 13.

      Installing Mongoose and Connect to MondoDB Database

      10:02

    • 14.

      Using MongoDB Atlas

      3:19

    • 15.

      Read Write Data to Database Using API

      14:31

    • 16.

      Analysing the E Shop Database

      5:40

    • 17.

      Create Backend API Routes & Schemas

      9:48

    • 18.

      Enabling CORS & Why Do We Need It

      3:15

    • 19.

      Backend : Products & Categories

      2:44

    • 20.

      Products Model Schema

      6:12

    • 21.

      Categories Model & Schema

      1:13

    • 22.

      Add and Delete Categories

      12:39

    • 23.

      Get Categories and Category Details

      2:48

    • 24.

      Update Category

      4:09

    • 25.

      Post a New Product REST API

      5:55

    • 26.

      Get a Product & List of Products REST API

      3:47

    • 27.

      Show Category details in the Product Populate

      3:01

    • 28.

      Update a Product REST API

      3:17

    • 29.

      Delete a Product REST API

      3:45

    • 30.

      Get Products Count for Statistics Purposes

      3:43

    • 31.

      Get Featured Products REST API

      5:18

    • 32.

      Filtering and Getting Products by Category

      6:54

    • 33.

      Changing "_id" key to "id" - more frontend friendly

      2:05

    • 34.

      Users & Authentication

      2:22

    • 35.

      Users Model & Schema

      2:01

    • 36.

      Register a New User REST API

      5:18

    • 37.

      Hashing the User Password

      2:57

    • 38.

      Get User and List of Users Excluding Password

      2:56

    • 39.

      Login a User REST API & Creating a Token

      11:25

    • 40.

      Protecting the API and Authentication JWT Middleware

      6:07

    • 41.

      Authentication Error Handling

      5:07

    • 42.

      Excluding REST API Routes From Authentication

      6:48

    • 43.

      Add More Secret User Information to Token

      2:38

    • 44.

      Users & Admins

      6:46

    • 45.

      Get User Count REST API

      2:16

    • 46.

      Backend: Orders

      1:53

    • 47.

      Orders & Order Items Model & Scheme

      5:00

    • 48.

      Array of Refs Example of Link Order to Order Items to Products

      1:12

    • 49.

      New Order & Create Order Items on Posting New Order

      11:42

    • 50.

      Get Order Detail and Populate Products in Order Items and User Data

      8:10

    • 51.

      Update Order Status REST API

      4:29

    • 52.

      Calculating Total Price of one Order with Mongoose

      7:01

    • 53.

      Get Total E Shop Sales using $sum

      6:42

    • 54.

      Get User Orders

      3:25

    • 55.

      Backend: Product Image & Gallery Upload

      2:22

    • 56.

      Configure Server Side Upload

      11:24

    • 57.

      Testing Image Upload with Postman

      4:55

    • 58.

      Validating Uploaded File Types

      6:16

    • 59.

      Image Upload With Product Post Request

      1:10

    • 60.

      Image Upload With Product PUT Request

      3:19

    • 61.

      Product Gallery Multiple Images Upload

      7:17

    • 62.

      Excluding Uploads Folder From Authentication

      2:57

    • 63.

      E Commerce NgShop App Page Structure

      4:13

    • 64.

      Creating Project Folder and Installing Angular

      3:41

    • 65.

      Components, Modules, Services in Angular

      3:27

    • 66.

      What is NX & MonoRepo?

      8:25

    • 67.

      Overview on NX Real World Example - E-Shop

      10:49

    • 68.

      Installing NX

      1:35

    • 69.

      Installing Extensions for Rapid Coding

      3:47

    • 70.

      Creating Nx workspace for Your Team or Company

      10:59

    • 71.

      Creating the Applications (Admin Panel App)

      4:12

    • 72.

      Creating Application Level Components

      8:52

    • 73.

      Routing to Application Level Components

      5:02

    • 74.

      Master Page with Header & Footer

      3:11

    • 75.

      Naming Component Selector Rules with ESLint

      2:57

    • 76.

      Enabling Live Coding Linting

      5:22

    • 77.

      NX VSCode Extension

      5:14

    • 78.

      Creating Shared Libraries Through Command Line

      7:32

    • 79.

      Creating Shared Libraries Through NX Extension

      7:48

    • 80.

      Creating Components Inside Libraries and Use them in the Apps

      14:11

    • 81.

      How to Call Libraries Check Paths

      2:19

    • 82.

      What about Shared Style Files

      8:45

    • 83.

      Structuring Style Files For Applications (NgShop + Admin)

      25:30

    • 84.

      PrimeNG Material Installing 3rd Party Libraries and Include Styles

      9:40

    • 85.

      Installing PrimeNG

      4:48

    • 86.

      Using PrimeNG Components in Our Project

      2:44

    • 87.

      Overrride PrimeNG fonts

      1:41

    • 88.

      Installing The Grid System

      3:47

    • 89.

      Introduction: Admin Panel Overview

      3:08

    • 90.

      Building the Shell

      7:01

    • 91.

      Creating The Routes

      4:10

    • 92.

      Admin Panel Navigation Sidebar

      13:34

    • 93.

      Disable Backend Authentication For API's For Frontend Purpose

      1:39

    • 94.

      Categories Service Get Data from Backend

      8:39

    • 95.

      Use Categories Service in Categories List Component

      6:26

    • 96.

      Add Categories From Use PrimeNG Forms

      9:58

    • 97.

      Add Categories Form Bind Form Data

      14:25

    • 98.

      Add Categories Form Send Data to Backend

      14:05

    • 99.

      Delete a Category with Confirmation Dialog

      12:22

    • 100.

      Edit a Category

      25:07

    • 101.

      Add Color Picker for Category Color

      8:23

    • 102.

      Refactoring Code & Beautify Categories Table with More Features

      7:42

    • 103.

      ESLint Fixes

      4:55

    • 104.

      Products List Table

      9:31

    • 105.

      Products Service and Get Products From the Database

      8:14

    • 106.

      Show the Product Image in the Table

      2:21

    • 107.

      Build Products Form Template

      13:36

    • 108.

      Dropdown for Product Categories with Filter

      5:03

    • 109.

      HTML Editor for Product Detailed Description

      5:07

    • 110.

      Product Image Upload Field with Thumbnail Display

      10:20

    • 111.

      Submit a New Product as FormData

      18:57

    • 112.

      Edit a Product

      8:57

    • 113.

      Dynamic Validation Image Field Is Not Required In Edit Mode

      4:31

    • 114.

      Add Products Table Pagination

      1:26

    • 115.

      Users List Table and User Services

      7:03

    • 116.

      Users Form Add and Edit

      8:29

    • 117.

      Retrieving Countries to Dropdown Using i18n iso countries

      9:37

    • 118.

      Retrieving Countries solution

      2:56

    • 119.

      Create Orders Components Table, Details and Services

      13:02

    • 120.

      Order Status

      8:30

    • 121.

      Order Details Component

      17:07

    • 122.

      Display Order Items with Subtotal Prices

      10:08

    • 123.

      Order Address and Customer Info

      2:51

    • 124.

      Update Order Status

      18:00

    • 125.

      Create Login Page

      22:17

    • 126.

      Login Service and Retrieve the Token

      12:54

    • 127.

      Create Local Storage Service and Store Token

      8:31

    • 128.

      Create Admin Panel Route Guard

      12:10

    • 129.

      Read Token Data isAdmin and Expiration

      10:31

    • 130.

      Enable Back Backend Authentication For API's

      1:44

    • 131.

      Intercept HTTP requests with Token

      11:41

    • 132.

      Logout User

      5:04

    • 133.

      Dashboard Styling

      12:06

    • 134.

      Dashboard Statistics Services

      11:30

    • 135.

      Routes Refactoring

      8:45

    • 136.

      End Subscriptions for Performance

      9:08

    • 137.

      Architecture of the Components in the Repository

      2:58

    • 138.

      Preparing Structure and Styles

      5:47

    • 139.

      Styling the Header

      15:12

    • 140.

      Product Search Component

      12:45

    • 141.

      Banner Components

      19:06

    • 142.

      Animate Banner

      7:57

    • 143.

      Overriding PrimeNG Button Style

      7:20

    • 144.

      Categories Banner

      27:35

    • 145.

      Product Item

      13:25

    • 146.

      Featured Products Banner

      7:10

    • 147.

      Styling Product Item

      4:39

    • 148.

      Styling Product Item

      1:13

    • 149.

      Products Page Reuse Components

      17:04

    • 150.

      Filtering Products by Category

      19:41

    • 151.

      Category Page

      13:30

    • 152.

      Product Details Page

      33:10

    • 153.

      Product Gallery Image Component

      28:35

    • 154.

      Cart Service in LocalStorage

      13:47

    • 155.

      Add Products To Cart

      20:58

    • 156.

      Restore Shopping Cart on Reload

      2:40

    • 157.

      Observe Cart Count Badge in The Header

      24:55

    • 158.

      Add Product To Cart With Quantity

      5:42

    • 159.

      Cart Page

      25:37

    • 160.

      Connect the Cart with Products

      7:10

    • 161.

      Remove Circular Dependencies Between Libraries

      14:09

    • 162.

      Remove Products From Cart

      10:08

    • 163.

      Order Summary Widget

      9:46

    • 164.

      Update Cart Item Quantity

      13:23

    • 165.

      Checkout Page

      19:06

    • 166.

      Placing Order

      24:55

    • 167.

      Thank you Page

      8:48

    • 168.

      Enable Login On Checkout

      6:05

    • 169.

      What is NGRX

      6:33

    • 170.

      Let's Do Create NGRX State Store in Users Library

      8:26

    • 171.

      Diagram Building User Session Process

      4:39

    • 172.

      Init User Session Service

      4:37

    • 173.

      Creating Build User Session Action

      5:13

    • 174.

      Creating the UsersState

      7:07

    • 175.

      Create Effective Actions if Token Valid or Not

      6:57

    • 176.

      Creating Build Session Effect

      8:04

    • 177.

      Calling Action on Invalid Token

      10:17

    • 178.

      Observe StateStore Fields Using Selectors

      6:22

    • 179.

      Auto Fill Checkout Page Based on Logged User

      9:16

    • 180.

      Refactoring + Place Order with Current User

      5:24

    • 181.

      Stripe Payment Gateway

      4:14

    • 182.

      Installing Required Libraries

      3:24

    • 183.

      Checkout Payment Flow

      2:37

    • 184.

      Creating Checkout Session API

      15:07

    • 185.

      Creating Frontend Checkout Session Service

      20:57

    • 186.

      Placing Order After Successful Payment

      6:30

    • 187.

      Placing Order in Thank you Page

      10:35

    • 188.

      Linting Project with NX Lint

      15:49

    • 189.

      NX Migrate Updating The Project to Latest Version

      13:01

    • 190.

      Installing Heroku and Prepare Git

      8:24

    • 191.

      Optional Creating Production Database

      3:59

    • 192.

      Setting Development and Product Environment Variables

      6:17

    • 193.

      Deploy the App and Test It

      12:02

    • 194.

      Preparing Git and Github Pages

      6:48

    • 195.

      Building Frontend Apps

      4:57

    • 196.

      Deploying Frontend Apps to Github Pages

      13:08

    • 197.

      Building Multiple APP's, Create Scripts

      10:24

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

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

441

Students

--

Projects

About This Class

Start Coding Like The Biggest Software Companies in The World!

I don't like to do theoretical things, I like to do something Practical!

This is not a reading documentation course. You have here a real-world project to learn from, and you will see the exact place of every feature of every technology used in this course.

You will learn how to build a Full Web Application  MEAN stack using Angular.

In this course you will learn to use technologies like:

For Frontend :

- Angular 12, And Structuring your Project

- NX Monorepo

- PrimeNg Material Library

- RXJS

- NGRX For User Session

- SCSS

For Backend ( WebAPI )

- NodeJs

- Express

- MongoDB

- JWT (JSON Web Tokens)

MEAN Stack is an acronym for MongoDB, Express, Angular and Node.js – whereby all these four are integrated to form solution-built full-stack JavaScript applications.

Almost, every web development player in the market is trying to become a MEAN stack app developer.

You will learn the basics of building Angular apps. First, you will discover how to set up your environment in record time, including how to debug and run your app. Then, you will explore the Angular component library and how to style your layouts for a great feel. Finally, you will delve into how to call an HTTP API from your app.

When you’re finished with this course, you will have the  skills and knowledge of Angular, Nodejs And Architecture skills which are needed to tackle profitable, cross-platform  projects without learning at least multiple programming languages.

Also, this course is a perfect to the concepts of server-side web development. You’ll learn the different parts that make up the back-end of a website or web application, and you’ll gain familiarity with the Node.js runtime environment. After this course, you’ll be set up to explore popular Node frameworks like Express.js to build great API's.

You learn in this course how to use mongoDb without any installing extra tools, MongoDB is now on cloud, so you will store your database in safe place!

Main Features:

  • E-Shop APP From Scratch

  • Admin Panel to manage the E-Shop From Scratch

  • Great E-Shop Architecture

  • Admin product management

  • Admin user management

  • Admin Order details page

  • Changing the orders states (shipped, delivered ..)

  • Handling cart

  • Product Filtering

  • Login And Authentication

  • Checkout process (placing orders)

  • Using Database in the cloud

  • Deployment to Production Servers.

  • Using External Libraries

  • and much more ...

Meet Your Teacher

Teacher Profile Image

Alex Bakker

Web, A.I. and Mobile Development

Teacher
Level: All Levels

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

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

Transcripts

1. What Are We Going to Do: You will build a great application which is an e-commerce platform. And with this e-commerce platform, you will be able to do some animations. You will have banner, you can control them. You will have a categories for your products and you will have a featured products banners and as well, when you go to a specific category such as this one, you will see only the products which are under that category. And as well, you will be able to see the featured product here, which you can control in the admin panel as I will show you and as well, when you go to the product detail, you will see all the detail about their product that like you see with a name or title and the rating of the product, that quantity. And you can add it to your cart and you will see full description, which we can be right in the admin panel. And also you will have a gallery of the product. So you will be able to build this gallery by your hand. We are not going to do this gallery using some library. No, we are going to do it by hand. You will learn how to use the reality of components in Angular. And as well, we will see how to go to their cart and add items to their cart. And you will see also the notifications and the Toast notifications. And you will be able to go to the cart. You can manage your cart, you can delete items from the card. You can as well change the quantity and everything will be calculated immediately after you update the quantity. Everything is observed. So we are going to use our x js to observe our cart and it gets updated immediately every time the user is updating or adding a product to the cart. Also, we will have a checkout page where the user can enter his data and place an order. And he can also do get the order and get a thank you page. And as well, we will work with the admin panel. Admin panel will contain all the dashboard which you need. How many orders, how many products all comes from the database, from rayon data, nothing is hard-coded. And also, you will learn how to make the products panel so you can manage the product, delete them, or edit them, or even add new product. In adding new products, you will be able also to use a great component, such as these grades drop down switch button. You will use also a great editor. So it will reflect for you all information in the front end. So you will not have headache to style the component or the description of the product, but you will see how you can let the user stylet with a user-friendly editor as you see here. And as well, you will learn how to upload images to your server. And then you'll be able to use all of those images and then create a gallery for your application and for your product as well. Something different with categories, we will use the icons. We will use also some filtering on the table or sorting. And as well, you will use also a color picker, as you see here. We can also use this great component to pick up colors and update also the categories. All work is with real data, nothing is fake, nothing is hard-coded. We are going to learn really like a practical. And over that, you will learn a great structure with Angular. How you can structure your files, how you can build a shared styles, and how you can build a reusable modules and components, which can be built like any big company. Also, there is an orders. You will be able to manage the orders and then you can change the state of the orders and it will be reflected in the admin panel as well. And you will see as well the order detail. We will grab complicated data structure from the database using our API with NodeJS and also the customer M4 and connecting customer info with the order. And as well, we will do a management for the user. We will be able to see all management of the our users. And we will be able to assign the role of the users if he is admin or not. So he will be able to look into our page or to the admin page or not. And also we will provide with like a great look in, we will use the login, the authentication, the Web Tokens to authenticate the user and specify if the user is admin or not. All of that. You will learn it through Angular, through an X Mono repo. And you will learn as well how to build a great application like this application, you will learn a lot of things. You will learn styling. You will learn how to structure the project. You will see how big companies are coding, like how they are creating shared modules. And they will be able to develop faster, more and more applications. At the end of this course, you will learn a lot of things, NodeJS, MongoDB, and as well angular, and then an X Mono repo and RX and also the RX JS observables. You will understand them in practical. So are you ready? Let's get started for it. 2. What is MEAN Stack: Okay, in this lecture we will know what is mean stack. But first, let me introduce to you what is a technology stack in general? A tech stack is a list of all technologies and services that came back that they are used for building and running one single application. For example, the social side, Facebook, is composed of combination of coding frameworks and languages, including JavaScript, HTML, PHP, and React js. And this is Facebook technology stack. For example, I have listed here a mean stat, which is MongoDB Express Angular Node.js, as we will explain later, lamp is using the technologies Linux operating system, Apache server, MySQL database, and as Will PHP programming language as well. Married is MongoDB, Express, react or React Native and NodeJS. So what is mean stat means stack is using for technologies. So for database where I am going to store my data, I'm using MongoDB. Mongodb is a very sparse database, which is providing me with many functions that I can retrieve and filter my data easily. Express is used for building web APIs where I am getting and creating or deleting data from my database. And NodeJS is the famous framework for building a back-end applications and running web servers. And finally, Angular. Angular is a main purpose of our course. We are going to learn a lot about Angular. Angular is a front end framework provided by Google to build mostly web applications and also cross-platform applications to build your application on web or on mobile devices. Provide you with a great structure to architect your application and make it easy to be combined altogether using a great tools and also providing a very fast performance and secure production builds. Learning. All of those technologies alone will not fulfill your experience to learn how these technologies can work together. Because if you don't do any practical work or a real-world project, you will not learn them in real. You will just see courses which they are only reading documentation of each technology. But here in this course, we came up with idea to bring a full functional e-commerce website. And with this website, you will use the MongoDB and connected with Express. And express will be connected with Angular and all of them interacting using Node.JS. Every technology has responsibility. And we are going to see in details how to implement this responsibility in a real-world functional application. Otherwise, I am sure you will not learn it. You need a real-world application course to learn that. 3. Who can take this course: Okay, in this lecture, I want to explain who can take this course. What are the course requirements? So for me, I would say that if I got already a small basic Angular calls about like a basic knowledge of Angular, then this course is fitting for me. Like you need a very, very basic Angular. Like you need to know what is component, what is service, what is module? Even I explain them as well quickly. But when you do something practical, you will understand them. I did it in a way, like at the beginning. I explain them in very detail. And then by time, because we are going to create multiple components, multiple services and multiple modules, you will get used to them. You need to know as well a basic knowledge with TypeScript. So in this case, basic knowledge with TypeScript and JavaScript is really enough to enroll and go to this course. As well. We need a styling and templating. Html and CSS knowledge is also required. So you will understand the CSS code which I am typing, even I am explaining it point-by-point and I am showing you how if I am putting padding top, what will happen? How if I change the font color, how I make a box-shadow, how I make border for the button, et cetera. So all of these three information you need to know before you enroll the course. If not, I would prefer for you to follow this course very slowly, because even that, I explained all of the points which are mentioned here. But I prefer students who have a very basic knowledge about angular. And also I would like to mention that this course is made in beginner way. I didn't make it very complicated. For example, I am not using very complicated glasses structure and also like how I can make the relations between classes a lot of extension and inheritance. No, I didn't do that. I made it with a basic knowledge. So who is freshly finished Angular course, theoretically or practical? He can also see how the things can be implemented and it will expand your knowledge about Angular to build more and more applications and you know how to structure them as well. This talk is applied on the back-end part about NodeJS. And NodeJS, we will start from scratch and you will see what I am meaning with every word I am doing there. So that's it. If you have any knowledge, also, this course is good for you. But I, as I told you, you need to follow it very slowly. You need to repeat multiple staff. You need to repeat again and again some videos. Then you will get the information and you will understand that it comes Ailey easier for you after that. 4. Installing Nodejs: To start development, always we need the package management. The package management comes with NodeJS application. So to install it just plays in Google NodeJS and go to Download. And you will see the download for all operating systems. For example, I have here for Windows and also I have for Mac OS. There are two types like LTS, which is recommended for most users, and the current, which is the latest features. Better to get always a stable version, which is recommended for most users. Here, you can choose your installation based on your operating system. And it will be simply an application, like as any application you can install. So after that, you can download this application and run it. And it will be like any normal application installation. So to be sure, after that you finish all of these steps. You need to run some MPM comments. So to run mpm commands, we can use Visual Studio Code. After opening the Visual Studio code, you will see here the latest projects you have. But for example, we need to open the terminal of Visual Studio code. So I will go here and say Control and J. And then I will have the terminal opened. And in terminal, we can, for example, place a comment NodeJS. So we can say, for example, NPM version. And we would get the full detail virgin about the installed Node.js. After that, we will be able to use NodeJS package management, where there are many libraries we can use in our application and developments. 5. Configure MongoDB Atlas: For our e-shop, we need to have a database. And the database, we don't need to install any software. We will use MongoDB, Atlas. Mongodb offering now an online database storage, which means that the database is already in the Cloud. What we need to do just to go to the URL which I attached with this lecture and create an account here and sign up and then look into your account. After logging, you will see this screen that you need to create a project. So first of all, you need to create a project for our e-shop. So you go here and say, I want a project which is, for example, each hub. And I click Next. And then creating the project. After that, the project requires a cluster. So we need to build a cluster where we offer our database. So here, there are shared clusters, which is for free. You can use it and choose the closest server to your country. For example, I will use this one, the default one. And then after creating the cluster, we are ready to create our database. The database in MongoDB called collection. So you need to go to the collections and create a new one based on your need. We have already one which we created for the course in the project 0. Here there are collections at I created multiple databases. So your part is just to create an account and create cluster and create your own collection, which we will use in the course. We will see later how to make the connection between our back-end code and the MongoDB in the Cloud. 6. Installing PostMan to Test our API's: When we are creating APIs, we need to test them. You can test your APIs with a front end application like React or Angular or Vue js. But we are going in this course to start with the backend first. So the best way to do that and test the APIs is installing a tool called Postman. Let's go to Google. You go to the download Postman. And here you will find based on your operating system. So here you will choose download the application. And after it gets downloaded, it will be a normal setup like any application. After opening the downloaded file, you will get notification if you are using Mac OS. And it will ask you to move this application to application folder. And after that, you will see this application is located in your application folder. The same thing for Windows. It's normal installing like any small application. After opening the application, you will be able to test APIs. Let's test one. When you go to Google and type JSON placeholder, you will see the first link is some fake APIs. So you can test a GET requests or post requests. So let's try this one. It says here. As a GET request, I go to the Postman and then I open a new tab with the GET request and place the link which I copied from JSON placeholder and press Send, I will get a response. This response comes as a JSON. And in the same way, we are going to build our APIs. 7. Starting With The Backend: Welcome to the third section of this course. We are going to have introduction about starting with the back-end. What is a backend? In software engineering, the terms front-end and back-end referred to a separation of concerns between the presentation layer and the data access layer. So any web application and mobile application is considered as a front end. Back end is the part where I am holding data. Again, a database or a file server. And the server itself can be considered as a back-end. So let's have it like this. The front end is showing the data and the backend is holding this data in some secure place called server. We need somehow to handle these data which are stored in the server and serve them to the client. And using some programming languages like Java, SQL, and also no GS, which we are going to do in this course, to send this data to the client in a beautiful way, to render it in HTML, CSS, and JavaScript libraries. So in the next lecture, we will see how the front end can communicate with the backend to grab this data, which is called RESTful APIs. 8. Overview to our RESTful API: Let's take a look to our RESTful API to see how to exchange data between the client and the server. What is the architecture of RESTful API? We have the client and we have a server, and they are exchanging data through HTTP protocol. This is the basic concept of RESTful API. There are also include operations to create data, read data, update data, and delete them. Its operations can be done through HTTP protocol. There are specific methods of HTTP protocol which doing these operations, which we are calling operations at first, what is the difference between RESTful API and the front end route? The RESTful API is bringing data. The front end drought is showing the data or rendering a specific page. When you open your browser and put RESTful API link, if you have access to get these data, then you will get a string which consists of JSON or XML file. Http protocol is able to render a page with HTML CSS and bring your data. So HTTP methods in general, they are GET, post, PUT, and delete, which are the crude operations. But in HTTP methods, they are called like this. So I am sending a request to the database or to the back-end in general to get through rest API some data. For example, getting a product list through the API, it will give me array of list of products. Getting a single product, bypassing the ID of this product, it will give me JSON file with all detail of the product. When I want to update a product, I send a PUT request with the idea for the product and also attaching the new data. And the response will be the same product, but with a different data. And deleting a product is just passing the ID of the product with delete request. Creating a product, need to post a new product. So I am using the main route of the API of the products and then I am passing any new data, the data which for example, name of your product and the image, and that is ponds, will be a new ID with the new name of the product and of course, the image. Those are our API requests to get the data or post or delete or update data in the server. And I am using api slash v1, which is meaning the version one. So when you want to update your API in the future, you add a new version. So they users are still able to use the older versions of your API. The same thing for orders and the users. So in this case, you have all the same sequence, but you just need to plan your data, right? Creating a web server with NodeJS is very simple. Let's see that in the next lecture. 9. Creating the Backend Server with Express: Let's start to create our back-end server, or let's say our web server, where we will call our APIs to the client. After we have opened our Visual Studio Code to the folder back end folder, as we structured it before, we run a command npm init in MPM in it, it will ask us for a package name. I put e-shop, a virgin. I press Enter description, let's say some back end for the e-shop for example. And then the entry point like where the application will start, I put app.js and then some, another comment. We keep pressing Enter and then it will ask us everything is okay. We press Enter. Then we will see a package Jason is created. So let's create now our file up js, where we will start our entry point of our application. So I will put here, for example, console.log, Hello World. And then it will print Hello World when I am running this application. But how we will run this application, I advise to use a library called NADH Monde, which is a utility that will monitor for any changes of our source code when we press Control S or save this application JS, it will restart the application again automatically. So after we install this library, we see it is in independency in a package JSON as a custom script, we can add it here, like it's a comment to start the application using Node monitor. So I can say start node monitor or node moan. App dot JS. In this case, I will have the application started with the entry point file app.js. Let's try it now. Let's save ab.js and then write npm start. And after I started the application, I will see Hello World. And the application is still running. So it's detecting any change I do in the application. So I say helloworld with the change was exclamation mark, and I see it's changed. Let's change the world E-sharp. We will see hello e-shop. That's great. So till now we have only a running application, but we don't have any server yet. So to create a web server, let's install Express, which is a famous library from Node.JS to host a server. So after doing this installation, I will see it also in dependencies. But let's remove this console log and it create a constant, call it express and call the library express using the keyword require express. It will call it automatically from node modules. And let's create a constant which is called app. And this app with call a function called Express, which we mentioned or defined before. This web server requires listening to a specific port. So I say up that listen. And I specify, for example, 3 thousand as a port. And there is a callback. Callback will give us, we all will be executed when there is successful creation of the server. So in the callback, I can print any message in the console. For example, I will say the server is started now or the server is running now on the link local host with 3000 port. So now let's run the application again. I will say npm start. And we will get some error because I am running the server already. So let's start it off and I run it again. I will see local host or the server is running on localhost 3000. When I open the browser and visit this URL, localhost 3000, let's see what we will have. I put it here and I see that come up, get, cannot get because I didn't specify any initial route for the application. We create. Now the initial route or the root, we can say app dot get. We will see Express is providing us with all HTTP requests. For example, PUT, delete, and also post. So forget. It will accept two parameters. The first one is the route itself. For example, I will say the initial route or the root. So in this case, I will ask for a callback. The callback will have the response which I will send to the client when he will call this route. So I say in the callback response, dot sand, for example, let's say a message, we can call it hello or API, not Hello World. So now we have this API. Let's save, and now we can run the application again on the browser. The application will call a getMethod and we will get as a response, this hello API. So as a recap, we saw how we created our own server or web server with express. And we were watching our changes with node Monitor and how we call this application get to initialize a route. And we run the server under a specific port we saw before. We need to have an API and a version in the URL of that out. So let's see how we can create that with environment variables in the next lecture. 10. Reading Environment Variables: Okay, so let's start with environment variables. Environment variables normally are used as a public variable, which are used among the application. So for example, I want a public variable for API URL. So this API URL, which will be prefixed for every route which I use for my application or for my API. So as we saw before that every API we had, it's prefixed with something like slash, api slash version one. And this mean that every API in my application will have this URL. And then API version one. And then I say, for example, products. And then I can post, delete or create some data to this API. So now let's see how we can read this prefix. So I don't want to repeat in my API is always the string. So I can fix it in some constant which is readable from everywhere. And then I can pass it to the mike, to my strings routes, and then it would be readable in that route. So to do that, first, normally, in not the Node.JS, normally we have an environment variable called dot n or environment file. And what example I pass a variable name which I want it, any name you can, for example, API URL. And then I can say the string which I want to pass, which is api slash v1. And in this case, I will have this API URL is defined everywhere in the application. But first, how we can read this variable from this file in our application, there is a library, we can install it from MPM packages. And it's called dot-dot EMF. So we can't say npm install dot EMF. And this library normally is available always. And we can use it in the application JS in the route in the root, No problem. So we can say define or we can say require this library. So does't EMF slash conflict. And normally this should be in a string. So when I say require this library, then I will be able to use some specific constant to get these values from the M file. So I will go here and define a constant. Let's call it for example, API. And then we can say process dot, dot, then the name of the variable which I created here. So I can say API on the score URL. So let's save everything. And now let's try to print this variable to see if it's really reading from this file or not. So let's do it on start when we started the server. So I will say console.log, the API for constant. So then I will start my server, mpm start. And here it is, we have now defined already. So in every route I have, I can define or pass this API variable plus the route which I want, for example, products. So in this case, I will have the prefixed API version one plus products. We will see that more in detail in the next lectures to see how to create the route and how to build it and how to call it. The most important thing you need to know now that we can create the public variables in this file and read them anywhere in the application. So in this case, I want to store, for example, the database string or connection string. I can store it here in this file and also, for example, some secret for authentication, I can also store it here. And when I want to deploy the application to the production server, I'm going to change these variables. So we will have also another file, for example dot EMF, but for production server, we will see that of course in the lecture where we will deploy the Node.JS application. So now let's move to the next lecture where we will create the real API and how we will send JSON data through it because we need JSON data for our e-shop to exchange with the front end the information about the products and the order and et cetera. 11. Create First API Call & Parsing Json Data: Now we are going to see how to exchange data between front-end and the back-end. We saw previously how to exchange data with the front end with the GET request. So we send Hello API. But what we did is only exchanging a string, which is hello API. So we need to exchange JSON data. For example, the product is an object, consists of ID, name, image, and the price. So now let's simulate the products API. So at first, Let's have the nice prefix as before. So I am going to use the back ticks, which are very helpful to combine between constants and strings without using this plus. So now, let's remove this part and create a backticks. And with a sign dollar and curved brackets. I will make API. And then let's say products. Let's remove this part from here. And also this one. And I'm going to create a constant. Let's say product. And this product is object, contains ID, let's say one, and name, let's say hair, dresser. And image with, for example, some URL. So you have option here to select double quotations or single quotation. But with JavaScript, It's better to use always single quotations in that response. Let's send this product to the front end. And we will run the application. Now we have the application running. Let's go to Postman. Postman is application as we talked before and we saw how to install it. So I can't call APIs like with GET methods, post, PUT, etc. So let's have here our API 3000 and then api slash version one slash products. And I click Send. Then that is pons is the object which I created already. So we assume that we are building this object by getting the data of the product in the database or from the database, and then send them to the front end with a getMethod. So what if the user or the admin of the application of the issue up, we'll send, or, for example, create a new product. So the new product need a data which will be sent from the front end. So now let's change this muscle method from get to post. What example I will copy it and say post. The post requests need also data. This data will come from the front end. So how I get this data from the front end, it's very simple by using request dot body. So after posting the data of the body, I am going to send them back to the front end. So let's create a constant, let's say new product. And this new product will be request dot body. So let's make it like this. Console. Log the new product. So we go to Postman. Postman we change this method from get to post. And the body of the request will be, for example, at JSON row, which is JSON. And then I can pass, for example, this object. And when I click Send, we see that we return one. And in the console log I got undefined. So the problem is that the body is not parsed well. So we need something called a middleware. The middleware is a function that has control of request and the response of any API. So when the front ends and JSON object, we need the back-end to understand that this is adjacent. So please analyze it and use it in the back-end. So to do that, we need just to use one thing from express JS. So we need to use that JSON. So the Express will accept JSON data. And the thing is very simple. As I told you previously, we need to have a middleware. And this middleware can be done by using app use. And then we say Express dot JSON. And this method, we'll make our data be understandable by Express, which are sent from the front end. And we can type here like middleware. And in the future, we will see that we will put all middleware. In this section. Previously, there was used something called bodyParser, and this body-parser got duplicated. So now on we are using Express JSON. So if you see in the next lectures that we are using bodyParser, just replace it with expressed or JSON. So in this way, you guarantee that your application will run in the right way. So now we are able to make a get and also post of the data. I will, for example, change here hairdresser to and send it. And I will get back the hairdresser two. So now our API is ready. We are now starting to build this API structure for orders for products and 40 users, as we talked before in the previous section. In the next lecture, we will see how to log these APIs events. For example, when someone post data or good data, we will lock them in the console of our application. 12. Logging API Requests: It's very helpful fault that the developer to know what is going on on his server. So we can know and log the HTTP requests which are coming from the front end, like posts, get or put or delete. To do that, there is very good library called Morgan, so we can use it to log our HTTP requests which are coming from the front end. So let's install this library. I stop the server, say m, Pm install Morgan. And after installing this library, we can call it also with require. So cost Morgan. Require. Morgan. We said that this library is a middleware library, so we have to put it in app dot use Morgan. And there is some default options, which is called Tiny. This is good in case to display the log requests in a specific format. For example, let's run the server again. Mpm start. So we have here that a server is running with Postman. Let's do some requests. For example, I am going to send the post again. Okay, back to the application or to the code. We will see that we got a post request on the API and with their specific status number. Let's make a GET. Also. Here is a get, Send and back to the application. And I see that I logged also, they GET requests. There are many options for this library, so you can format your logs as you want. But we are not going to do that. We are going to use only tiny. And of course you can say with this logs on some files, all of this is, is displayed here in the documentation of this library. Now we were using only a fake data of the product. Let's start to bind this data to the database. So let's in the next lecture to do the connection to the MongoDB using Atlas. 13. Installing Mongoose and Connect to MondoDB Database: Previously we saw how to fake a data of the product to store them and display them in our application. Now what we need is to store the data in the database. And in this course we are using MongoDB. And as we saw before, we don't need to install any special software for MongoDB. We just need to log into the cloud of MongoDB. And then we create our database and connect our application to that database in the Cloud. So first of all, how we can connect our application to the database on the cloud. So first we need to install a library called Mongoose. Mongoose is responsible for all operation of MongoDB database in the application or a Node.js application. So let's install this library which is called Mongoose. I will type here npm install mongoose. And as every library we need to create a constant. Let's call it mongoose. And this Mongo's, we can say it's require Mongols. We can assume that this thing here is like import. So we are importing every library and store it in a constant. Normally, we add the connection to the database before starting the server. So here I will say Mongoose, dot connect and disconnect. It's asking for URIs. Uris or connection string. I can get it from MongoDB Cloud. We saw previously how to connect to cloud of MongoDB and create our application and clusters and our project. And we saw that we have multiple collections, or we can say databases. And those databases, we will have access to them through our application. So let's see how we can connect to those databases in clusters. If I go back to clusters, I see here a button that says Connect. When I say connect, I can use multiple options from MongoDB. For example, what we need is connect your application. So we need to use a connection string to get it from here and paste it in our connection method with from Mongoose. So by clicking on this option, we will get a connection string. Let's copy it and have it in our application. So I bring quotations here and copy this connection string. But we can't see it says this connection strings should contain a username and password and database name. But from where I can't get this information's simply in MongoDB Cloud. We can use a specific users to connect to these databases. We just need to go to database access and create a new user. And this user we can connect To database in the Cloud. So let's click here, add a new database user. And let's give it a username, E sharp user and the password, you have freedom to select any password. For example, I put from one to seven. He said that password is provided is very weak. So let's add some letters to it. And then it successfully added the user. Going back to our connection string, we need to replace this data here. So first, I will put here the username, E-sharp user, and the password which I had before, and the database name. Okay, we don't have that the base yet. So let's add one. We go back to the clusters. And then we can see here our collections. And in this list of collections I have previously, I can create a new database. So I am going to give it a name E-sharp, that the base and the same name for the collection. Back took that connection string. We can add now a database name. So now we have the full connection string. We talked before about environment variables. So let's store this string in the environment variables, so I copy it. And then I create, for example, a variable, call it connection string. And then I give it this value, which is the string which I got from the database cloud. And here I just say process dot environment variable, dot, connection, string. So now how we can check that we are connected to the database or not. If we check this method Connect, we will notice that it's returning a promise. The promise normally is getting executed and it's returning two methods. One is then when its successes and one with the error when it's fail. So here I will put then. And then if I arrow function and I console log some message, that database connection is ready. And when it fail on catch. And it's also arrow method. We can say console log the error. Let's try to start our server. So now npm start. And we see that there are some notifications saying that deprecation warning. It's saying that current URL string parser is deprecated. So we need to use some specific variable. So we need to use a specific option as a true to make this deprecation disappear. But how we can use it, we see this connect method has another parameter called options. So with this options is an object where I can pass the options which I want. So let's copy this one. Added as option. We got also another deprecation warning which is use unified topology. This is used also for searching for the servers. So let's add it here. And let's save. We are still getting error. Actually the error we need to pass also the database name in the options. So I can say that it's some reserved word, it's called DB name. And with this TB name, I can pass the database name. We named our database in the Cloud as e-shop that the base. And after saving and trying to reconnect, we see again that the authentication is failed. In MongoDB Atlas, you need to give a network axis. So this network access, you need to have a whitelist of IPs which can access your database. So I have two IPs already. I can add another IP by going, for example, to Google and just type what is my IP. And in the first search result, I will get my IP directly. So I go here, copy this IP, and then I say add the new IP. So this IP is added, I can say my home office. And then I click Confirm. So back to the application. We can see if we are able to connect or not. So just we can press Save again. And we see here the server is running, but we didn't get any response yet from the database server. And we see that the database connection is ready. So in this way, we connect the issue of back end application to the database in the Cloud. The next part, we will see how to write data to this database using our APIs which we created before. 14. Using MongoDB Atlas: Of course, there is also an local tools for browsing the database of MongoDB. You don't have to use our class online. You can also download some tool which has more, more functionality as we will see later, like export and import data. Because I want to give you the files and the data and the database which I have created to not be bothered to fill your data or database by your own. You will have the files ready. So you can use this tool to import like the databases and the tables and the documents to your database as well. With this lecture, there is a link attached for and something called MongoDB Compass. And this is a very great tool for browsing MongoDB database. And it's available for all versions of operating systems. Also, like for Windows, for a Ponto, and also for Mac OS. So after you download this link, it will give you an application you can use. And this application you can install it to your applications and then you can open it. Okay, let's open the installed application. As I show here, I have it here in my application list, in my Mac system. And it will going to append for me the MongoDB Compass. As you see here, we are initializing it. So it's initializing. And let me zoom in a little bit like Give it to be more bigger size. So now it's asking me to add a connection string, which we have created in the previous lecture so I can go and copy my connection string and then pasted here and then click Connect. I explained already how to get the username, password, and also the database name. So I have done that already. So it's in recent. I have here the e-shop user and also MongoDB and all of this information between it. So now we need to click on Connect. And then it's going to connect to my database. As you see, I have listed all my cluster, which are which I have in the atlas. So we have all the databases which I created previously. And as well the database which we are going to work with. So you have two options. Maybe you can use MongoDB Atlas or MongoDB Compass, MongoDB compounds. You didn't need to look into the browser and look into the website of MongoDB Atlas. But you can hear use locally. Just open an application, add your connection string, and it will be saved here always. In this course I am going to use MongoDB Atlas. And when we are going for deployment, I'm going to use MongoDB Compass because we need to import and export data. And as well. In the next lecture later, I will show you how to import and seed your database. You don't have to fill all of this information manually, like the database. So you will have already database you can import to your collection and then you can use it. Like to follow up with their course. 15. Read Write Data to Database Using API: Perfect, So I'm so glad now that we have a successful connection to the database, let's now try to post some data to the database so we can see them in the MongoDB Cloud. In the relational database. Previously, we saw that the relation between the tables, but here in MongoDB it's acquire different. We can consider the naming table is a collection. So as we see here, we have already a database. At inside this database, there is a collections. So we can say the collection is a table in relational database. I deleted the database which we created before. I'm going to create a new one with the table, let's call it a products. So for example, we said that our database name is e-shop. Database. Products is the collection name. So I have the database. Each database and inside that there is a table or a collection. We can call it a products. Okay, great. So now we have, let's say this collection, let's post data to this collection. So in Postman, as we saw before, we have here to this object, let's push it to this database. But first, what we need to do in the Node.JS application, we need to create a model with Mongoose. Model is the same thing as a collection. So we can say in MongoDB, it's called collection and in Node.JS, it's called model. So we need to create a model of product. This model will contain the columns which we needed for the product. For example, the name or the image, or for example, the quantity of the product in the storage in Mongoose. This is called schema. And if we go there to the documentation, we see that Mongoose has a lot of flexibility here. So we can create schemas. For example, block schema as we see here. And we can put the field's title, author, body, and there is type of it, and every field has some options. So you can specify, for example, date dot. Now, for example, we're in this record or this document is created, then we will see that it takes automatically the date of time of current time. So let's start simple. So let's first create the product model. I go to the application and after, let's say use and before the APIs. I create, for example, at constant, call it product schema. And this product schema will use Mongoose library and schema. And the schema accepting an object and this object will take the fields as we saw here in the documentation. So we have a new schema and here we can list our fields. So let's add our fields which we had before. So I say I need the name. We type is string. And for example, I need also image. Which type also string. It would contain the URL of the image. And let's add also something like count in stock. Count in stock. And this count in stock will be a number. There are a lot of types. You can check the documentation of mongoose and we will see in the course the different types which we will use for our webshop application. After having this schema, we need to create the model. So I say constant product. Normally the models start with capital letter. So we can say product, which is mongoose dot model. And the model called, or the collection is called product. And using the product schema which we had before here. So I say product schema, and I press Save. Now we have the product schema and the product model already defined. So now we need to, for example, with posting requests, we need to receive this post data from the front end, which is we can say postman or any other application like Angular or React. And then we need to receive these data by the back-end, analyze it, and push it to the database. To do so, we need first, we need to create a new product, for example, of that model. So let's do that. We can say const product. And this product is new product which we had before. But what are the fields of this product? So the product is this model which we had before. And we are going to add the fields of that product, like the name. And the image and the count in stock. So I will go here and I will receive that request, which I got. With this request, I get the body. And with the body within the body, I am sending here id, name, image, and I can send also count in stock. It will be exactly the same naming here, which comes from the front end. So the front end and the back end must agree on the same naming for the fields and the object which are sent to the backend. So here I say the name is request dot body, dot name. Image is request dot body, dot image. Count in stock is also from the request dot body dot count in stock. Now we have the model ready, so we just need to save it in the database. So to do that, we can say product dot. And it has a method called Save. Save. It means that save it to the database. If we check this save method, it's returning a promise, promise with the document. So we can say, then it's returning a promise. So we can say created product. So this is the product after it got created in the database. So it's our own method. So we can say here, response dot status, that it's successful connection or successful creation of the database of the document. So I can say here dot JSON. So I want to return back the created product to see it in the front end. And in case of error or anything can happen, we can say catch the error. And this error, we can say response dot status. For example, 500. It's the response code for errors in the http dot JSON. I create, for example, my own object. I say error is the error which I got. And for example, I say if its success or no, maybe I can use this variable in the front end. For example, to end some loading or go back to homepage. If there is some failure. We already send that product. So let's delete this part here and start our backend MPM, start. We have it now ready and the connection is ready. Let's post some data here. Nice. It's boasted, we got ID, name, image. So if we go to the our collection in MongoDB, Let's press Refresh here. We got the same data here. Let's try again by adding count in stock. Say for example, 500 pieces in my stock. I send it. I created a new product with the same name, and it's returning the ID of created product. Going back to MongoDB, refresh again. Nice. I have also two products already posted through my API in the back-end. And we notice here that it's locked and successful. Let's make an error. For example, to make an error, let's make this field as required. So database will recognize that this count in Stoke is required field. So it will response with error that you didn't send, for example, the count in stock. To do that, we go back to the schema and we change this to an object. The type of this object is number and required is true. So let's save it and run our, again our API but without count in stock. And if we validate the JSON and send again, we will see that we received an error, error and successful, false or failed. So in this case, I would say the error is validate or error path count in stock is required. So the database replied to me that this field is required. When I do it again, its success. So now we have posted a data to the back-end. Let's create a get request. So I want to get this data, display their product information in the front end, for example. So to do that, we need to create a get request. So creating a GET request just simply we change this to get. And we need to specify the products list. So let's, for example, get the old product list. And if I send the request, I'm getting the old API which we had before. So let's change it to have it from the database. To do that, we go to the get request and then we replace this constant and call it, for example, that list. And I call just the model itself which we created before and find. That's it. So I say const product list and the response will get our, send me the product list. Let's try that. We do ascend. We notice that we got an error here. The error is because that find method is returning a promise. And here, when I am sending the response, maybe this product list is not ready yet and I didn't get it yet. So I need to wait until this product list is ready and then I can send it with the response. There is another way than doing, for example, dot then and not catch. That is something we can do with await keyword. And in the await keyword it requires always async method. So I put this method here and it's async, and I have a weight here. So in this case, when I call the product list, then it will wait, it will be filled, and then I send the response to the front end. So let's do it again. Now. I am saving and then sending that request, we see that we got the data here. We didn't get the error anymore. So this is because of that we return a promise. We should wait for the database to send us their response, and then we shall wait in the front end. So maybe you will ask me how I can detect the problem or issues. It's very simple. I can say if a product list or no product list, if there is no product list, then I can say response dot status 500. And for example, with JSON, I can say error or success false. So if there is any mistake happened, for example, connection or anything, I can simply return error with a success if this list is empty. So we have two different way to express and catch errors from the database. So I can say here, find, I can put a weight and async, or I can do it with normal promises. Like for example, I say Save, dot then and catch. Of course this is more code saving. We did this only in two lines, and that's very good. So from now on, we will use always async and await. That's all for now is mongoose. Let's do some refactoring. It's very nice to have the routes in some files and the models in another file. So we can have more organization of our code, of the backend. 16. Analysing the E Shop Database: Welcome back. I changed my mind here, so we will not do refactoring. Let's analyze first the database of e-shop. So in this way we can know what routes and what schemas we can build and creating the files in the back-end. So here we have least of the tables or documents or collections which we need in our database. Every shop has products, orders, categories, users, and order items. This is the simplest e-shop. So when you want to grow up more, you need to have more tables like a reviews or for example, some new categories are bigger categories. So we start simple and we will build our e-shop to be bigger slowly. First of all, the products, for example, it has ID, which is the ID for the product. And this ID is generated when we post any ID to the database automatically by MongoDB. The name of the product, and also description. And the description reaches scription is used for, for example, I want to store some HTML code. Sometimes people are using as a description of the products with images and titles and some complicated reach texts. So we will see how we will have editor in the front end. For HTML. We need also the main image of the product. And it's a string, string, which will store the URL to that image. Also, we need a gallery of, a gallery will have some images and array of strings, of URLs where we have a gallery of the product, more detail about the product. And then we will have a brand and also price, price of the product category. It will be the type category. In MongoDB. Here we will have something called references. It's not like relational databases, but here we can define the type of the table directly. So as we will see in the future, we will see that this category is a type of category or has a reference to the category table. And count in stock how much items of this product are in the storage. Also rating based on reviews and if this product is featured or not. So to see it in the homepage immediately as a featured product. And then we will see that what they, this product is created four categories. We just need a name, maybe some additional data. For example, what I need in the front end, sometimes color, so I can color every category based on some specific color and also icon or image. For orders, we need order items, which is array of order item. And order item is a table where it's contain the product and the quantity. So every order will have a product and the quantity. So maybe I will have 10 products. I ordered them in one order. And then every product will have some quantity. The shipping address one and address two. And city, zip code, country, phone number of the user status to see if this birth order is, for example, bending, shipped or delivered. And also the total price. We will see how to calculate the total price based on the order items and the user who ordered this order. Because we will have lookin for every user who want to order something. And then the date of the order. For the users. We need an ID name, e-mail, where the user will log in with his e-mail and the password hash. The password should be stored hashed in the database. I cannot store it as plain text. Street, Apartment, city and zip code. And also country with a phone number. And also to know if this user is admin. So he can log in to the, for example, admin panel or not. Maybe someone will ask why I separated here the address from the user. Like for example, I can have extra table like address here. Then I can put this field in that table. And I can relate user and orders to that address table. Actually, most Aesop's has a problem that sometimes user, after he ordered something, he changed his address. But the order is already shipped. So we need to store the order as a plane with a shipping address, how the user placed it, not related to the user address. We will use this address just to auto-fill the order address when the user is ordering something after he locking. In this way, we took an overview about our database in MongoDB. Now we will go to the backend and create the files and refactor our code a little bit to be based on this database structure. 17. Create Backend API Routes & Schemas: Welcome back. I'm imagining now that what if we place all the schemas here in this file App.js, it would be very big. And I think we will have thousands of lines here. So normally in Node.JS, the people or the coders in general, they are putting these routes, for example, the API routes, and also the schemas in separated files. To, let's do that now and we will see how to organize the project more better way. So forth schemas. Let's create a folder here. We call it models. And inside modal, we will create a file for every model we have, for example, products or product dot js. In products AS I will place this schema. So let's copy this part and place it here. Mongoose is not defined in this file, so we need also to copy this part where const mongoose require mongoose because this file cannot see the imported Mongoose in the app.js. So we have here const Mongoose and mongoose schema. And by the way, let's get also the mogul. Though we cut it and we place it here. Now, how ArcJS will use this model in Node.JS. If we want to export a constant or for example, a class or object, we just say that we need to do it in this way. Exports dot product and then the model. So here, in this case, product will be seen in any other file. And I can import it with require method. So going to ab.js file and I say const product, which is coming from by requiring it from this file where we have the model, for example, models slash product. In this case, we got the product and we can use it as a model for our API. Let's do more refactoring. We see that we have all the APIs, get post, GET post. So if we do that for all the schemas, it would be very big file. There is a way in Node.JS that you can also store the routes or the APIs in separated file. I will show you how to do it. So first let's create a Word folder, drought routers. And inside the router, I create also products, the js. So for every model, maybe there are routers. In Express. There is something called router, and this router is only responsible for creating APIs, stalling the APIs and importing and exporting them between the files. So how to do that? First, we need to import the Express. Require Express. And the router will be part of Express. So we can say Express dot router. So this router, when I import it in ArcJS, I can use it here. And this router, it can be used as a middleware, so I can use it with app use. So first, let's move, see how to move these routers. So first, let's copy all the APIs we had and place them here. Instead of app. I just say router. That's very simple. And also I delete them from here. And as we said up the 2s is, it can use also that outer. So we can take the main API route of the products and place here, for example, product router. But from where these products router will come, it will come from here. So I can't say I want to export also the router. So I can go here and say module dot exports is router. So we have here different way for exporting. Here we are exporting the product itself, and here we are exporting a module. So in this way, I can say products router is a constant. So we can say here, constant. Products router coming from, require, from routers. And then products. So we will see here that this application is using this routes from routes which are coming from products router. So here we need to do something. We cannot use the API like this, because otherwise it will be, we can consider this as the children. So for example, here, I need to place only the slash so I can consider it when I say localhost 3000 slash products, then I can reach this one, get. And the same thing for the post. If I want something in the future like count, I put it like this, then the API will be http 3000 slash products slash count. So this is the best way how we can handle that outs in separated file. But first we have here the model product. So we need also to import this model. So I say const, product is required from models the product. Now we have the routes completed. So we have everything get post and we will see how to add the delete and update. Let's save this file and also save it here. Make some more organizing of the code here so we don't need it anymore. So we can hear, say routers. And here, the product router, we can have it here imported. Let's see now if everything works fine, we can say MPM, start. Everything is connected and everything is working as smoke. The same thing. We go also for the other database collections. For example, I will have here orders GS and also user and also the category. Also the same thing for that authors. I will have the same files. So I'm sure you are not interested to see all the process because it's exactly the same. I'm going to add them. And then we will see after that how they look like at the end, our application look like that. In app.js. We have the middlewares, routes, and also the database connection and the seller. In the routes. I created routes for every type or, or for every collection we had in our application. So I go here and I created that out exactly like the products. We have, the users orders, categories. And the same thing for schemas. Every schema has its own now. So in this case, we have now everything ready to create our APIs. Currently, I use only get in every type. I just want to mention one thing. When we export the model from exports dot-product in this way, not in this way. When we import it, we need to import it as an object. So here, when I go to the products, I import it like this. In ES6, we have this object destruction. So this model is returning an object. So I need to create a new object and assign all fields of that object to this one. So in this case, I can use it everywhere for sure there is no any problem if you use this way. The way of exporting the module directly. Let's try our LPI. Now. I go here and I say get, I got list of products. That's it for now. For next lectures, we will see how to fill these schemas and how to connect it to the structures of our database. And we will see how to continue to build our e-shop in a better way. 18. Enabling CORS & Why Do We Need It: If you are doing a front end and the back-end development in their same time. I'm sure you saw this error. This error called Cross-Origin Resource Sharing, which means in a human language that Node.JS application cannot trust any other application. So when I am sending requests from my front end to the backend, then the back-end when Lot response to me the same that I want because it's forbidden. It's using different port, which is totally a different domain. So in my front end application, when I create a services to call the APIs, then I will get that error. And in Mozilla org, they are explaining all the data or all the details about this course. So somehow in NodeJS app, we need to enable those course. How we can allow any application to request API from my server. There is a library called course. We can use it to allow the course for any application. So I stop the server and I say npm install course. After installing it, we need to require and import it. So here we are importing everything in ArcJS. So I say const course, require course. And to enable the course, it's very simple before everything, before the application start, before using any service in the application, we need to do up, don't use cores. And app dot options. With star, like everything. Using the course. This app dot options. It means it's some type of HTTP requests, like GET and post and put and delete. But what is it? When we Google http options, we see that HTTP option is a method requests permitted communication options for a given URL to the server. So when I say, I want a star, so I am allowing everything with using this course. So in this case, I am allowing all other HTTP request to be passed from any other origin. So it's very important to use this course and enable them to avoid this error. Finally, after we finish this module or this section, I would say that this project is the startup for us for creating the issue of back-end. So I will put it as a zip file so you can download it and start from here. You can see this project in resources with this lecture. In the next modules, we will see how to build all the schemas and the APIs for every part of the application. 19. Backend : Products & Categories: Welcome to the third section of this course. We are going to have introduction about starting with the back-end. What is a backend? In software engineering, the terms front-end and back-end referred to a separation of concerns between the presentation layer and the data access layer. So any web application and mobile application is considered as a front end. Back end is the part where I am holding data. Again, a database or a file server. And the server itself can be considered as a back-end. So let's have it like this. The front end is showing the data and the backend is holding this data in some secure place called server. We need somehow to handle these data which are stored in the server and serve them to the client. And using some programming languages like Java, SQL, and also no GS, which we are going to do in this course, to send this data to the client in a beautiful way, to render it in HTML, CSS, and JavaScript libraries. So in the next lecture, we will see how the front end can communicate with the backend to grab this data, which is called RESTful APIs. 20. Products Model Schema: Welcome back. In this lecture, we will see how to build the product model or the product schema. Everything in Mongoose start with schema. Each schema maps to a MongoDB collection and defines the shape of the document within that collection. So based on the model which you see in the right of the screen, we are going to build the same schema as we build it before in that model. So the fields of the product can be like start here, I say the type of this field is a string. And there are schema options or Schema Type Options. This schema type options, you can see them on Mongoose documentation. So I go here to Mongoose documentation. I go to schema types. And in schema types, we can see that there are many types. For example, string, number, date, and there are something called options, as we see here in this example. So I go, for example, to Schema Type, and I see that there is path and options at Schema Type Options documentation, I can see all the options which I need to build my schema. What we need actually for our course, I think we need that required field and also something called href to reference to another table and default, which is a default value when the object is created of the product. So the product name is always required. I set it to true. The next field is description, which will be a short description of the product. And it will be also a string. Is it required? I would say the short description will be required in our case. And then let's go to the rich description. In the rich description is also has a type string. But I would say it's not required. And we can put a default value for it when it's created. For example, I say empty string. The same thing go for the image. So I put say here also, the image is a string and it has a default value like empty. Now we go to images. Images. They are always array of strings. So we can put it simply like this array. And the type of every item of this array is a string. We have also brand, which is will be the same thing. String and price. So the price will be in the way type is number. And the default value. We can say it's 0. The next step now we need to add the category. So it's simple. We say category is type of ID of category. So here in the product, when I want to add a product, I use the category ID, not the whole category. So I say that the link between the table and of the product and the table of category is the ID of the category. So the type of this field will be Mongoose dot schema, dot types, dot object ID. So in this case, I need to pass always the id. And how I would say that this ID is connected to categories table or category schema. I just do that. I say a reference is category schema. So in this case, this ID will be connected to category schema. So when I add product, it's search in categories and I pick up specific ID. And then I say this product has category, for example, beauty and health. Is that required? Yes, let's add it as required. The next field we do We have already is count in stock. Count in stock, It's normally a number and required. So you need to specify how much of this product you have in your storage. There is also another property we can put max and Min. For example, I say minimum has 0 and maximum. It has 255, for example. So I say here that when I post a product with minus number of count in stock, then I will get error because mongoose, when it turned to me and tell me that, no, this is wrong. You need to put number between 0 and 255. The same thing goes, for example, for rating and also a number of reviews. They are numbers. So I added them here. And the field is featured is type Boolean. So the default value of it is false. So this is to show the product in the homepage as a featured product. Also, I have the field date created. So data created is a type date and the default value of it is date dot now, so it's very simple. So when the product or this request comes, then it will take the current time. Now we have all the scheme are ready for their product and we will see later how to add product in the post requests and how to get it. 21. Categories Model & Schema: Previously, we created the category schema. And as you see here in the model on the right of the screen, we need to create those fields. So let's start with the name. It's exactly the same thing as we did for the product. So I say type string required through. So to not take so much time in typing, I'm going to add the other fields because they are also having the string type. So here we have icon and color. The icon will be icon name for example, we are using some font icons or Google material icons. So I can say only the icon name. And also I say here the color, that color will be a hash, hash string, like something like I can say 000 000, which is black. So in this way, I can store the color of the category which I need to display in the front end. So let's start now with creating the API of the category. In the next lecture, we will see how to add category and deleted. 22. Add and Delete Categories: Great. So back to the real-world. Now we are going to have the category API. So in this lecture, we will know how to add a category and remove a category. I started simple here because the category API is the simplest we will see in the future. How to create more complicated APIs, like the products and the orders. So as you remember before we created the routes and routes, we are adding our APIs. We have here a GET, we will edit it to make better way or we can keep it to get list of products. Now, let's add a category. So by creating router dot post. So I am going to add a category, so by slash and then async, request and response. Then I will do here the adding to the database using Mongoose and adding a new category. We saw before that the request always getting the information from the front end, how the user is sending the information. And then we will read them and post them to the database. Let's create, for example, a constant, we can call it or let category. And this will be a new model of category. So this category, we have imported it already here. And we will have the object of this category will be name and also icon and color, exactly like the schema. So how I would get this data from? So request dot, body, dot name. So the front end must send me exactly this name. So also the same thing goes for request dot, icon, dot or sorry, dot, body, dot icon. Also for the color. We add here. The color. If you remember, when we posted a product here, we had something like save. So I say the model dot save, and then this save will return me a promise. And then I return back with the status that created products. And we talked before also about await and async. So let's do it now with a weight and async. So using a weight and a sink, I say category, which I created it before. I can say that our weight of category, which I created dot save. So in this case, I am waiting until this saved. And this save will return for me a promise with document or the category itself which is created. And then I check if there is no category, like no category created. Then I say return error. So the response dot status will say 400 four. For example, dots end. That the response for example, or the category cannot be created. For example. And then if there is category, then I say response dots end the category. That's very simple. As a recap, I create a new category model and then I filled it with data. I saved it using Mongos and then I was waiting here until this category is ready. And then I check if there is category, there is data inside this category, then I send it. But if not, I am returning an error. Let's start our server now. Mpm start connected to database. Everything is okay. And I use Postman. Postman for example, I created this category. I said name is health and icon is icon health and some color. I send it and I see it's posted successfully. And I got a new ID of this category to check if it's really working. We go again to Atlas and check it in the database. I go here and I found it already. So let's create another category. For example, like computers. And this computer has icon computer and some specific color in front end you can create a color pickup. Color pickup. We'll assign to you the code of the color. For example, I say 444, and I send it and I created a new one. I go to Atlas. And say refresh. And we will see that that category also is added here. So we have computers and health. Now let's delete a category. Deleting a category is the same. So we can't say router dot, delete, not post. And I say that out which I want to assign for deleting a category. And then I say request and response as a callback. And I would use this request and response. Let's do it here with promise way. We did it before with a weight and async. Let's do it here with a promise way. So first, I call the model, I say category dot. There is method called find by ID and remove. So we find an ID by and remove it the same with find by ID and delete. So here I need to find the category which I want to delete. So by ID. So where I will get the ID from, I will get the ID from the user or from the client. So the client will send me the ID somehow and then I will find it in the database and deleted. So how I can get the ID from the client? There is one way, It's very good way. It's through the URL. So I can't say here by two dots and then I can say by ID. So this ID, you can put it as you want, as any name you want. Then the URL will look like api slash v1 slash the ID, which I want to delete of the category. So here, how I will get this ID from the URL. It's very simple. I say request dot params dot ID. So here this name is the same name as, as I assigned here. So for example, I say category id. I, then I must put here category ID. So before we saw that we asked for the body. The body is when we send the request inside the body. So here we have body and we are sending in the body of the request, the data. But now we will send them or we will send the ID by the URL. So as we see here, that this method will return for us a promise. So I will say then and then the promise will return for me a document and the document which is the deleted category. So I say here, if there is category, like if you find it, then return a response dot, status dot or sorry, 200 and dot JSON. And I can create my own object. I can say success is true and some message to the user. So I can't tell him the category is deleted. And then if there is no category, when I don't find that category else, I say return, response dot status. The not found code is 404. And the JSON, I say success, false. So I didn't find that category and nothing is deleted. So I can say in the message category not found. But what if there is some error happened in the server? For example, not about not finding that category, but some error, like connection error or if I buy the wrong data, wrong ID. So I can't say that with the catch error. I say that please find for me or send me a message that there is error happened in the server. In general, it's not about found category or not found category. So here I say return response, dot status. The error in general is 400. So JSON. And then I say success is false. And then I can send the error to the front end to the user. So now let's test this API, the deleting of the category. Let's create one and deleted starting the server again. Mpm start. We are connected to that database. Then let's create, for example, new category computer for example. Yeah, this name, we keep it the same. And I copy this category. And then I change this method to delete. So here I say after categories, I say the ID of the category which I want to delete. And then I press Send. Nice category is deleted. If we get the list of categories again, if you want, you can see here the history of what you did before. So let's get a list of categories. We still have the old category which ill-health that deleted also. So I can go here and say delete this ID. And then if I go back to get, I would get empty array. So we don't have any category. Now, let's try to delete not found ID. For example, I can say 444 here. So when I send it, I get success false category not found. That's good. It's exactly the message which we wanted. And also, let's make an error. Normally, if you want to make error in deleting the ID of like category or object ID has this format in MongoDB. Let's change this formats. For example, I make it short like this. So when I send, I get here the error. So the error is 400 and then I say success falls and the error happened. It's about object ID because it's wrong formatted. You have here that choice to make between async and await methods or with then. So the promises, they can be in both ways. You don't have any difference. But here also is more guided and here is shorter code. In the next lecture, we will see how to get list of categories and also one single category. 23. Get Categories and Category Details: In this lecture, we are going to get list of categories and categories detail. So first we will do the categories list. We did it before already in the previous lectures. So here I am using getMethod and then I'm using find. With using this method, I will get Categories list. And if there is category list, then I will get, I will send it by response. And if there is nothing, then I will send error. Let's edit, edit here. And we can say state 2s 200 that we found the category list. Now let's get one category by ID. So I will say here or alter. Also it's GET request. So this get will accept the same API but with parameter as we saw before. So I would use here async method, request, response, role function. And then I will do a constant category. And here I would use await method. So I will do here called the category. And there is method called find by ID. So using this method, I will ask for the id from the request params dot ID. And I will check if there is no category, then send the response wrong or error. If there is category, Then I will send it with that response. So here I did it quickly. If there is no category, then send response 500. The message to the user saying that the category with the given ID was not found. And if there is category, Then I will send it with that response. Let's test this with Postman. So the categories list is API version one slash categories and a get request I send, but I don't have any category. Let's add one. I have the post request here, and I have the body already at this one. And let's add another one like health. Health. That's end. So we have to now back to the GET request. Call it again, I have two requests or two categories. Let's get this category only by ID. So I will pass just the ID after the URL. I will click send. And I got the detailed category here in my API request. 24. Update Category: Welcome back. So now let's update the category. Updating category means that we are going to update either the name or the color or the icon. The HTTP requests for doing that is called Realtor dot put. So we've put, I can update the data in the database. But here it's mix between getting the params and getting the body, the params. We will use it to get the ID of the product or the category which we want to update. And then in that response or the request body, We will do that. We will get the data which are updated. So the same way here, async request and response will be a ROM method. And then I will constant the category in some variable. And then I will say await for category and find by ID and update. So I can find the product and then our category, and then I update it. So the first parameter of this method is request dot powerapps dot ID. So I have to pass the ID, which I got from the user. And the second parameter is the object where contains the updated data. So category has a name and icon and color. So getting them from request dot body, dot name. The same thing, exactly like how we posted a new category. So I will do it here. So if I get category, then everything is fine and everything got updated. If not, then there is error. So I am going to implement this logic. It's exactly the same how we have it in the post. So I will copy the same and put it here. So I'd I save connected to the database, and that's the state with Postman. So here we have the list of categories which we created before. Now let's take this ID and change this method to a put. And then I pass the ID which I got. And the body will be different. For example, here we have it computer elephant computers 11. Let's change it, for example, to elect through phonics. And the icon will be the same one electronic, and the color is 55 when I send. So what I've got here is the old data in Node.JS. There is option if you want to get back the old data which you send, or for example, which was the category original or the current data which you update it. Because if we go here and press on get, we will see in our list the updated data. We will have here, the electronics. But here in the PUT request, we returned the old data. So in this case, in Node.JS, you need to pass a parameter to the find by ID and update, which is called is object of course, and you can say a new through. So here it means that I want to return the new updated data. Let's save it and try it again. So we go to the port. Let's, for example, change it to another thing, for example, beauty. And here I said Beauty. And I click, then I got the updated data. If I say again here with the list, I got the all the data updated. 25. Post a New Product REST API: So in this lecture we will see how to post a new product. Like working with categories. We are going also to post a new product. So we just need to collect the fields, the same fields which are sent from the front end. And then add them as a product model and then save them to the database. Previously, we did this part. So let's refactor it and make it with our model and with our database. So let's create our copy the fields which we had in the model. So here I already feel the fields to not take so much time in filling them. They are all the same. They are all coming from the body. Let's reduce also here the code so we can use async and await. So here I will add async. And then let's move down. And we say, we have, for example, product is equal to await and the product which we created the product model dot save. So we have here now the new product is created after saving it. So let's delete this part. And we say here, if there is no product, then returned as a response, status code is 400 or 500, that it's like internal server error. And then send a message that the product cannot be created. And if everything goes well, then return the product. So what is special here? The special thing here that you can post the product easily, but what if the user or the front and center on wrong category? So for example, if I have some category ID and the user created ID from by himself, and this id of the category doesn't exist anywhere in the database. So let's first to validate if there is category is exist or know. To do that. We can the same thing, we can do, const category. And in this category we say await for a new category model. And find by ID. We saw this before. So I say request dot body, dot category. So the front end in the category will send the ID of the category which I want to add to the product. So here, if there is no category, then return response dot status, for example, 400, that the user made a mistake and he's sending invalid category. So in general, we have all the fields and the user must send the category. If everything is valid, it will continue and adding their product normally. Let's try that with Postman. So I go to Postman and I create a new API. And the link will be the same. Http and categories, not categories. We need products. So pen I think now we can add the body here. And this buddy will be the type row. And this row is not text, is JSON. So the front end will send adjacent block to the back-end. So I have it already prepared to not waste time in typing this. So I have the name, the description and read description, image, brand, price, category, and the category. I got the string from the list of categories. So if you remember, we have two categories. I copied one and I added it here. And the counting stock is 10. Rating is for not so much good product. And reviews. Number of reviews is 22. And is it featured? Yes, it's true. So now when I send the product, I will get response of the product and with a new ID of the product. Let's check the Atlas database. Here is Atlas and we have here MongoDB, I recreate a refresh. So we see here that the product is posted already. And we notice that the category has object ID. Let's now try to send invalid category. So Let's remove, for example this and make it 80. For example. Send I got invalid category. And that is bones is 400 bad request. So the special thing in posting a product is only how we linked it to the category. So you must validate every category which is already exist in the database and then send it to the post with the product posting. In this way, you will have a valid product which is really linked to a category. 26. Get a Product & List of Products REST API: When we were preparing our API, we made a get request for a list of products. So as we see here, the product list is saved with find. And then we are returning it to the front that. So let's try that with our changes. With Postman. I see here the product, I change the post to get. And we see that we got array and list of products. That's very simple. Let's create a GET request only for one product. It will be exactly the same as get list of products, as we saw before. We just need here to add the ID parameter. And let's change this name to product. And now if there is a product, then if there is no product, sorry. So you return an error. If there is product, then send it again to the front end or to the API. But what we need to change here is not fine, but find by ID. And the ID, as we saw before, comes from request looked by the or, sorry dot params because we have the params in the URL dot ID. Let's save and try it. Now. I copy, for example, one of the IDs which I have here for products, and I put it here after the product. So I have the ID here. And I say, I get, then I got the product details exactly like here. I would like to mention here that, for example, in the list of products, sometimes if I have a big list of products, I don't have to send all the data. For example, if I want in the front end to display only the product name and image. So I crank create a specific API which returning only list of names and images of the products. Let's try that now. So always, after we have find here, find method, if I click dot, then I will find a method called select. So it's exactly like selecting a query. So I can pass here what fields I want to display. So I say for example, I need only the name. So let's say here name in there, stirring and save it. So here we are going to remove the product single one and we get a list. And we see here we got list of products and only the names if we want, for example, name and image. So I go to this string and I add only space. And then the field which I want to display, for example, I say image, and then I save. Let's go to Postman and we would get image and name. We notice here that there is ID, so we can also exclude this ID. How we can do that. We go also to the same string, and we have the ID in this case. So I can say minus the ID. So when I press Save, I go to Postman, send that request. I have now clean selection. So in this way, you can create your APIs with more performance and more efficient. So you don't have any obstacles in memories for loading to the client. You need a list of product. So just send what you need. So you can create a special API for that. So you can send what you want through this API. 27. Show Category details in the Product Populate : So as we saw previously, that we are getting a single product in this way. So, but the field of category is only the ID. If I want, for example, to display the product with the category name. So I have, for example, the product detail, but I want also to show their name. So it's not nice to go and get another request for the category and then merge these two requests together and show in the front end what I need. There is a very beautiful way to do it in MongoDB and Mongoose. So after find by ID method, when I press dot, I see them MSO there is populate. Populate mean that any connected ID or field to another table will be displayed as detail in this field. So what field is has, for example, ID, which is linked to another table, as we saw before in the schema we have here, we created the category is object ID and the reference category. So this category actually is ID as we saw before. So I say a stirring populate. Category. I go to Postman and then I click Send. I see that I got the details of the category. So here in this way, when I create a GET request for a single product, I assume that I am in a product page. I send a request to get the product detail, and then I get also the category detail so I can display them also in the product's page. It works also with the GET request. So they get in general. So if I want here to have all list populated, so I just say populate category of all lists of product. I press Save, go to Postman. I get list of products and IC them already populated. Some of them, they are not connected to a category. They are previously we created them. So here, for example, this product, it has a category and it's connected to some category in database. So as a recap, if someone asks you how I can connect MongoDB tables together like relational database, I just create a field in the original table. And then I say in this field that I want an object ID and it's referenced to the schema which I created for the other table. And then when I am creating a GET request, I say populate this field. So this field must be an ID and then it will populate what is related to that table. 28. Update a Product REST API: So now let's update our product. Updating a product is exactly the same way how we updated a category. But as we saw in the post, we need only to validate the category. Though going to categories, let's copy all the PUT request would be exactly the same. And then I go to the product, I add the new route. And here we have product or put ID. And then we will do the same thing, which we did for category. So let's change this to product. Here is product, product model. Find by ID and update. We have the perimeters requested params ID and I will get the fields from here. Let's copy them the same and paste them here. So we have all the fields of the product, new. Yes, we want to return the new product. If there is no product, then send a bad request or internal server error and then say, the product cannot be upbeat. And also, if everything is fine, then send the new product back. We only now missing the part where we would need to validate the category. So again here we get the same thing here. And then I say paste cost category, and then I am asking for category. And if that is not category, then send invalid category to the user. So let's try it now with the Postman. I go to Postman, let's copy or we have the fields already here. So we can change this, get to put. And here I pass the idea which I want to change. So I say here, for example, this ID. And then let's change it to product one in new. And here also description you and Ford example. Let's update the price 32. And that's it. We send the post request and we got an error here that it's invalid category. So let's make the right category. So we go here to the categories API and pick up the right one and updated here. And they send, we got again the new product. So we see or hear the product new and the description is in U and with the new price. So the only thing we did here that we also, we validated the category. So in the front end, as we will see later, that we will have Forum of the product. So when I click on Edit, then I see the fields already filled. So I just update the fields which I need and then I send that request again. Let's check also the database if everything is updated. And then I get the product list. And I see here the product has a new description and a new name. And of course also then your price. 29. Delete a Product REST API: Also deleting a product is the same way how we deleted a category. But here I want to mention some point which is very important to validate our API. Let's first copy also that delete requests from categories. I will take this one and then paste it here in the Product API or product routes. We replace everything to product. Everything is replaced. So we have now all the states. And let's try it now. Let's get a list of products. Will get we have all of these products. Let's remove the old ones because they are empty. So we can select one of the IDs, change this to delete, and send that request. Now saxes through and the product is deleted. What I want to mention here is very important thing. So what if I send a bad ID like this? I will see that I will get error that the object ID is not valid. So we need also to validate the object ID in all requests. So in this case, we catched an error. But here in the PUT request, that request there is no any catching the error. We are just checking if we are getting a product or not. But here it's checking the ID, so it will hang somehow. So let's change that to the PUT request and make a problem in the, in the ID. For example, I remove this one and then I send a request and I see the backend is hanging. That's why I prefer more this way, the promise way. So I can say always what I can see, what I can get and what I can catch. But if you want to keep this way, so we can also not validate only the category. We can validate the ID. How we can do that? The ID should be the type of object ID which is stored in Mongoose. So here I will start first to do a constant. Require mongoose. This constant Mongoose. It has a method where I can use it in the PUT request. So I can't say Mongoose dot is valid object ID, so I can pass then the request dot params dot ID. So if this valid, then I continue. If not, then I return a response about the error. So as we see here, this is returning a Boolean. So let's put it inside an if. So I say here if Mongoose. So I will send also a bad request in this way and I say invalid product ID. And in this case, the product or the API will return for me error when I am passing along ID. Let's try it now. We have wrong ID. I see that I didn't return any error. This is because I said if is valid then return error, so I should have not valid, so I add not. So let's go back again and send the request again. And I get error invalid product ID. 30. Get Products Count for Statistics Purposes: Welcome back. Sometimes in the admin panel, I want to show to the admin how many products I have in the database. So in this case, I want to see an API which is giving me back all products or how many products I have in the database. So it will return only a number. Mongoose has a lot of methods. So based on those methods, you can return any query you want with an API. For example, in Mongoose, you can have from the model product any method you want to return. So you can create your own API based on what Mongoose provide you. I won't count of the products. I want total total price of my products. I want, for example, total or price of the orders, total sales, any statistics I want to have in my front end, for example, I want to have admin panel. In the future. I will show you that with some statistics. So for that, you need to create API, which is get normally to get what you want from the database. So let's add a new one here, like router dot get. It would be getMethod of course. And then say, for example, get slash count. So the API will be after products get count. So the second parameter, it will be the same as getMethod. So let's copy this one the same and just change the road there. So I say get count, I have async response and here I need to change based on what Mongoose giving me. So we create a constant, call it product count. And here I would delete until the end and say for example, there is a method set count documents. So I want to see how many documents in this model or in this table. So count documents and then it will return the count or as a callback. And then I say just return the count. So I get the count and return it. And then the count documents were returned for me, the product count. So here I say, if there is no product count and then return an error to the user, else, send the product count. That's it. Normally we return a JSON. So for example, I say here, product count is a product count, or for example, I say only count is product count. You have freedom here to choose any name. I prefer this one. Let's test that we supposed man, I go to Postman and then I say products GET method, get count. And we execute this. And we see product count is three, so it's really three. Let's check that. Yes, I have first 1, second, 1, third 1. That's cool. So we can now show to the admin what products or how many products he has in his talk. 31. Get Featured Products REST API: Another statistics request can be, for example, I want the featured products, like how we see here in the homepage of this website. We are seeing some featured products which are displayed always on the homepage. So previously in products model, we had something or some field called is featured. Is featured has a Boolean value like true or false. This mean that this product should be displayed in the homepage or not. Now let's make an API to get only the featured products. And to make it more complex, we can have account. So for example, I can get three featured products or last three featured products or last six featured product. Let's do it now. So any GET request is like starting with router.get. So let's copy this one and build our featured API. Or instead of getting count, we will say getting featured, featured products, for example. So in Mongoose, we need to find the featured products. Only, not all products, only the featured one. So I say here, products dot find. And as you remember before, we had some filtration. We just talked about it, but we will see how to build a filters with the product. So anyway, so now I find it's accepting like object and then you can define what fields are required to be the value. So for example, I say is featured must be a true. So all products which has featured through, then I will get them. So here everything stay the same is deed only the object. So ISA here just returned for me the products. So I say here products, products, products. Now let's check that with Postman. I go here, I say Get feature. So we send and we got only one featured product because we have only one featured product in our API, so in our database. So if we check it here, so the first one has, is false. The second is also false, but the last one is featured. Okay, so now I don't want to feel my homepage which featured product for example, I have like this page for example, I have 200 features products. So I won't only, for example, five products. To do that, we can merit also some limitation to our API based on what user is sending. For example, I can add here, as we saw before, we can add any parameter like before, we add an ID. But here we can add count for example. And then here I will get this count. Count is equal to request the params because its parameter and count. So if there is request dot count or request a torque params dot count, if the user pass something, then get it. If not, then return 0. So this like if here. So if there is count past with the API, then get it. If not, then return 0. So this count can be this value or this value. It's exactly like IF statement. So how we will use this count? It's very simple. After I find what I want, only the featured product, I say limit count. So let's try that with Postman. We say get featured. And then the count which I want for example three, then I will send that request. We will not is that it's hanging. So there is error. Let's check what is the error. The error is saying here that unable field to parse find products is featured through rejection limit three, Return key false. So why this is happening? Limit field must be numeric, but we have it numeric here. Because that, because here, this request dot powerapps dot count is returning, as you see here, a string. And this is also will be a string. So we have here a string value, not a number, because limit is asking for a number. So to change it to easily to a number, just place a plus behind this drink. So now, after we save and restart, the server, asks for our API. We will get the featured product. 32. Filtering and Getting Products by Category: Continuing with filtering, Let's have also filtering by categories. So when the user selects some specific categories, he will get those products which are in that category. And this is normal filtering in every workshop. So we need somehow to adjust the GET request or get product list request to have filtering by category. But first, I need to talk about something we experienced before. Two types of parameters that we can send to the backend. First one is URL parameter. So the user can send any ID after they, you are ill or in the body parameter. So we have body. And inside this body there are some parameters, and also with the URL. So we have another type of passing values to the backend, which is called query parameters. Query parameters are used always. In this case, for example, I have URL API, URL localhost, and then I pass the query parameter. The API parameter is passed like this, so I can pass here number, but the query parameter is going always after a question mark. So I can't say always that I need here a categories. So as we saw before that we can also filter in the find method. So after passing the model and then find, we can pass object like how we did before. Like is featured like one of the field must have this value. But now let's make it as category. So this Find we must have category and with a specific ID which is passed by the user. But how we can make it multiple values, because here I can have only one single value. It's very simple. You can just pass an array and automatically mongoose will realize that all of these values must be in that category. And then this will return the right products which has those better categories. So I can't say here something like this, first category and second category ID. So let's make it here like something different. So to be more different. So now we need to take somehow this query param and split it to an array and then pass it to this find. So it's very simple. I say if there is request dot, jquery dot categories, which is this one, then let's store it in some constant. Const, for example, filter. And this filter, we will have the value request dot query categories. And we will split this value. So we split it by comma. So we say split, split the string based on comma, and then it will return for me to items in the array, which is one string and the other one. So simply, we can place this variable here because we got it splitted as array. But because of scoping in JavaScript, we cannot assign this value or uses value out of this if, because other fields cannot see it. So it's better to create the variable here and give it as empty array. And this variable, I assign to it the split, and then I am using it here. Let's try that with Postman. So I go here and I tried to get the product. I get nothing because that I am forcing the API to have category. So when there is nothing, then it must have a category. So let's have like more dynamic way. I make that as empty object. And this empty object will be assigned and has value when there is params and or query params. Then say I say category is this. And then this filter, I remove all of this object and then it will be passed to the fine. So when it's empty, there is nothing. So I will get all the list of the product. And when there is query params, it would be filled with category, which is our condition, and it will have this value from the user. Let's try that again. Now. I send that request, nice. I got all the products previously. I created some products, for example, product 1 and product 2 and product 3. And they have from different categories, for example, this category and this category. So I say here, question mark categories. And the value of these categories. Let's take the first category. For example, this one. And I send, and then I got two categories or two products. So those two products, they are belonging to this category. Let's add another one. For example, the second one, by splitting them with a comma. So I say here. So we got 123. The first product is from the second category, and the other two products, they are from the first category. And when I pass nothing, then it will work normally to get all list of the products. So here the user has the option to pass the query params or not. So now in my homepage, I can have, for example, some banners which are displaying some specific products from categories and also the user when he goes to the product page, you can also filter these products by category. For example, it will be something like checkboxes or for example, some pills. So he can click on them and select the categories which you want to display the products for. 33. Changing "_id" key to "id" - more frontend friendly: When I am getting a product or list of products, Mongoose or MongoDB is sending the field with the right how I did them. But the ID, it has some small problem. It has this underscore. I want the ID to be only ID as a key, so I can use it everywhere in my applications, not only, for example, for the application we are doing in this course. So I can use this backend with another applications which are normally mostly accepting the ID only as a key. Somehow. Mongoose, we can also copy this ID and create a field called ID only without underscore. So how to do that? It's called virtuals. So with this product schema, which we created before, we can always create a Virtual ID. And this Virtual ID will have a get. And this get will be from the ID which is passed in the product schema. So this is a way how to do it and to hex string because we have hexa strings for the ID, which is called object ID. And then we need to enable some option for the product schema. And say that when I want to send some value to the front end or to the API, we enable the virtuals because this is a virtual field. So in every schema, we can add those two or four lines or two methods. And then we will have the ID. So if we try it now with the Postman, I can send. And I will say that I will have the original ID and the ID which I want. So mall front end friendly, I can use this ID directly without this bothering underscore. 34. Users & Authentication: Welcome to a new module. In this module, we are going to learn how to make the authentication and creating the users API. Let's get a quick information how to create all of this process and how to secure our backend. The concept which is followed in every server or authentication server is as following. First, the user is signing in using his ID or email and password. And then the authentication server will answer him with authenticated. If he has the right credentials. And gt, which is called JSON Web Token. And this token will be returned to the user. So the user can use it to get the other APIs like products and orders. And of course, the user has not all rights to do what he wants with the back-end. So we can differentiate between the admins and the users, but they are in the same table. So some users will have special ability to do some creating products, creating orders, removing or changing the state of the product, et cetera. So when the user has this token, he can pass it with any API call, for example, creating a product to the server and to the API which we created previously. And then the server will say, Yeah, you are verified and you can make the API call. So they user here or the server here, we're response either with authenticated, you are. Okay. You get the response, you get what you did. And also, if there is no authentication, the server is answering like you are not authenticated user to do this API call. So in the next lectures, we will see the main steps as the following. So first we will take a look to the user model and schema. So we can create exactly the schema which we need for the users. Exactly how we did it before with the products. And then we are going to post all register a new user with a rest API. So when we have a user in our E-sharp, so we are going to register him and then he can make his orders. Hashing the user password. Of course, we are not going to save the password in the database exactly at is it? So we have to make the password somehow is hashed. So if there is some attack and someone's told a database, then they will not use the user password again in our webshop. Next, we will see how to get user and list to get list of users, but we are excluding the password. So we are going to learn how to exclude parts from our APIs and then update user data with and without password. So sometimes a user want to update his profile. So I just want to change my name, right? I want to change my address. So I just say that I want to update this data, but I don't want to update my password. But also when I have forgotten my password, I can reset it. And then in this case we are going to update the user data with the password. Then we will go to the important part where we are going to protect the APIs. So for example, not any user is able to create a product. Only the admin. Also, not any user is able to change the state of the order, only the elements. So we are going to see how to protect these APIs. So the user cannot send any request only if he is, he is authenticated. And then see how to look in the user after we created this user. So the person can log into the shop and get a token so he can use it to get a product or place an order. Also, as we talked before, maybe the server can respond with authentication error. So when you are requesting an API and you are not authenticated, then you will get an error. We will see how to handle that. Also, we are only bill to add more secret information to the user, so through the token. So we can also specify or differentiate between the users and the admins. So we can say something like is admin, but where I can hide this information. Because if I put it as a plane, then everyone can change the data and say, I am admin and he can't have access. But here we will hide the token of is admin inside the token. Also at the end for statistics, as we always do, we get the user count or how many customers we have in our webshop. That's it for now. So let's go and start with the user schema. 35. Users Model & Schema: As we had in our user model before, we see that we need a name and e-mail and password, etc. So let's build our users schema exactly how we have it in this model. On the right. I wrote them already So we can quickly go over them. And then you can implemented from the code which I am going to upload to the resources. First, the name of the user is a string and it's required. Second, the e-mail is a string and also true required. And also the password hash. We said we will save the password hashed in the database. It will be a string and it's required. The phone number of the user also will be a string or a number. And with the true and it's required. Here, we will identify the user if he is admin on the shop or no. So it will be a Boolean and the default value is false. The address which will be used for shipping the order of the user. So we can use a street like a string, and the default is empty value. Apartment is also String. Zipcode is a string, city and country. And at the end we have a user schema, as we did previously with the products, we created a virtual ID. So we would get ID in that way, not in that way. So it's more user or front end friendly. So we can use it in the front end as a normal ID to fetch user data or identify a user. And here we enable the virtuals for the schema. And here the normal export of the module and the schema. So this is all about the user schema. We will move now to create a user or registered user in our webshop. 36. Register a New User REST API: In this lecture, we will see how to register or post a new user as any post request. We can also post the user data in the body of the request and then submit them to the database. So to make it quick, Let's copy one of the post request which we have before, for example, the category. So let's copy this one and then paste it in our user routes module and start to add the body requests based on the model which we had before for the user. So let's feel all these fields like we got them from the front end as normal and paste them here in our request. So first of all, I will adjust this to be user. And here we would use user model. And then I will wait to save the user. And then if there is no user, then responds with the error that the user cannot be created or registered. So let's add the fields which we need now. So I will separate this two screens and then I will add my fields here. So name, the same name. And e-mail will be email. And here the body e-mail. Let's do quickly for the rest. Now, our new user model will look like this. So I put all the keys or all the fields, which I got them from the schema. And there I assumed that I am getting that from the body of the request. So this buddy and request will come from postman or from the front end. How we will see next. Let's try that with a postman now. So we will create an object, for example, and I will assign a user and a password hash and all this information in that object. So what will be the full route for that? It will be the API route and then users. Why? Because in the app.js, we had before, all APIs routes are defined here. So I am saying AP US products and then I assign the products routes. And then here we will have users. So in our API, we will use users. So going to the front end, Let's copy one of the APIs we had before and paste it here. And here. Instead of products, we will say users. That's perfect. So let's add a post. And then in the body, we will add a row. And the type of this row is JSON, because the user will send the data in a JSON format. And then let's create our object here. So I would say the name, and I assign any name, for example, James, and the same thing for the rest. So let's feel them. So we have here the password hash, the phone number, the admin, Yes or no, apartment, zipcode, city and country. So in this case, we will have one user which has these properties. We should not put the password like this. So we have to hash it, as we will see in the next lecture. So I pose the data now and I get all of this information. So we have here name than username, and the data and all information which we entered. And also the API responded with ID and underscore ID. So the user has created in the database. Let's check our database on Atlas. So when we go to our cluster and then collections, I will access our database, which is users or e-shop database and the table users. And we will see the user is created here. I think I missed one field which is not sent with the API, so we have to add it. So let's add it here, which is street. So we put three it also, and it's 3s. For example, 100. I'm going to add different users with different names to feel our database. So I will say James, for example, I would say Tom and Tom here. And the same password, Let's assume he has 777 here and the same address for example. And we will send, send. We will have also the same that also another user like Mike. We will have here, Mike small m. And also the same information like let's say here it 88. And the street number, for example, five, the flat is 4. So in this case, in our database we had three users. As we will see here. I'm refreshing the page. And we will see here that we have three users. 37. Hashing the User Password: Saving the password, in this case as a plain text is not secure because if someone got somehow our database, he will see the list of all passwords of all users in our database. So it's better somehow to hash it or encoded somehow so anyone can not understand what is this, the real password behind this hashing or it is encoding. To do that, there is a library, it's provided by NodeJS. It's called decrypt the js. We can install it here in a new window. So MPM install be gripped JS. And I'm going to install this library and then import it in my application. So I would say caused, be gripped and require decrypt JS. So how we will use this library? So I will not ask the user or the front end for a password hash. I will ask for a normal password, but internally in my back end, I will encrypt this password. So here I will say be crypt dot, hash sync. And then Hash Sync will ask for a string and also something called salt. The salt is, for example, like extra, extra secret information so that any person cannot decrypt this hash. So for example, I will add here my secret. You can add any secret. For example, you can say my cigarette. You can add anything. I will add here, for example, number, it's 10. And I will not ask the user for a password hash, but I will ask him simply for a password. Let's try that now and let's see what the server or the backend will respond to us after encrypting the password. So here, let's create another user password, not password hash. So it will be from one to six also. And he has some information like we had previously. Let's not make him admin for example. And I will send, and we will see here the password hash like this. So it's not exactly what the user sent. So we will use somehow when we login, we will compare this hash with the password which the user used when he locked in. This is also will be done by decrypt library. So now we have a secure back-end or secure object of the user so nobody can resolve or decrypt this information. 38. Get User and List of Users Excluding Password: As we saw before, that we created GET request to get list of users. And also we can create the same thing for getting a single user. So copying it from categories also. And I am going to change this category user. So in this way, we have a list of users and get single user. Let's try that with a Postman. I go here and I won't get one user which has his ID. There's like this and I won't list of users. Then I get them like that. We have a security issue here. I don't want to send the list of users with their password hash. So it's better to send the API or the API fields without Password Hash. How we can do that? Previously, we saw that we can exclude some parts from our API or some fields. How we do that after we call the find method, we put Select and then I press Minus, and then with minus, I can specify what field it should be excluded. For example, here in this case, I will say password hash. And then when I call the API, I will see that I got fields without password hash. Let's do that also for the single user. I will put here select, or we can copy this directly. It works also with find by ID, like with find and width, find by ID. Save it. Try it. And let's get, for example, this user with this ID I posted here. And we see that we got that user without any password hash. We can also, when getting list of users, for example, in the admin panel of my application, I just want to display the name of the user and for example, phone number and email. So in this case, you can create an API which has only these fields. So you can select not with minus, but you can say name, phone, email. So then you will get only this fields with this request of this API. So let's get them. We got name, email, and phone only. This is very helpful when you want, for example, when you have a beak list and then this big list, you want to reduce it. So you want only to select a specific fields which you want to use in the front end. Let's put it back to password hash. So I want only to exclude the password hash and get list of users with all their details. 39. Login a User REST API & Creating a Token: In this lecture, we will see how the user can log in and use the APIs. So he is required to have his email or ID and password and then send them somehow with API to authentication server. And the authentication server will respond with GW t, which is JSON Web Token, and say that the user is authenticated and is able to use the APIs which are secured. Let's start doing the first part. So we need to create a post request where person can send his username and password to the server. So let's first create a post request in our users API. So I will say router dot post, and then the path will be login. And then we will save an async method, the request and the response. And we will have the callback here. Let's do the login by email. So we will expect in their response by the email and password. So first, we need to know if this user is exist. I really have a user with this email. So first, I will create constant, give it user. And this user will have a weight method, exactly how we did before user and find one. I want to find user by e-mail. So I will say here, find one, and then it will be object. I can assign which field I want to search the user by. For example, I want to search by email. So here I will say email. And that email will come from the request dot body dot email. So here I have the user already which are send to lock in by the email. So if I get a user or if I don't get a user, I will send error. So we will do that return user or response dot status for 100 dots end. And then we will say the user not found. Otherwise, I will send in the response that the user is found. And it will be in the sand object like user. Let's try that out to be sure that this is working. So here I need a post request, I remove this, and here we will have a login. And then we don't need all of this. We just need the email, as we said, and the password of the user. So here I will have password. For example, let's say 1, 2, 3, 4, send it. And then we will get this user really exist with this e-mail. Let's make mistake in the email. You make two, for example, I will get the user not found. So we are on the right path now. So we found the user which we want to login. To login a user, we need to compare the password which he entered and with the password which is already exist in the database. But we have already a hashed password. So we need somehow to unhappy or decode this password and then compare it with the password which you sent by the user. And then I say, okay, you are right, you are authenticated. So after I be sure that I have a user in my database with that email, I want to check that if there is user we have before and decrypt With compare sing, I can't compare two passwords with the hash. So I will say that request dot body dot password, which is sent by the user and then compare it with the user dot password hash, like the user, which I found with his password hash. So if this compression success, I will say, for example, sent to the backend or to the front end. We will say, for example, response dot status, for example, to a 100 dot send user. Else. We delete this part. And we say, for example, with 400 and say password is wrong. Let's try that out. And here, for example, I have this password, username. I would say password is wrong, but do you remember we have the password in this way from one to six and the user got authenticated. So when the password is wrong, we get password is wrong. So now we come to the important part. So we saw before that the server will respond with JSON web token. So from where I will get JSON web token in the back-end. In Node.JS, there is a library called JSON Web Token. So we need to install this library. So I go to the other window which I had four for installation, I would say npm I. And then JSON Web Token. Installing this library will give me the ability to use JSON Web Tokens. So let's have it in our constants or imports we can say, okay, college AVT require JSON web token. So I can use this variable now or constant to generate the JSON Web Token. How to do that? So when the user is authenticated and everything goes fine. So I will say const token. And then I would use this library JSON Web Token, that sign there is a method there. And this method accepting the object, object with a payload and secret, which is secret or private key. We will talk about the secret. So this JVP, those sign as we saw before, it's asking for object. And this object will have, for example, you can't pass anything. I can say, for example, user ID. And the user ID will have, for example, user dot ID, the user which I got here, and with his ID. So here you can pass the data which you want with the token. We will see how to resolve the token in the front end. And also how we can compare the token in the authentication API. And here in the second parameter, we need to pass a secret. Secret is something like, for example, a password which is used to create your tokens. So it can be any string. For example, I will say, for example, cigarette. And after that there is options. And in this options, we can add some options to the token, like expiration date, which we will see later. And in their request sending succes, we will send the user with his token. So I will say send user and user, for example, email that send only the email and the token. So in this way, the user will get the token in the front end and can use it to access the API. Lets try that out. So I go to Postman. I will use log in. Again, we have password wrong. Let's put the right password. And then I got the e-mail and a token. So this token is created by the secret which we have here. So you can make what you want. And this secret, nobody knows about it. So he cannot anyone create a token like with the same tokens which are used in your webshop. So in this case, no any user send with the API, for example, any token, and then it will have the response, right response because he doesn't have the Secret. We will see how to resolve the token with the secret which we created so the user can get the right response. So if you remember, we have here the environment variables. So here we can put our secret. For example, I can say here secret. My dog is nice. So I say here secret. And we will use it here. We will say constant. And then let's say secret is process, lot, environment variables, dot secret, which I created here. So let's pass this secret instead of the hard-coded string. Let's check back again to be sure everything is working fine. So we got a new doc. So sometimes you see that when you are locked into a website in the next day, automatically you are logged out. This happens because this token got expired. So the server has some expiration time. So when you try to use this token, again, the server will respond to you, sorry, this token is expired. How to set expiration time? The third parameter of this sinusoid, it has options. And these options can be one of them. For example, expire in, expire in, you can specify one day, one week, one month. I want one day. I say one d. If I want one week, I say 1 w. So normally, Let's look, for example, for our workshop, we have the token for one day. When I come again after one day to use any API and I am loading the expired token, then the server will say, sorry, you cannot use this API because it's expired. Let's save it. And we will see in the next lecture how to protect our APIs. So they user cannot use any IBI only if he has a token. 40. Protecting the API and Authentication JWT Middleware: We saw before how the user now has the token. Now he can use it to access the data or our APIs, but how we can make our server protected. So no one can use the API without a token. As we saw before in our app.js, we had a middleware. And the middleware is checking everything, going to the server before it gets executed. So here in this point, I want to check if the user is authenticated or not. The sequence. To do that, normally, I create in my, for example, I want to create some helper folder. And in helpers folder, I will create a new file, call it for example, GBT dot js. And there is and there is a library called Express JWT, which is used normally to secure the APIs in our server. So let's install this library, MPM express JWT. And let's ask for it. So I will say constant express JWT. And then it will require express JWT. And the protection function will be as the following. So I will create a function, call it Authentication or our JWT. And this method will return expressed DWT as a function. And this function, it has options. We talked before about the secret. The secret is based on some string where we can create our token. So when someone pass any token to our, for example, backend, we need to compare it with the cigarette. So if the token is generated based on that secret, then he will have access to the API. But when his token based on different secret, then the API will not work. And as you remember, we have imported this secret or put it in the environment variables. So here I will say const secret again and then process the environment dot secret. Another option which we need to pass also is the algorithm is generating this token. If we go to the website of JWT io, we will see that the token can be generated based on many algorithms. Here are the most used. For the example, I'm using HS 256, which also library JSON Web Token is using. So we can have, for example, algorithms is array HS 256. Now we explored this method with the module, so we say module dot exports is our JWT. So in this way we will be able to use it in our app.js. So here I will say up, not use our JWT coming from constant of DWT, which is required. Helpers JWT. So the middleware is used now. Now our server is secured based on the token. So any request we'll come, we'll be asked authentication JWT. And then we go here or express JWT where it turned for us. If it's possible that the user can use this API or not based on his token. So let's check now if our API is protected or not. So I will ask for a get of list of products. I go here, I send that request and then I see that unauthorized error. So no authorisation token was found. Express JWT returned for me this error. So I need somehow to handle this error and sent to the user that required data. But first, how we can add a token to the request. Normally adding a token with a request come with authorization in Postman. And also in the front end, you need to use, for example, a bearer token. And bearer token. We will need to pass the token which you got by after login with the user. There are different types of authentication we will use here, the bigger one. So before we had also here the token after we locked in with a Thomas user. And here we will pass this token. So the authorization here coming for this API loaded with this token. So after I send the request, I will get there i data. If I remove that token, I will not do that. I don't have any authorization in front and we will see how to load token over the request in the headers. So now we are sure that our token is working. So let's make a change here. Make error. We will see that on authorized error, invalid token. So we have different errors here. So we need to handle this error somehow. We will see that in the next lecture. 41. Authentication Error Handling: We saw previously that we got some errors in our API. So we need to handle those errors to be displayed in more beautiful way for the user or the front end. Handling error in RGS can be done simply in this way. We go to the middleware and we say AP US. And we create a function which would contain error as a callback request response. And next, in this case, this method will be executed every time there is an error in our API. So here you can check if there is error. Then you can ascend, for example, response.status. Like for example, let's say 500 and the JSON. And in this JSON USA for example, a message and this message saying error in the server. So any error can happen in the backend will be called with this message. Let's try that with the error which we got with authorization. So I will make a mistake here in this token. So we will see here that we got error in the server because we have a problem in the token, but we don't know what is the error exactly. So we can classify these errors based on the type. Because if we print this error somehow, let's say instead of the message, the sprint, this error, a mistake here and then try, we will see that the error has a name. Based on the name. Maybe I can classify the errors or we can keep it like that. It's up to you, but we can make it more beautiful in the current way. But first, to have a clean app.js, Let's move this method to our helpers. So let's create file here, call it error handler to JS. And we create a function, call it error handler. And it will have the same parameters, error, request, response, and next. And then we can handle what we have here. So we can take this if paste it here. And in this way, we can keep up J as clean as possible. So here we have to say error handler. And error handler is constant. Error and learn is required from the helpers and error handler. So based on the type or the name of the error, we can classify our errors. For example, let's say if error dot name, we saw previously that we have a name, an authorized error. So I will return here status 401, and the error will be like a message. We can say that message is, for example, the user is not. As we will see also in the future, we will have type of the errors which is called validation error. We will see that later when we are going to upload photos. Or we say error dot name will be, for example, validation error. Then the response will be the same as this. But for example, let's be enough. Now with the error only, we will change this message when we will do the upload of the images and the files. And for general errors, it's better to handle that also. So we have here returned response dot status. And when there is some general, we can say it's a server error, so it's 500. And then in the JSON, I send the message as error. Or you can send the error directly without a message. Here, we will brace return and return here also. So we have now an error handler for our authorization and validation. So now in the front end, when I-I do some unauthorized sync. So when I ask for an API without any token, then I will get this error. And if I do, For example, I upload a PDF and I am not allowed to upload a PDF to our Thurber, so I will get the validation error. And also if there is not classified error here, then we will get the error in general as a message in the JSON. It's nice to have some comments always in the code. So you can play some comments to explain what type of the error is this. 42. Excluding REST API Routes From Authentication: Welcome back. Now we have totally a secure API, so nobody can use it without authentication. So in this case, the user, when he wanted to look in, he must be authorized. So this is not logical for us. So the user can be able to use a login to get a token. So in this case, we need to exclude somehow this API from to be authenticated. So here in Express JWT, I can't say unless. And in this unless I will have object where I can locate empathic is the whole APIs which I want to exclude. For example, let's exclude the login. Do that. I need to specify all APIs which I want them to be excluded. So I can say here, api slash, v1 slash users and login. So I want this one to be executed. Let's try that now is Postman. And we are still not authorized. This is because I need to add another slash here. So we go again to Postman. We try it and we have the token again. So you have to be careful that you have to have the slash here. So we can also add the register. I already added that it just the API, which is exactly like the post. So here in users, I have the post register, which is exactly the same as post. So the user can also register an account in the webshop. And here is used for the admin who want to remove or add users. What about the products? Products Also, I need somehow to get the product for free without authentication. So I don't need the user to be authenticated to get the product, because I don't want people to log in. Then they can see my web shop. I need them to get the product list without any authentication. So how we can do that, we need to specify the method, the HTTP method. So I can say print me only that GET requests, but don't allow post. Otherwise people will be able to post products to my web shop. So to do that, this path method accepting An object and this object has a first field as a URL. And second field is methods. And URL, I can specify the URL as we have it here. But instead of that, I will use products. And the methods will be get, for example, and options. And those will be an array. So we see here we specified the API URL, and then we specify the methods. Let's try that. I will go here to get list of products. Without authentication. It works perfect. And when I remove that, it will not work. So it's better to have it like this so the user can get the product list in the front end. I refactored here the code, so it looks more beautiful. So here we have the API variable, which is we get it from environment variable. And here I'm using backticks to inject the variable inside the strength. But now we have an issue. Do you remember? We had before in the APIs for products, we created methods like for example, get featured and get featured. We needed also to be public because I want to show the features product in my front end without user authentication. So here, if I want to try it, I go to Postman posted here and I say three featured products. I will be not authorized. In this case, we need to specify also this URL here. But then we will have very long list of APIs, especially by the time when we have very big web shop. Because we need a lot of APIs. Not only saying, for example, give me the feature product or give me the product count. So the nice thing here that I can use STD string like that, I can use regular expressions. Regular expressions are giving me the ability to specify everything after the products, for example. So here with this string, I can be able to use this one. So because here we have I have this star. So anything after products work. So now after I built my rejects, so here I say API slash, v1 slash products. Here is escaping slash. So it will not make any conflict with the slash which we have to define. This subject is about regular expressions. So you need to know more about these regular expressions. I am using always rejects tester, which is always located online. That is a beautiful website called regex 101. And here you can test your regular expressions. So here I will take this one and try it in that website. So I say here, something like that will be allowed, But if I made a mistake here, then it will not be allowed. So it's exactly this formula. So here it's better to use always regular expressions to specify more the APIs and have less code. So let's try it now. And we've got our featured products. Let's do also the same thing, four categories. So we have here 1 and categories. So we can get them. And for example, we cannot do eat or post them. So in the future, when I add more APIs, we need to add some exclusions here, always in this path array. 43. Add More Secret User Information to Token: We saw before when we had a login that we can't specify some data inside that response or inside the token. In this case, I can also pass some secret data, which I want to be only comes with the token. So if the user doesn't have this information in the token, I will not allow him to do something. One of the secret information I can pass here is admin. So is admin, I can say this user is admin on the webshop or not. So in this case, I can allow him to look in to the web shop admin panel or not. So the normal user cannot log in, but the admin, who has admin, true, he kept looking. And of course, in this case, it's better to separate the tables. So I can have users and customers, for example, or users and admins. So this we will see in the next lecture in more detail. Now we have the user and then I will check user is admin. So in this field, in this token, I can send the user if he is admin or not. Maybe you will tell me why you cannot do that in the front end, like check if the user is admin or not. In this case, the user will be able, for example, some hacker who has experience in programming, he will be able from front end to login to the admin panel. Even he doesn't have this ability. He can just create a fake data that he is admin. And then he can put like in the JSON is admin is true. And then he can look in. And this case, it's not good in our webshop, so it's better to have it secured here. So if the user doesn't have that I token, which has is admin, then he will not be able to look in to the admin panel. Let's try that and see our token if it's validated, right, I will go to Postman and press Send. That's good. We have now the token. So we check this token in DWT dot io. Go here, try it. I will say also this admin and expiration time. So in this case, person cannot build a token like that because doesn't, he doesn't have the secret. And if you remember, always the API is checking this token. If it was built with that cigarette, which we specified in our backend. 44. Users & Admins: As we saw before, that we excluded some API requests to not be authenticated. For example, here the products like Git and options should not be authenticated because they will be on public. So any public user can browse the products in my e-shop. So the login user who locked into the e-shop, he can post products or update to products, elite products. But in our case now the users, our customers. So if I am customer and I logged into the issue, then in this case, I will be able to delete products. And the first seconds I publish this website online, it will get destroyed. If you remember, we created in the model a field which says is admin. So here we specify the user if he is admin or no. In our E-sharp, we will have also admin panel. And this admin panel is not allowed for normal users to enter only the admins. So we have here on users table, some user roles. We have a customer and we have admin, and they are both of them in the user table. You have freedom here to do, for example, separated tables in this case. But here I wanted to mention the user roles. So you can also make them in same table but with different roles. There are many ways to do user roles in Node.JS, but I am going with the simplest way which we need for our e-shop. If you remember, after the user got log in to the application, he was assigned a token. And this token is overloaded with user ID and is admin. And here we know inside the token if the user is admin or not. And when the user sends a request, the JWT library is disassembling this token with the secret code which is provided in our API or in our server. And it will see that if it's really generated from this server or not. So we can identify the user if he has token from our e-shop or no. Till now everything is nice. So let's assume that I have a right token. And I want also to look in to my job as an admin. Letting this way it will keep us not secure because the user, in this case is able to delete or add products. So the express JWT has a great method that it's reviewing, for example, or revoking the token under some specific conditions. To do that, there is a field is revoked, and this is revoked is a function. So we can also, in the callback, we can specify if the user is admin or not. So I create here, for example, another method is revoked. And this is revoked will be a function, async function. And it will have request, payload. And Don. What are those parameters? Request is when I want to use the request parameters or the request body, I want to know something what is sending the user. The payload contains the data which are inside the token. For example, I want to get is admin from the token which is signed to the user. And this user is sending it to me with the request headers. So here in this case, I can say if not payload dot is admin. Because now I have access to this, is admin to the payload of that token. Then I will return that done is null and true. So in this case, we are saying that reject the token. So if any authorized API called and our user is not admin, then it will be rejected. And else, if he is admin, we can say done without any parameters. As we said before, we have only two types of user in our issue. So we have admin and users. If you have more roles, you can hear, classify them. And here you define what is in evoked or what is allowed. Now, let's try that with postman. If you remember, we have a user here, Thomas Jackson, which he is not admin on the shop. And this is his data. So we see here that is admin is false. And when I tried to post a product in our API and new product, I will get the user is not authorized. Let's change the token to be with admin through. Well, let's go to the database manually and change this user to be an admin. So I will say here admin through and then I click update. If I try now to use send, I will also get unauthorized. Why? Because I'm using the token which is loaded with is admin false. So we need to look in again to get a new token. So I go to the login API, I have the user and the password. I send that request, I got a new token. And let's use it in our post requests. On authorization. I play, replace it here and try again. And it's successfully posted the product thanks to express JWT that it has this method. So it was able and made us able to do, for example, this user role. Now our application is fully secure and nobody can use it or access it without any authorization or any admin role. 45. Get User Count REST API: Sometimes the admin of the workshop want to know how many users or customers he has in his workshop. So in this case, he needs an API for getting the user count. We did that previously with the products. We had an API, especially for getting how many products we have in our issue. So let's copy it and go to the user's API. After login and register, we can use it here. And we say the same getCount, but user. And here we say user count. If no user count, then return 500 and then your return for me user count. So let's save tried to his Postman. We go for example, here, I say users and get count. Try it. We have an error because I am doing a post. We need to do a GET. We try again. We have user count for, we have really four users. We didn't do also a delete request. So let's also copy it from, for example, the categories or products. We can do it from here and get this one. And then we put a delete request and I replace user, user. And everything else is user. So as you see here, it's exactly the same way how we did it with the products. We save it, and now we are totally done with the users. I am so happy that you finish this module and you will see the code where we arrived in the resources folder. So you can download it and then try things, change things, try by yourself and try to compare your code with the code which I uploaded. 46. Backend: Orders: Welcome to a new section. In this section is related totally to the orders. So we have created their products and also the users. And now we are going to build the orders. As every e-shop, the user is going to have a filled his card and then he is going to check out to submit an order. This order will come with the address of the person and also the shipping options and how he will pay this order. And we will see also after the user get logged in, how we would get also the data of the user and fill the order data automatically. So without letting the user to feel the billing address again. So we will let the data comes from the user information which we created before. And also in this section, we will see how to link the product with the order. So we will see that the order contains of many products. So sometimes I add, for example, t-shirt and trousers. So we will see how to link the order with the products. And in the back end or in the back office where the admin can login and control the orders. We will see how we will be able to change the state of the order. So it will be from delivered or for example, shipped, or even it's on hold or canceled. So here everything will be related totally to the backend. We will not work on the front end. So we will work with Postman. Student can understand how this backend works isolated from the front end. I hope you will enjoy this section. This section, as I told you, is not repeating of the previous sections. It hasn't new things. How we will link the products like array of order items and also link it to the order gets ready. And let's start. 47. Orders & Order Items Model & Scheme: Welcome back. Now we are going to implement the order schema and order items schema. Previously, we implemented the database or we planned the database based on what we need for the e-shop. As you see on the right of the screen, we have the table already of orders and order items. As in relational database, we see the connection between the order and order items. Let's start first with orders, as we saw before, with the products and the relation with categories. We had also implemented that the category has a type of object ID and the reference is to category table. So let's do the same between the order and order item. So I will copy this part. I will go to the order and I will put here order items. And here we'll have the object ID and the table of order item and required yes, through. But the difference here that we have maybe multiple order items, not only one. So in Mongoose we can implement that by aligning this inside an array. So in this case, we need to pass or have the order items array of IDs of order items which are existing in the database. So in this case, we need to create order items table. So let's have a file here. Call it order item dot js. And it will have the same schema, Mongoose all this information. The thing here we will have item and here are the items we don't have this. We will have quantity, which is type number. And it's required. Yes, true. And as we see also that we have a product. So we need to link this order item to the product. So I will say here that I will have ID or type of object ID. Mongoose schema types that object ID. And that is reference of this order item will be product. And let's exported as order item and have it as order item. And here we have ordered item schema. So our order item is ready, which we have imported here. And we referenced with object ID in order table. So the thing here that we have many relations. So the order is relating to all other item and order item is relating or referring to the product. So in my application, when I ask for an order, I will get all other items including their products and populate this products. For example, I need the name and the category also. Here I added quickly the other fields which we need, the shipping address, 12, city, zip code, country, phone status, which we'll say that a default value appending. So when the person submit an order, then the default value or the first state of the order will be pending. And here we have also the total price. How we will see that we would calculate it internally when we create the order. And here, another reference with object ID to the user table. We know which user or their disorder and the date ordered then here, that the user doesn't have to send it to the back-end. It will be automatically created with the dot now. So it will create the time where the post request is sent. And as you remember before, we had here some virtual ID. So to not have this underscore ID, we can have also normal ID. Let's copy it also and have it in the same way. So here I said order schema, create for me a Virtual ID field instead of underscore ID. So now we are ready to work with these tables. For example, here we have order and order item, so that relationship is achieved between these two tables. And now we are ready to create our API with orders. 48. Array of Refs Example of Link Order to Order Items to Products: So the order is linked to the order items by array. So let's see and read example how the front end will send this data to the back-end I created here and object of, for example, how the user will send the data to the back-end. So first of all, let's imagine that the user has a cart and he selected two products, product 1 and product 2. And they have different IDs. So order items will be array of two products, and every product will have a quantity. So in this way, I have array of order item or their item has a quantity and the product. And the rest will be the same. Except here we will see that the user will send the username, but we send the user ID creating the order. The same thing here. We didn't send their product name, but we send the product ID. So this is how the product ID is linked to the order item and how order items are linked to the order. 49. New Order & Create Order Items on Posting New Order: Placing an order in our database required data from the user. As we saw before, we have this JSON data where they user after doing the checkout, he will place the order in our database. So what we need first to create a post request in orders API, we have already a GET request. We need to create now a post request to not repeat the same process which we did before. Let's copy the simplest post request which we created in categories. And we go here two categories, post request and copy it, and paste it in our orders. So what is required from us, we need to create a model of order and the fields of the order we were, we had before and created the schema. So let's assume the simplest case as the user will send that data. So here we get the data. I paste them quickly to not repeat the same process. So we have from the user the order items all comes with the body of the request, which is this one here. So we have all other items and all the data which are sent by the user from the front end. Let's fix this stuff here. I am teaching cue that way how to call it fast, so we don't have to write again everything regarding the order because, you know, we have always post request, we have always delete request. So it's better to copy it from basic request and change the, for example, the name things to fit on our new API. So here we have ordered everything now order and sent back the created order. But if you remember, we have created order items table. So the user doesn't know in the front end that the order items which are stored in the database. So here you will just send this data. He want three times of this product and two times of this product. But for fetching this data and storing them for the admin, this will be like for example, we can say an obstacle, a small obstacle to get them again from the database. But we will solve that with Mongoose during this relation between order and order items. So when the user or the post request is sent or created, we have to create the order items first in their database and then attach to them or relate them to the order request which we have here. And as we saw previously, that order items, it's array of IDs from order item table. So in this case, we need array of IDs, ids which are in the database of those our order items. So first, we need to create those IDs or how Mongoose will create them for me. And then I will store them with the order or relate them to that order. So here, we will not get from the user directly the order item which is containing the product and the quantity know, we need only array of IDs. So we can say order items IDs. And this order item IDs will come from our created order items in the database, which we will do here. So we have this constant const order item IDs, which we will get them from after the creation of order item in the database. So we need somehow first two loop inside the order items which are sent from the user. So I will say request dot body, dot order items to loop always we use map because we know that the user will send array, array of order items. And here we will have or their item, one order item. And then inside this order item, we create let new order item, new order item model. So ordered item model. We need to have it from our models or their item. It's exactly like we are creating a new category or a new product, or it's like a post request. So I say here, or the item, what are the fields in the order item? We have quantity and a product. So I go here, I say quantity. So we have already one order item from the list of the order items which they users. And so I say here, order item dot quantity and also product, which will contain the product ID. So from order item dot-product, then we need to save this item in the database. So I say let or the new order item, the same variable we can use it. Await a new order item which we created previously or the model, and not safe. So here we are saving the order item in the database. So when we loop in order items, so for every order item, I will save it in the database. But I want this map to return for me only the IDs. So here I say return not the new order item, but the new order item dot ID. So in this case, we will get only the IDs in an array. So we created the order IDs and we attach them to the order, and we are going to save the order. Let's not save it now in the database, let's just send the order is created or the order model to the front end to the user after he post request. So let's try that with Postman. I go to the postman and I replace this with orders based on our API, how we created it. And then I will put here the data. Let's first review the authentication token and then the body, what we have this JSON for example, I am already getting these IDs from our database. So we must have these IDs in the database already. Let's send the post request. We see that we got an error. The error comes, Let's see in the console of our test server or of our server, we will see that we have here a weight. This is because we have here a weight, but This require an async function. I mean here. So here we have a weight and this require an async function. So in this case, we cannot do await inside a normal function. We need to place an async function basically is this one. So I would say here async and save and try again. And we will see that the request is created or the order is cooled recreated, but the order items are empty. Let's track this order items to see why they are not created. To track them. We can do console log of order, items, IDs. And let's see in the console what it will return for us. So here I saved. And then let's try again. Let's check the console. We will see that we have returned to promises. So we are not returning actually the ID, we are returning a promises. This because we have here async function and await, and we are returning with await a promise. So somehow we need to resolve those promises. Because the user is sending array of order items, not only one. So we have to combine those promises together. So here we have an array of promises to combine them, I use promise dot all. So here in this case, I will have a return promises or one promise, which will be resolved after that here, before we create the order. So let's try to consolidate. Again. We see that we got one promise, not to promises as before. So we need to resolve this promise. How we can resolve it, we can create a new constant. Call it Order ID is only or order items. Ids, for example, resolved. Because this is a promise. So I can say here, uh, wait for this to be resolved and then print those for me. And then I replace this order items ID with the resolved order items IDs. Let's try again. That's great. We got to them again. And in the console log, we have the two IDs which are created of our order items. Let's check that in the database. After logging in, I see here order items table is created. I didn't create that they book atlas is very smart. So based on the model I created in my database or in my code, it's creating the table for me. So here if I go to order items, I will see to order items which are created based on the postman and they have the same ID which are in the database. So now we are ready to create our order. So here we don't have anything, so we don't have order table. That's because we commented out this save. So here, after the order is created or saved, then I will resend it back. Let's remove this console log to not have our log full of unnecessary data. So here I will go now to the postman. Place an order. Great. We have now created an order, and we have here, the new ID is created of the order. So if I go to Atlas again, I will refresh. And we will see that orders table is created automatically because we have order model. So what I asked Mongoose to create for me this order model, then he created the table. So here we have other items, object ID of the new order items which are created again here. So every time I place the order, I create a new order items. In the next lecture, we will see how to get order items or the order itself more detailed way. So we will not get only IDs, we will get more detailed. We will see the order item, what it contains, and also everything. For example, which user created it, not only IDs. 50. Get Order Detail and Populate Products in Order Items and User Data: Okay, now let's get a list of orders as we have now one order in the database. We have created already a GET request for a list of orders. So let's try it now with a Postman. I will go here, create the same as post request, but it will be a GET and the authorization because always when I create a new API, I must have it authenticated. Or we exclude this API from authentication as we saw previously. So now I will use this token get list mice, we have list of orders. So we have now only one order in the database. And we are getting it with the GET request because it's an array. Let's populate the user so we can see the user details inside this request. Because for example, I want to see in the admin panel, in the table of orders, I want to see the users who ordered them. So here we go in the code and we just say dot populate. What to populate the user. Save. Try it again with Postman. We get now the user detail, all of his detail. But for me as a user or as admin, I don't need all the information of the user. So I just want, for example, his name. To do that. We just put after the population of the user, we put the fields which we want to populate. So all I have, for example, the name and in Postman, when I send that request, I get only the name. Let's post another order with a different data. For example, I will say here instead of country, Czech Republic, I will put USA. So here I will go there and say, I don't use a and a different number. Example, 1, 2, 3, 4, 5, 7. So here I will post another request or another order. So in this case, I will get in there least two orders. So we can also sort the orders by date. So because we have already that date ordered field, so we have the date here by the dot. Now, we can also sort this by date. To do that, It's very simple. I just go here and after population of the user, I say sort based on the column date ordered. So here we have, you remember a date ordered. And based on this column, I want to sort my output. So we go here, Postman, try to get the list again, and we see that we get them ordered by date. As you see, the order here is from oldest to newest. So we have previously this one on 23 of December at this time. And we have now this one. So we can order from newest to oldest. And I think this which interest the user to do so. We just align this in an object and then say that this object equal to minus one. So when I say in the sort method, this case, then it means that order them from the newest to oldest. So if I refresh and go to Postman right out, and we will see that we have the newest 1 first and then the oldest. You can check out the documentation of the sort method. It has a lot of features. So you can use them to sort your outputs based on some specific field or on some specific order. Let's now get one request detail or one order detail. So the same thing is here. I post or I get this request pasted here. And then instead of having the sort and population, we have find by ID. And here we specify the ID. And the ID will be request dot params. Because its parameters took ID. And we were renamed this to order only instead of ordered list. Here we have order, order, order. I go now to the front end and I get, for example, this one. After that, I put this ID of the order and send that request. And I will get only this order with population of the user. We come now to the important point. We have here, the order items only as IDs. We want to see the products are inside this items and the quantity that, let's clean up our code a little bit. So we have here populate. And we will have also taught populate of another field which is order items. We try that out now. We will see that we got the product and the quantity. But what if I want also to populate this product in a way that we see the product detail inside or the items. So as we saw here, the user, we got all his details. The difference here that we have array of them. So we need to know how to populate the product inside this array of order items. To do that, we have here a different way of populate. So instead doing this, the populate method will be an object which will accept a path. And here I put order item or order items. And inside this object, I say also populate for me the field, which is called product. So I will put it here and tried again. We will see like a magic. We got all the information about the order items. And in our database, the order look like this. So if we refresh, we have our order only with IDs and order items are only IDs. So in this way, we are keeping a small sizes the documents of the database, and we are doing the relations using Mongoose flexibility. If we see also here that the product has the category and the category is also id. If I want to populate also the category, we can't do that. No problem. We can say also this is populate. This is a path which is called product and then populate category which is inside this product. So if we go again, send this request, we will see the category is also populated for all the order. So to make it more clean, we can't have here this path, so we can understand the way how it's got built. So here I have say here, this one. Now I have the clean code. So this is the way how to make population of the relation between the tables in the database. We see in the future. Now how we delete this orders and how we update the state of this order, which will be in the next lecture. 51. Update Order Status REST API: After we made the GET request and post request for order, Let's do the update request as the requirements of my issue up. The admin of the A-Sharp want only to change the status of the order. So when some customer places an order to the e-shop, the owner of the shop want to process this older. So in this way, the order will be transferred from bending and then to processed and then for example, to shift and then to delivered state. So we need just to update the status of the order. We saw previously how we are updating, for example, the product. We were updating all fields so that the user or the front end must send me all the fields again. But here in the orders, we just need to update one field, which is the status, which is this one. To do that, let's do it that quickly. We copy one of the requests, for example, from categories. We get this one. We copy it to the orders. That outer put ID. We need the ID. And then I will say here I have the order. Here. I ask for the order model. And here we don't pass anything, only the status. So the status will come from requirement or request dot body, dot status. In that way, if there is no order assigned with this ID, then I am sending error. Otherwise, I am sending back the updated order. Of course you can add all fields which you want to update. But the requirements for this e-shop, I need only to update the status. Let's save it and try that with postman. So we have already this order, Let's updated. So I will have a row and the type of that or is JSON. So here I will say status will be, for example, shipped. So I put here shipped. And we need also to change this request to put. And we send it. And we got the same order as a shift. So let's get again the order. We have a get here, check it. We see the order detail already and we have the status of the order will be shipped. Deleting the order will be the same. Let's copy it also the Delete order from the category. And here we will add order, find by ID, and then it will return for me order. If there is or there, then return true success. Otherwise send error or not found our some error in the server. So let's try that with Postman also. I will change this from get to delete. We deleted and we get success. That category is deleted. We have to fix this because it's not category. We have to make it as order. And here also order. So now if I want to get a list of the orders, again, we will have only one order, which is the one which called USA. And we had now only one. Maybe someone will ask What about the order items? Are they deleted or no. Let's check that in the database. In our database we had order items and we should have two orders only to order items, but we see that the order items are still here. So we have an issue here. We need also to delete the order items of the order which is deleted. So I will let this as an exercise to you. So the exercise will be just to delete the ordered items also after we deleting the order. And then I will see you in the next video to see the solution, how we implemented the deleting of order items after we delete the order. 52. Calculating Total Price of one Order with Mongoose: Sending the total price from the front end is not a good practice. For example, if some hacker was able to send an order with a fake total price somehow, then it will be stored in my database with a fake total price. So maybe someone has order was one hundred, ten hundred dollars, but he faked it and he made it with $2. When I have a very busy webshop, I will not detect it. So it's better after the user is sending the order items, IDs, or the order items in general to the backend. We calculate that internally in the backend based on what we have in the database. So the source of truth is a database. So what I need to do is to loop over the order items which I got from the user or from the front end. And then I resolve that order items. I get the product related product. And with the quantity, I multiply that and calculate the total price. So everything is coming from the database. So let's try to do that. Here. We got order item IDs resolved. So somehow we need to replace this with a variable which we calculate internally. So let's call it a total price. And this total price will come from a constant where we are going to resolve this order items. So the same way, we click Create a constant, call it a total prices. Because we are going to loop on order items exactly the same way here. So we will do it like promise dot all. So here I will get the order items resolved IDs and map over them. And I will get ordered item ID. I will get back the order item from the database because it's stored here already in the database. So exactly as here, say async for our order item. And we get the order item through await. And we get also the model of order item. And find by ID, the ID which I got here from the map. And then inside this order item, we will get only the product ID and the quantity. So we need also to populate the product. And to make it faster, we can ask only for the price. So here I will get returned order item with the field of product inside it, only the price. And then I will go to Create Constant total price, only one. And I will say the order item which I got from the database, dot-product, dot price, because we have the price populated already multiplied by order item dot quantity. In this case, I will get also the quantity multiplied by the price. I will get the total price of one item. So mapping over all this array, I would like after that, return, only the total price. So here I will have array of total prices for every order item. So let's try to console log this total prices array to be sure that everything is going to work fine. And I am going to post a new request or a new order. I got an error here because I am console log a promise. So here, as we did before previously, that we have here only a promise, returned, promised at all, all combined promise, we put a weight. So it's simply we can also put a weight here, like weight and resolve this promise after everything is done inside. Let's try it again. Restart our server. Try to post. We will see here that we got array of two items or order items with their total price. So we need to make merge or summarize this two prices to one. To do that, we can't simply make constant total price. And this total prices array, I will reduce it. And it's reduced method. It's a famous way to get the sum of all numbers inside the array. So I have a and b, return for me a plus B. And here we add a 0. So the initial value is 0 and then combine a and B, or combine every item of this array. So here, after we got the total price, we can place it here, restart our server, place a request, and we will see that we created a post request with the order. And the total price is 146, which is combined of two order items. Let's get also this order detail. We go here, we put it in the GET request to get the details. So we will see first product, we have a 32 and the quantity is three. And also the second product is quantity 2, and the price is 25. The total price will be 146. In this way, we guarantee that the total price is coming only from our database, not from the front end. So first of all, we created the order items as we saw before. Then we got the price, total price of every order item, and then we combine them or summarized them to one number. And then we created the order with the total price, which comes totally from the database. 53. Get Total E Shop Sales using $sum: As always. And at the end of every module, we do always some post or GET request of some statistical data. What came to my mind here that for example, I want to show in the dashboard of the admin panel of the application how much totals hills I have in my whole e-shop. So the owner of the shop, when he locked into the admin panel, he see the total sales and he will be happy. So as always, let's create a get request. And the route will be get and total sales. And here we will, after we pass this API, after the orders, we will get the total sales. So here we have async, request and response. And it will be a ROM method. And we define a variable, we call it total sales. And we will get the total sales directly from MongoDB. So by using Mongoose, here, I have await, the order model. Then I use a method called aggregate. And the aggregate, I can group like join, we can say in relational database, all tables or all documents inside that table to one. And then I get one of these fields in that table and use one of Mongoose methods, like for example, some on that field. So it will return for me the sum of all field, which name, Total price. If you remember, we have a total price calculated already, how we saw in the previous lecture in every order. So we need to sum all of these total prices in one using some. So to do that, we have here an object. We are grouping the table. And here at the method, we say the ID is null. It's like that. And we name the field which we want to return in our API. So I say total sales is the sum. This is a reserved word in Mongoose of total price. The total price is a field in the order, and we have calculated it here while we are creating the order. So then I will get the total sales by summarizing all the total prices. Then we check if there is no total sales, then returned for me, error response.status. And then for example, we say 400. Not send, the order, sales cannot be generated. Else we say response dot send. Total sales is total sales. Let's try that now with Postman, I go here, I say get total sales. We sent a request. We see that we got array with ID null and total sales. So we saw that we got exactly what we have built in the group. So if I remove this ID null, I will get error because Mongoose cannot return any object without an ID or object ID 2, as we see here in this error, it says a group specification must include an ID. So it's better to put it back. Or you can also give ID by using Mongoose specifications, It's better to put it as null. So we saw here that we got an array. We can also directly BOP this array and take only the total sales. So we can say here, returned for me total sales dot pop because it's an array. And then total sales. So in this case, I got the first item of this array, or the light item because it's returning only one array with one item. So I say, give me this item and the total sales which I specified here. We try that again. We send that request, we will get total sales is 290 to this because we have here, if we get the request, we have orders. So first-order has 146 and the second order has also 146. We can also get how many orders are created or placed in my shop before how we make a total count of the products. So we can here copy this from the Product API and place it in orders. And we say here or there, count our undercount or the account holder count and here order. And with count documents, we will get the count and return into our order count, and then we will get it. Let's try that in our Postman again. So here I say getCount. And we will see that we have three orders. So now our API for the orders is completed. We are ready now to use all the API related to the orders in the front end. And in the next section, we will go back to the product for uploading the images. You remember, we have here image and images. The image will be the main image of their product, and the images will contain the gallery images of their product. I hope you enjoyed this section and see you in the next one. 54. Get User Orders: In the front end, when the user get logged in, he needs to know what orders he ordered in the history. So we need to have some at least of order history. So in this way, this API will be exactly like getting least of orders, something like that, but it will be specified only for a specific user. So let's take these GET requests and copy it to the last one. And we will say here that I want to get, for example, users older or user orders. And we need to specify as an, for example, as a parameter, the user ID. So here we say user ID. So when I am sending a request from the front end or from our API, we need to specify the user ID which I want to get the orders for. And as a condition for the find, we say object, user field must be request dot params dot. The same paradigm which I have here, user ID. And maybe we don't need to populate the user itself. We need to populate the products inside this order. So it's exactly as we did here in the order detail, how we were populating the order items and products and category. We copy that same one and we pass it here. So in this case, we will see that the order items are got populated with the products and they ordered from the newest to oldest To not have confusing names. Let's rename this. For example, we can say user or their list. And here user order list here also user orderly. Let's run the server. Pm start. Server is running database connection ready? We try that in Postman. So I have here orders, get user orders, and I pass the ID of the user, which I want to have his orders. So I pass this one and I got other items. They are looked like like that. And another order, it has also order items. So we have the three orders for this user. We will see here the same username are the same user ID. It's always n equals 4, 4. And here another one. So at the end of this section, you will see that you are able to create any requests or any API you need based on what the needs in the front end. So for example, we got here the user's orders and also we got, for example, how many orders I have in my issue. That's all about APIs. In the next section, we will learn how to upload files to our server, like images or some attachments in general. In this lecture, there is attachment of the resource code where we arrived in this orders. And you can download it and try by yourself to do some different things with the APIs based on your needs. 55. Backend: Product Image & Gallery Upload: Now we arrive to the last module, which related to the back and development. We need now to upload the images with our product, as we saw before, the product contain two fields. One of them is a main image and the second field is the images. So where will be more description about the product like a gallery images? So in this module, you will see the main step is installing Walter library. Library is a famous library used to upload files to the server using Node.JS. And in the second step, we will find out the best configuration for our E-sharp because we need to configure this library to use and upload the files to our server. The third, we will see how to use the destination and uploaded the file names. Always when the admin upload a file or an image, he must specify the file name. But no, we can't do that for the admin or for the user. We don't have to let him named the file. You can upload any file and it will be encoded in our server. Using Postman also is very important for our case here to test the image upload, we will see how to test the image upload with a postman using uploading one file or multiple files. And we will not allow the user to upload anything. We need him to upload only specific types of images, like with PNG extension for J Beck. And of course, these all done for a single file. Now we need to extend the library to make it possible to upload multiple files. And multiple files is needed for us to upload many images for the product gallery. And finally, we will see how to fetch this product with the images and the gallery images to see them in the front end. Of course, we will fetch only the URL of the image. I hope you will enjoy this module and see you in the next lecture where we will start installing mortar library. 56. Configure Server Side Upload: Okay, so first we need to configure the back end to accept uploading the files. To do that, we need to install a library called Walter. Like any library, we do npm install Walter. And with this, we will install the library and use it to upload files to our server. And as always, we do constant, Walter and required mortar. Let's see the documentation of this library. If you go to Google and type motor, you will see the MPM packages, the npm website, where we have all the usage of this library. To see more detailed usage or up-to-date usage, you can go to the homepage of the library. So here I click on it and it would take me to the homepage of mortar library. So the simplest usage of this library will be as the following, how it's in the documentation. So first of all, we need a form and this form will be provided by the postman, how we will see later. And the first usage here that we can call the molto library and then configure it with a destination on our server of the folder. So when the user upload any file through the form, it will be stored in the uploads folder, which will be in the root of the back-end application. And after that, in every post request, for example, we have a product posts we need to pass also not only the URL and the function of request and response, we need also to pass the upload, I mean the upload configuration from Walter. So here we can pass the upload and we say a single, we pass the field name, which is seen from the front end. So as you see here, the field name is called Avatar, and here it's passed in the request. But here the uploaded file will be exactly the same name where they user uploaded it. So we will have a problem when a customer, or sorry, the admin will upload the file. He will have, for example, another file with the same name. So then this file will replace the old file. And in this case we have a problem between the products may be I will lose some product names or some products images. So the best way we need to have more control on naming the files and naming the destination. So for example, we need, whenever the uploaded file is uploaded, we need to rename it somehow to some, a unique name and then store it in our server. To do that in multiple library, there is another option of having a full control on the name of files, which is called disk storage. And with this example, we are going to build our upload API. So we will use this part. Let's take it exactly the same and copy it to our application. And we will say that storage is Walter disk storage, which has two fields, the control of the destination and the control of the filename. The destination will be a function where it has the request itself and the file and the callback. The callback will be returned if there is an error in uploading and we assign the destination in it. So here, let's put our upload destination. We can call it public and uploads. So we here, we will have a folder called public uploads. We can create this folder. So we can say here in the back-end, we can say uploads. And inside it, or sorry, we could have public first. Public. And it's public will be in the root level. So it will have, for example here. And the public, the uploads folder will be inside it. So here now we have public uploads. So in the future, when we upload the file, we will see it here located directly in the public uploads. In the filename. It will be the same. It will contain the rock request and the file. And we need somehow to rename the file to fit on our needs and how it will be located in uploads. So there is another way like he is creating here. For example, the, some random mathematics to have a random naming of the application or over the file. And then he put the original filename with dash and the unique suffix which he created before. Let's do another way. So I would create a constant. Let's call it fine name. And this file name will be the file itself which we got that original name. It's already defined. And then we say, somehow to replace the spaces, it's not nice to have spaces in the naming of the files on the server. Because when you have the URL, you will have ugly URL where it will replace like with ampersand t2 for the spaces. But here we can have exactly our replaced the spaces with split. So I'm splitting the filename based on space and the replace or join. Again this space with a dash. You can also use another way, which is for example, dot replace every space with a dash. Both ways are fine. So we can also add some prefix or suffix to this name. So here we can say the filename. And for example, we can say date lot now. So here DataNode now method, if we see it, it will return the number of the day. So we can try it with the console of the Google Chrome. You can say date now. And you will see that you got the number of the date and the time now. So this is a great unique number to create our files. So after that, we have created a constant. Let's make it as a constant, not as a VAR. And this constant is called upload. Again, call it, for example, upload options. And this upload options, we need to pass it to our post request where we are creating the product exactly the same way how it's described in Malta library. So if we see here that we have also the upload single and Avatar and the field name. Field name, we need to send it from the front end. So here we say upload options, dot, single, and the field name where I want to send from the front end. So I say, for example, image. But here when we are creating the product, we are parsing request dot body dot image. This is wrong. We need to edit this field to have the full path of the image. So I'm Walter already sent us with this request, the file. So we can't say for example, constant filename is request dot file, dot filename. And this filename coming from here where we set up the file name of the uploaded file. So we will have the name exactly like how we have it in this way. Like the file original name, replaced with dashes and then dash, they don't know. Let's do it in this way. We have a filename and then we put the file name here. But when I want to fetch this data in the front end, and I want to see the, OR for example, display the image in the front end. I will have issue that. I will get only the filename. For example, I would get image 300, 300 dot J Beck. And this is a problem for us because in the front end doesn't know the original path of the file. We need somehow to have the full path with the URL also of the backend. So I will say http, localhost 3000 and the upload folder. And then the image with the name and the extension. We feel got also here to add the extension. So we have the file name only like this. We need also to edit the file name options here. To have also with the extension. We will see that when we are validating the file in the next lectures. But now let's focus on this part that we need the full URL, not only the file name. For that, we need to build somehow this string. So we can say constant. We can say base path, like the base path off their application. And we can do it with backticks somehow, like request dot. It has some field called protocol. And this protocol will return for me the HTTP. And then we will see that we have colon slash slash and we need to pass the host. So we can also do it in the same way. We can say request dot get, getting a specific field called host. This is a way how to get the host from the request. So now we build our base path. Let's add four. It also the part where we are saying the folder where it is uploaded. So we need to add also this part. So we can say it like this. And then we add only the filename. So we can say here, after that we have backticks, base path, and the filename. In this way, we build our API URL or uploaded file URL. In that way, we have the base path is this part and the file name, which is this part. Let's try that now with the postman. And try out if everything is working fine. 57. Testing Image Upload with Postman: Now let's test our changes with Postman. You remember, we created here the image field, which will have the path and the filename which is uploaded. Going to Postman. We need to create a post request on the product API and we add the authorization with the barrier token which we got before. And we have the token here to remind you, we got that token after we get a logged in user. So here I go. And then I look in a user with his email and password, then I will get the token. This. If you don't know how to get this token, what we explained that in the user's chapter. Okay, but now how we can test Postman to upload files. You remember we were sending in the body of the request as a JSON, and we were creating the JSON here and we were putting the name of the product or the description of the product or the description and the price. But here it will be different a little bit. In the front end, it will be something like a form. Form was fields like as you see in there right of the screen. So here we have a fields where we will fill it and send them to the backend. And the file field where the user can upload a file. This will be filled with a file data, and the file data will be sent to the backend through a form data. So we need to create something like a form data and embossed man. If you want to simulate a form, you can create a form data and every field will be named here with its value. For example, I will have here the name of the product. And for example, the product which I want to post will be product six. And I want also, for example, description of the product. And here will be product seeks description. So we need somehow to put all the fields which we wanted as we saw previously, the products model we have here. The description reads, description, images and everything here. So we need to have the image field, let me feel the fields here in the Postman. And then we will talk about the images. So here we have filled all the form fields which we needed to send to the backend and with their value. So for image here, it will evalue, will not be, for example, texts like here, or a value, or a number or a Boolean. It will be a file. So how we can make that as a file? It's very simple. We have postman, There is a trick that when you put the mouse, the field, where do you want to change? You can select that the type of this field can be a file. When you put the file, you will have your ability to select a file from your PC. Exactly like how you are uploading a file in the web form. So let's select an image. I have here, many images, for example, this one. And let's upload it and send the post request. We will see that the post request is created exactly how we did it in the back end. And we have the image as a full URL. And the image file with the same extension here. But if you see here that we have an extension and then the naming, so we have a problem here. So we need somehow to exclude this extension and put this date dot now after, and then we put extinction at the end. Let's do that quickly. We will change their configuration here of the file naming in Walter to get the derived file name with the extension. So let's change this part with the backticks will be more nice in the code. So we can have the file name dash, this date doc now. And we need here to add somehow the extension so we can say dot and here it will be the extension from where I will get the extension. In the next lecture, we will see how to validate these files which are coming to the back-end. So we need the user to upload only specific type of images. We need him to upload only JPEG and PNG. So we cannot let him applaud, for example, a PDF file or for example, an XML file. So we need somehow the back-end to refuse a request when there is not an image. This what we will do in the next lecture. 58. Validating Uploaded File Types: Okay, Now we need to create our extension. But first we said we need to validate the uploaded files from the user. To do that, we need to create a list of files which are allowed that full backend to accept. So we can define a constant. We say file type map. And this file type map will contain a list of extensions that are allowed to be uploaded to my back-end. The first field will be image PNG. And then PNG. Why I did it in that way. So here we have the key as an image dot PNG and the value is a PNG. This we need that because of mime type. Mime type. If you Google it, it's immediate type and known as multipurpose internet mail extensions or mime type. And this is an a standard that indicates the nature and format of a document file. Every request is sent to the backend. And the file which is containing the data file or the file data, has also a mime type. A mime type has a format like this. So I get and PNG document dxdy. So in this way, I can define what is the type of the file which is coming to the backend. The most three important types we need in our back-end are this, PNG, JPEG, and JPEG. So here we will have those types. And in Walter, when I want to configure the file name, I can find here something called mime type. So mime type will include the information or the file information with the ink station of the mime type here. So to have the right extinction, we will do it in this way. Const extension equal to the file type lab and get the value of File lot mime type. So here it will go to this array and take the mime type, which comes one of these, and then assign the extension as a value. And here I will get the value or the extension to the my filename. Okay, we talked about validation of the file. So we need somehow to validate the file if it's allowed to be uploaded or not. In the call back of destination, you can define error. So when there is an error, the callback will throw it here. So first we can do a constant is valid file for example. And we will use the same concept here. So it will get the mime type and check it if it's found in the map which I assigned in my back-end. And in Node.JS, we can define an error. So I can say here, let upload error is equal to new error. And we can say the error is invalid image type. And then we can check if there is, is valid. Then make this upload error as a nun. And then uses upload error in the callback. So if the file is valid, there is no error and the callback will be executed. So you remember, we uploaded with Postman one file and it has this name. So now we will not have this JPEG here. We will have it at the end. Maybe it will stay here, but we will have at least extension at the end. Let's test that with a postman. Now, with our form, I have the same data, same image which I have uploaded. Send that request, I got uploaded image. And let's check the extension. We will see it has the extension at the end and the filename. And here is the image working fine. Let's try now to upload a file, but not the image. We can say, for example, a PDF. So I have here a test PDF. I will upload it. And we got the error. So we got error, that invalid image type, which we created here. So here in the front end, we saw that when we uploaded PDF, we got the issue. But what for example, J peg, send that request. We don't have any issue. We have the full path and we have also the extension. And every time I do an upload requests, I get a new data and new date and the file, it's the same, but it's uploaded again with a different name. Going to our database on Atlas, we can check the file or the product which is created. We will see the product has the image and it has a full URL. So this will be accessible from anywhere in our application. But we must have something like excluded from the authentication. Because if you remember, all API is authenticated. So we cannot do anything without getting authenticated. But we need that to be public, which we will see that in the next lectures. In the next lecture, we will see if the file is really exist. So if there is not a file or image for the product, we need to reject the request. 59. Image Upload With Product Post Request: What if the front end send me their request without a file? Then that required field of image would be refused to handle that. Let's first check if we have a file in our request. So I go here and create a constant, call it file and give this constant the value of request dot file. And exactly with the category, we can do it the same with the file. So I say if there is no file, then return an error to the user that there is no file. In this way, we will be sure that our request will not pass without a file. When we go to Postman and send the request without file, we will get that there is no image in there requests. In the next lecture, we will see how to use images to upload multiple images, which will be, for example, a gallery about the product. So in one request, the user will send multiple files, not only one file. And this will happen in the images field. 60. Image Upload With Product PUT Request: When we are going to update a product, also, we need to care about the image. So what if the user wants to upload a new image to his product, like he want to update the image itself. For that, we will do the same steps which we did for the post. So we need to add the upload options as well to the PUT request. So we added it here and then we are going to do some changes here. So first, if the user doesn't upload any image, then I want to keep the old image which is in the database. But if he upload some image, then I need to send and upload again the image to the files and then add the new URL to the database. Let's make this dog to echoed. So first of all, I want to find the product. So I add here a constant called a product and the product find by ID, request dot powerapps dot ID, and then I check if there is no product, then returned for me status 400, that it's invalid product, okay, Now everything is fine. Then we guarantee that the user is really entering a specific and arrived product. Another thing, then we will get the file itself. So I would say const file and this file, we've come with their request dot file as we did exactly with a post request. And then I will define a path which is called image path. And this image path is empty. I am going to use it to fill the path of the image. Either it will be the old one which is already in the database, or then you file path if the user uploaded a new image in there PUT request. So as a logic, I will say if file, then exactly how we do with the post request. I will define a filename and then of base path. And I will say that the filename or the image path will be exactly the same how we have it here. So we will have the base path and also the filename together as Image button. And else, if there is no image bath or if there File, then I would say that the image path is the same as the old image path which was defined previously when the product got created. So I would say product, that image, the old one because I got the productive year and I guarantee you that the product is really exist. So I'm not throwing an error to the user. So for sure the product has a value here. And then I will say if that is five, then upload the file and give me the past to it. Else, give the image path will be the product image, which was previous. And then here I will say that the image will be the image path with the updated data. But here let's rename that one product. So we can say a product here for getting the product. And we can say here, updated product and the updated product, I find it and then check it and then send that request back with the updated data. So those are the required changes for the PUT request. In this case, you will not get any errors and you're going to have any problems when you are uploading the image again or when you don't upload the image. So the user here has option, he can upload image or not in the pool, request. 61. Product Gallery Multiple Images Upload: Okay, here we had a single file, so we uploaded only one file to the API. But here we need a multiple files for the product gallery. In the same way, we can change this post request to accept also a multiple files. But let's make it a little bit more complicated to have a real practical example. Normally when you are updating a product or adding a product, the second thing you do is uploading the image gallery. And this happens normally in the web shops. After you create a product, everything is fine. Then you go and edit the product again to ablate the image gallery. So let's create a specific API only for uploading the gallery of their product. This API will be update request, not a post request. So we need the post request. So I copy this post request. Let's go to the end and add it here. And further out, we can keep the product ID and also we can add their doubt where we will update only the gallery images. So here we can add gallery images. And then the ID of the product. As we saw before in the post request of the product, we added also the Upload option single image. We can also add it to the PUT request. So we can add here upload options, but not single. We will say array. So we will expect from the front end our array of files, let's call it emits. And if you notice here that the array method is giving me also a max count. So you can allow maximum file upload size. So for example, I would say maximum, I need 10 files or 20 files in one request. So let's put it as 10. Let's died more our code. So let's have this in a new line. So we can't say this one is here. And here, the async method. And here we have the port and we have here the content of our PUT request. So the update request of their product will be update exactly this data, but we will have only the images, not all the data. So we can do the same thing as we did here. It's copy this part to see if the user is passing the exact or the right ID. We don't need to check their category because we are not updated it. So let's have this one also. But as we said, we had all the data. We need to update only the image. So image field will be array of images. So as we saw here, array of image strings or path of the image. So we need here somehow to build array of strings. So we can hear, say, image buffers. And this image spotters would be a valuable as array of strings. So how will we will build this array first in that request, as we saw before, that we can have request dot file. Or if you see that we have a files also not only file. So we can say files will be constant files. And exactly like before, we can check if there are files. Then I will loop inside these files and build the images bothers array. So here I will move this up and say files dot map. And this will have file. And inside this method of file, we can say Image path is dot push, the fine dot filename. But we don't have to push the file name only. We need to push also the base URL and also with the extension. So if you remember, we created here the base URL, which we build for the post requests. So we can copy this part also and go to the put method and say here the base URL or the base path. And we push the base path with the file name. And here we can return back the product. So exactly like the PUT request, we can check if there is product, then that is ponds be the data of the product. Otherwise it will be error. So we copy this part and place it here. Let's test that with Postman on what we have to do with postman, that we place multiple files here. So let's create a field, call it, for example, image. And this image will be a file. And we select two or image for example. And we don't forget that to change the API. So here will be Gallery image and the request is put. And we need also the ID of the product. Exactly this one. Let's get our product, or product is product six, which we created before. And now we will add the ID here. And we will send that request. We have our error, I forgot here to add products. So we will have the right path. Now we try it. And then we will see the product got updated. And we have two images in the gallery and main image, It's still there. Let's check our uploads folder. We will see that we have two images, this one and this one. So in the front end, always we will update our gallery or update one product and add to it the gallery images. That's all about this section. In the next section, we will see how to fetch the image URL, so we can see it in the browser and in the front end, because now it's locked and we don't have access to it because it's protected with our API authentication. 62. Excluding Uploads Folder From Authentication: Now let's try to get this URL and put it in the browser, the URL of the image. So we put it in the browser and we will see that the user is not authorized. This because if you remember, in our JWT, we were defining the bath is which are allowed for public. So we need to add the upload folder path to be allowed so anyone can see these images. Otherwise, we will have an issue. So the e-shop will not show the images of the product. So let's copy this one. It will be exactly the same Git and options. We need also to replace this one with the path of the uploads folder. The regular expression for this is this one. I have slash, public slash uploads at everything comes after it. Let's save it. And let's go to our browser. Refresh. We will see error that we cannot get public upload image. Why this because it's a static folder. We need to define these public upload as a static folder in the middleware of our application. So to do that, we need to go to our app.js. So we go here and we say up use. And then we define the path which we need to make it static. So public slash uploads. And then in Express, there is method to say this is a static folder and a reserved keyword, which is dire name return for me the root path or the root path of the application. And plus the path which I wanted to make it as a static. So now this path, any file can be uploaded to it. It will not be as an API. It will be like a static path which is serving the files. So back to the browser and we do a refresh. We still get the error. This because I need to add slash behind the public. Act with our browser and refresh. We will see the image we had already in the front end without any authentication directly by the URL. Now our backend is ready. We have created the routes, four categories, orders, products and users, which we need exactly for our e-shop. We will move now to the front end part and you will see more than new things and how we reconnect to this back end and create our webshop interface. 63. E Commerce NgShop App Page Structure: Okay, in this lecture we are going to see what is the design or the page structure of our e-shop. The customer gave me an XD file. Xd can be opened with Adobe XD, and this application can use for making a wireframes. And as you see here, the designer gave me this design and I can move components, take some layouts, some coloring. So I can use it also for my styling and for my CSS. But the page structure in general, as you see here, that we have like some header. We have, for example, some banner. And we have also list of categories and some featured products. And when you click on one of the products, you will have the product details. And you will have also add to cart or going to their cart. We will have multiple pages. So we will have the homepage and a contact page and the products list. So we will see how we will structure the application in Angular and how we will do that with NX. So if we change, for example, to a programming view or development of view, we can divide our application to components. I call this application as NG shop, like angular chop. So if we go to the next slide, we will see the page structure we will need for this application or this e-commerce shop, we need two applications. First, we will need an e-shop, which will display the front end or how we will see the product leaves the cart page, et cetera. And also the admin panel, the admin panel, which will control all of these front end. So we will have some tools and tables, edit, delete. So we can have all functionality which will reflect the front end. So the admin of the issue, he can take a look to his orders. He can take a look to a product. So far from NX, we will see that each job application need a homepage. We need a product list page, we need a product detail page, cart checkout. And also we need a login page so the user can log in and save his data and his orders also. 64. Creating Project Folder and Installing Angular: Okay, now let's do some practical work. First of all, I am opening Visual Studio Code and I am going to install Angular CLI. Angular CLI, it means command line interface. So we can execute comments of Angular, like running application or service application or testing it, or generating components and modules, as we will see later. So if we go to Google and type Angular CLI, we will see on the first link the Angular CLI. So installation of Angular CLI, we'll be done with like Node package install globally. So dash minus g or dash g is installing globally of Angular CLI. Let's try that in our Visual Studio code. So I go first and I open the terminal. How we can open the terminal? It's very simple. You can't say Control Shift and J, or Command Shift J. And it will open for you the terminal. And in some cases it can be only Control J. So here you will have the terminal open. We can install the Angular CLI. So I will copy that command, which is npm install minus globally at angular slash CLI. And here it start to install globally the package. So I will be able to execute angular commands everywhere in my PC. If you are using Mac, maybe you will come to the error. So you will see that you are not having permissions to install some global libraries. So what do you do normally you can say pseudo before the wood comment. So I will say sudo password and then it start the installation again. And you will see that Angular CLI got installed successfully. If you are using Windows, you will not have that error. And if you have it, you can open Visual Studio Code as administrator. So let's try some angular commands. We can say mg help. And you will see here that you will get help of Angular comments. For example, there are some ad analytics, some documentation and linting and serve. And as you see here in the documentation of the CLI, you can check all the comments. So you have to add and you build NG config and you deploy, et cetera. But we are not interested in this course about Angular command. We need to have an X command. As we will see later, that NX is a global library also, which is located over angular comments. So actually, when we are executing and X command, we are executing angular commands internally. The most important now that we have angular installed globally and we can create a folder, for example, my desktop. I would say CD this top. And I will make dire directory. So I will call it, for example, with my company name. I will say, for example, my company, okay? And we can access my company. And here we will have our application all we will have our workspace repository, which will contain all applications and libraries in Angular and in NX. 65. Components, Modules, Services in Angular: Because this is a practical course and we are doing real-world example. If you are beginner in Angular, maybe you need to know what our components, modules, services. And as you see here, that you can imagine with me that you are going to build some application in Angular. I don't want to go to say what is module, what is component with the service? Very theory part. No, We will do that in practical. I just want you to imagine with me that the module is container of components and services. So the component in Angular has some parts where you can define the HTML template and the style of it, like CSS. And to code the script which will communicate with service and the service itself. It's going to connect to the backend of your application. And then the back-end, we'll grab data from the database. So you are getting the data through the backend to the front end. So we have many modules also in Angular, so they can connect to each other. So you can use some components of this module in that module. And also maybe components will, can contain or call some other components, as we will see later. So this imagination, it will help you a lot in this course. So you don't have to know what is every detail about these parts. So you just need to know that module is container of components and services. And the components communicate with services. And maybe another modules can connect to this module. Let's see some practical example. I have the product module in my e-shop. And I have two components, which are we can say product list component where I am listing all the products. And another component where I see the detail of the product when I click on one of the items here, inside of this component, I will go to the page where I will see the product detail. And when I want to see what are the data of this, for example, product list, I need to have a service in the front end and call from the backend to the database. The data which I want to show. The same thing goes here. When I go to this page, I will ask for the service to bring me data through the backend from the database to show the product detail, like the price, image, or name or description. So in this case, you can create Angular applications. So Angular applications actually they are modules. And modules can communicate to each other to build the whole application. In the next lectures, we will see how to build those modules and make to them communicative together to build the whole applications. And at the end, you will see the application is built in this way. So we have users module orders, module, product module, and all of them, they have their own services and their own components communicating with the same backend and same database. 66. What is NX & MonoRepo?: Welcome to the first lecture of this section. We are going to know what is n-x and what is mono REPL. Let's start first with Monod apple. The meaning of Manet rapport as Awards is divided to two words. First, model, which means alone or single report, which is repository. Like a GitHub repository where we are storing our code. And Mano ripple is a software development strategy where code for many projects is a stored in the same repository. So as you see here, we have here App 12 and up three. And those applications are all in the same repository, which is under the company name. In addition, we see that these applications are sharing some libraries. So Mano ripple is one repository, multiple projects and shared libraries. And of course, every application has its own components or own modules. This is the general definition of mauna report. Okay, who is using Mono rapport in general? The most famous companies like Google, Microsoft, Facebook, Uber, and Airbnb, and Twitter are using nowadays mono report, for example, Google mauna report is considered to be the largest in the world. And it's also called as the ultra large scale system and must be handled by tens of thousands of contributions every day in the repository with the size of over than 80 terabytes. Okay, Why one or epoch? Why is that so important? What are the advantages of mono ripple? First, ease of code reuse. As we will see later in our real-world example, we will see how we are using modules again in multiple applications. Another feature is simplified dependency management, which is in a multiple repository environment where multiple projects depend on third party dependency. That dependency might be downloaded or build multiple times. So I need to download the library for every project. But in Amman, Aleppo built can be easily optimized. So we can see that the reference or the external libraries can be downloaded one time for multiple projects, as we will see in the next points. The third feature of manana hippo is atomic commits. Atomic commit, which means synchronization between the dependencies. So when there is some update comes for one of the library, all projects will get notified and they will get that update. And also collaborations across the teams. So we are talking here about multiple projects. We have multiple teams. And the calibration across multiple teams will be more improved when they are going all in the same way by using the same libraries or their same shared libraries. And the most important part, single package JSON policy. So for example, when you are using npm or Node packaging management system, then you will have one single package, JSON. So you don't have for every project as separated node modules folder. And in that way, you are saving a lot of space, okay, after we saw the advantages, let's move to cons. So of course, every technology or every software development method has some cons. First one is maintaining the configurations. So always when we have multiple projects with different configuration, we will have a problem when some Update columns. So we need to maintain all the configurations after every library update which is shared among the projects. Second is coordinating a release process. The same thing, that release process can become complicated as the knowledge of what components must be released relies on the development team. The third disadvantage is setting up the entire project. Setting up the project locally might take a long time to each component has its own read me and it has multiple variations. So when we have a new project set up, we need again to link all the dependencies to that project. So we will feel like more time-consuming to set up the entire project. Okay, After that, let's see what is an X? And X is a menorah apple and is a DevTools. And we can't say it's TypeScript based mono or EPA tool, which is built on top of Angular, deaf kid, CLI and schematics. Also, it works also with another technologies, as we will see later. It also provides a workspace, CLI, and a Cloud-based computation caching, and a great language level IDE support. And x was created by Angular team at Google. And then the core members decided to start a new company called novel, providing an x toolchain. So when you check the NX website, you will see it's provided by Norval. Again, let's see Y and X is good. Or why we need n-x and x provide tools to give you the benefits of a mono ripple. Without that, the row bags of symbol called co-location. So I don't need to set up the menorah or manually. There are tools or comments which helped me in NX to create all the projects set up without doing any creation file by hand. Also n eggs Providing a faster comment execution, as I told you. And x is a file structure. So I don't need to create the files manually. I don't want to create component on in Angular manually. So by a comment, I do a faster comment execution to generate the component and its debts file and the styles. And also it's controlled called chairing. So when I am creating a library, it's shared and controlled by everyone who is member of the projects inside the applications NX providing accurate architecture diagram. And this diagram showing you that dependency between the libraries and the applications and circular dependency if you have them and fixing all the loops which are leading to circular. And it has also a great deal i, we will see it in the next lectures. And the most important feature that when you are building a project or testing it, it will not take you so much time because it will test only what is changed. So it will test only the effected files which you changed. So this is also good for development. You will not need to have Hall built again or whole test. Again. You will have access to the Git repository by NX and it will do for you only the affected or changed files. Finally, let's see what is supporting annex. The following technologies like Angular, React and NodeJS are the frameworks where an X support. So you can use and x with Angular, React and NodeJS, you can have also a project or repository that all of these frameworks sharing one library or multiple libraries. In the next lecture, we will see a real-world example about NX. 67. Overview on NX Real World Example - E-Shop: Well, let's move on now to a real-world example. Actually, I don't understand the ideas only when I see a real-world example. That's why the goal of this course is not reading a documentation, but we are going to have real-world example from my work. Actually, I am working in a company and I want to show you how we are working, how we are sharing the resources and libraries using NX. So let's move on. I assume here that I have in my company, which is project repository on the top. So in one repository, I am placing three applications. First one is e-shop application, and the second is internal blog application. And let's talk about the admin panel later. This e-shop application has its own components. So this components are not shared with the other applications. So as we see here, we have E-sharp home component, which is the homepage and also featured products banner. So where I will show the featured products and also categories, how I will list the categories of my e-shop and product list component, where I will list all the products and use some filtering so the user or the customer can enter to the issue, filter by category, for example, and see the product list. Also, we will have a product detail component which will display the detail of the product and also component where the user can log in and see his orders history. And finally, check out and card components. The checkout where the person is entering his data or shipping address so he can place his order. The cart is opening the cart page to see what is inside the cart. What we shop there. Okay, this e-shop application doesn't share these components with any other applications because the other obligations are not interested about those components. For example, the internal blog application is not interested to display product list component because it's a blog. So the blog application will have its own, so it will have homepage and also posts list and also a post services. That post services is something where I can grab data from the database. I can grab my posts from the database. Okay, these two applications are sharing some stock. Let's start first with their login. So when I want to create an application like e-shop, I need a login login page and also the same for the blog application. I need also a login. Normally, if you are working normal Angular with stand alone application, you will create the login here again. And the same thing you will do for the e-shop. And when some update comes up, you need to update login here and login here. This is the application of work, the application of teamwork. So in that is positive 3, we can create a library, as we will see in the NX. And as we talked before, that we will have a libraries. And this library will contain a login component, page and register component, and user services where I can grab users and also see how to add user, registered user, etc. And also authentication services so the user can look in or log out or other services like protect the APIs. And when the user logged in, we need when we refresh the application or when the user visits the application. Again of the issue, for example, we need him to stay logged in, for example, for one day. So for that, we are going to use User State Store and also for sessions. So these two applications are sharing all of these features. So we need to have a library which is shared for both. The same thing. Here goes, for example, for some UI components, like for example, I need a banner. Banner will have some services to grab data from the database. And we will see that e-shop has a banner in its own page. And the same thing for internal block, also slider and Carousel. Okay, Let's continue now to the admin panel. Those two applications need admin panel. So first, let's start with this library. Why the admin panel sharing this library is sharing it because of the services. I need to use those services. So I need to grab banners from the database and for example, post banners that content to the database. And as you see here, we have banner and slider content edit. So the admin will look in, change that banner and then it will be displayed in the application of e-shop. Also, the admin application need log n, So we need to secure the admin panel as well. So we need to have a login component. But for example, I don't need register component. But because the register component is shared between these two applications, then I need to place it here. And the nice thing, when I am not using register component in admin panel application on production build, I will not see this register component. Even if I am using this library. So NX automatically provide warm for me exactly what I used from the libraries and which will reflect the size of the application or the bundle size. Okay, What about the products? The products which we are grabbing here from the database and display them like product least product detail. We need the services. So these services can be located in a shop. But now because admin panel has also add product category form and also listing of a product table. So we need to have a shared services between the admin panel application and the e-shop application. You see this right way, how we are sharing the resources. That same thing for the orders. We will see that the orders, I need only the services and I am sharing between the Admin application and the e-shop application. But internal blog doesn't have orders. So in the admin panel, I need to edit the order form and list the order table. And the same thing here. I need to place order like add order like from the users when they do the checkout. And also I need to see user order history. So I need a service to grab information for me from the database. In the same time, we need to have a state store for the cart. So where I can place the state store, I can place it in the library, or I can place it here. No problem. But I prefer to have it here, even it's only used by the issue of application. And of course, you have the option to place the state store here. No, any problem. Okay, to understand the idea more, I would like to make another application or fourth application, which is also a shot. So I am in a company, we build three applications and now a new customer come. He wants a different design and a different layout for his issue. I will not show you the different image, but I will show you how I will categorize the components. Let's move on. So just a tip for you, how I build this diagram, how I draw it, I'm using a tool called the draw dot io. This is a very great tool, so you can build your own diagrams. It's provided you with a lot of shapes, which will help you to build explanation diagrams. So let's move on and create our own application, or another application of the E-sharp. So I will move here and make this bigger a little bit, and we will have a space for another application. So let's imagine that we are really coding in Angular. So I will have here one and another application. I will create it here. Let's call, this is e-shop up one or customer 1. And this is e-shop app customer to, so we can copy this one customer to. Okay, also, it will have its own E-sharp page. May be featured banner may be, for example, categories list banner. So let's copy all of these items and place them here. Let's keep it like this for example now. So as you see here that we have many shared components. We need to place these components in places where they can be shared. I don't have duplicated components only if I am creating a new component which is not exist in another issue. For example, the homepage will be different between these two sharps. So I would keep this component here, e-shop homepage, which is different from this one and featured product banner. I can place it in the shared library. And also categories list banner. I can place it in the shared library as well. Product list component, product detail component, and also user order history. So I see that everything can be shared. So we place all of them here and we delete all of these components from here. So the only difference between this E shops to each OBS is just this component, which is the homepage. And they are sharing all of these components. So it's better to put them here. Maybe someone will ask, what if these components have different styles between two Aesop's? I will show you in the practical example how we can create a special CSS for every E-sharp in the NX repository and use the right one which you want. For example, I would say create a theme, theme of CSS. The layout will be the same, but the CSS will be different and the style. So I hope you understand the way how we are structuring our project in real-world. So we will see in the next lectures how we are going to build this structure with Angular. We will use all an X command to build all of this repository. 68. Installing NX: To create our structure, which we talked about before, we need an x CLI. It's exactly something like Angular CLI. So I will go to Google and type in ECS CLI. And in the first result, I will go to this link. And I will see that in Excel I is a command line interface tool that help you to develop, build, and maintain applications. So we will see how to generate applications. We will see also how to run a web servers. And also we can generate dependency graph, as we will see later, and et cetera. So let's install first NX, and it will be installed globally. So first, we go again to our Visual Studio Code, and we will type the same command when we installed the angular. So well, I will say here sudo npm install not Angular CLI, but NX. Again, it will ask me for a password and then it will start installing the NX command line for me. It will give me error because I have that NX already installed. So just executing this command, it will help you to install NX to be sure that everything is installed, you just dive in x. And when you get this, then it means that you have an X. For now, this is enough. We just need to be sure that we have installed NX to move on to the next lectures to see how we can work with it. 69. Installing Extensions for Rapid Coding: In this lecture, I am going to show you some extensions which will help you for fast coding. First extension is called angular language service. So this extension will help you for auto completing some commands in Angular. So as you see here in this Give, it will help you to autocomplete what is inside the script. So we have a template, as we saw before, that we have HTML template. And in HTML template sometimes we need to access some variables which they are in the script. So this library will help you to access these variables or methods which are in the script file. Another extension which we need also is a prettier. We talked previously about prettier and how to install it. I created special video for prettier because it needs some configuration. So if you didn't know about prettier, it will be in the Visual Studio Code extensions. So you can call it here and configure it. Another amazing extension which I am always using is called bracket pear polarizer. So we can say bracket pear polarizer. So this extension will help you also to color the brackets by group. So in this way, you will know what is the beginning and the end of your brackets, especially if you have a very big nested objects, honest and closures. So here you see how it's coloring based on the beginning and the end. It works for curved brackets and normal brackets. Another great extension which I am using is called CSS navigation. And this extension will help you to access any class directly by going to definition. So as you see here in this give, when you click on some class in the CSS, you will go to that class, or when you press Control and click on the class. So as you see here, we were in HTML file. We jumped to the app CSS file, where the glass is. Okay, if you don't want to install those extensions manually, I attached with this lecture some JSON file which you can located as the following. So you go to your project folder. I opened here My Folder Project. So we say it was in the desktop, my company. And here I open the project and I create a folder, call it dot VS Code. And inside this VS code, I will locate a file which is called extensions. So here I create a file, I call it extend shells that JSON. And here inside extension to JSON, I will give you the file which you need to copy. So it will be listed on the recommendations. And you will see here all extensions which you need for this course. And after you save this file and you go to the extensions again and type recommended. So when you put at recommended, you will get least of the recommended extensions, which they are listed here in this file. So you just need to install all of them and then you are ready for coding. 70. Creating Nx workspace for Your Team or Company: Okay, Now we will start a real coding and working with a real example with real-world project, as we talked previously, that we have this repository which we are going to implement in this course. So we need first to create a workspace or working repository. And in this working repository, we are going to give it a name. Normally, the name in the companies, take the company name. So the company is creating its own libraries and own applications, and all of them are shared together or the company is very big, you can divide repositories based on Teams. For example, I would say e-shop team, for example. And for example, machine learning team and for example, another theme for mobile development. So in this case, I can divide by the name of the team. So I will assume in this course that we are going to create repository for our company. We go back to Visual Studio Code, close everything. And we also close this folder and then append the terminal again. And here we will type creating a new workspace using NX. So if we go to an x-dot dev, you will see on the homepage and px create an ECS workspace. So when we go to get started, we will see the first command for creating a workspace. Let's copy this command and go back to our Visual Studio code in the terminal. Paste it here. And we have a preset, angular because NX support and other frameworks like React and also no JS. So MPI x, which is a comment bundled with MPM, is worked for creating a workspace or applications. So when we press Enter, it will give us a notification. What is the workspace name? This is what I said before. It will be company name or the theme name. So for me, I like the name Blue Bits. And what is the first application name? As we saw before that we have multiple applications so we can create or type the name of the first application in this repository or in this workspace. So it will be NG shop. And what is a styling is used inside this N G sharp or in this application? I prefer sas. And what about linting ES LND or the Estlund? The modern linting tool now is ES layer, which will fix for you all the mistakes which can happen during coding. And it will give you errors. So it will find and fix all problems in your JavaScript code as we will see later. So I will select ES lint because TS land, as you see here in the notification that's used by Angular CLI. And it got deprecated and use NX Cloud. It's like something for building the project and running some details and GitHub integration. So we say no. And we will see that it's now creating the workspace. We will start to install some packages using MPM install, everything is done automatically. And as you see here, the package installed successfully. Add, installing more packages which are required for this project is continuing to create applications. And you shop as you see here and all the required files. And this ND shop is Angular project. So we are ready and we have all the required files for our project. So let's open that project. We go to file or we can click on this folder or this icon, and we click Open Folder. And I will go where I installed my company as you remember. So here and I will see their name, Blue Bits. I will go inside this folder and click open. So it will open for me the whole project. And we will talk now about those files. But first, we will see that it's also recommending another extinctions which needed for development. Let's click on install. For example, that is extension called jest runner, which is a tool for unit testing. So we go back to our application and let's check those files. So as you see here, we have a folder apps. So in this app, it will be located my applications like candy shop and also the admin panel. So here we will have two applications. And what is this? N G sharp, E to E. This is end to end testing. So you need to have also application for that, for end-to-end testing. And in the lips folder, we will see that we are locating here our libraries. Currently it's empty, but we will see later how to create those libraries. For example, the UI library as we talked before, and also products library or does library, et cetera. Then I think here all applications are using the same node module folder. So for every application you install here or create here, you don't need to create another node module folder. The same thing you have here, a package JSON. So you will have the same libraries which are used all among these applications. And the package Jason is automatically created by NX to meet all the required information which are needed for creating or building applications and serving them. We will see all of these commands later and those libraries also. And in this annex JSON file, you will see the listed projects and the libraries which we are going to create. We will not also about this tags later. So here, all information about this workspace. What is important for us is this part, as you will see in the next lectures. And angular JSON, as you know, Angular applications are coming always with some configurations. For example, you need to include some specific styles which are inside the application. So as you see here that we have here all the applications listed under projects. So we have here any shop. And when we create another application, we will have, for example, admin panel application. So in this case, you will see all configuration related to this Angular application. It's like you are working on stand alone application, but under peak workspace. So when I want to create a style specific style, for example, I have here style CSS, which is the default one, which come with Angular. So if we go here, abs and G-sharp, SARC, and we will see here styles, CSS, assets folder where you are locating the images or some forms. So you can located in assets folder and you must declare that for the application main ts is the entry point for our application where we are bootstrapping all the libraries and all the TS code which we are writing at an index HTML, it will be the entry point for our template. So as you see here, we have here the head and the body, and inside it there is blue beet roots. So in this route, we will call this component, which is entry point for our application. So it has already a default templating. I think we will clear it. But first, we will run this application to see how we can run it. And then we will delete all this content to start our issue. If you remember, I told you previously that every application contains of components and modules and services. So here is a module which contain one component currently, which is called app component. You can create as much as you want components. We will see that also later, how to communicate and work with these components. And the nice thing here and eight snakes that it comes also with prettier configuration. So you can configure your prettier as you want. So let's add back our configuration for prettier as we configured before, so we can take them, copy them. I have them copied. I put them here again. So we have top width four and print tweets 160. And some other configuration which you carried in the quotation of prettier ES Linde is also configuration for the linting, as we will see also later. And the nice feature here that when you see some configuration file, for example, ES lint RC, you will see one global and one specific for application. And when you want to do something like a specific for this application, or especially LinkedIn for this application, you can add your configuration here. But to warn you want a global configuration, you can add it. Global folder there. Same thing for TypeScript coffee. You will see here that you have a general configuration for the TypeScript. And inside T is coughing application. In the application level, you will see a specialty is conflict for every application, we will not go so much in details, our goal to build our application. And we will see whenever we need to use those files and we need to configure that. So let's now try to run this application. It will be angular application, which is called ND shop, and we are going to run it. So I open my terminal again. And it's very simple. I just type in x, starve and then the name of the application. So I will say NG shop. So here it will start to serve this application. So I can see it in my browser. So now the application is compiled successfully. Let's open it in our browser. So I will go here to my browser and type in localhost 4200, and we will see that the application is running. So when I go to the application again, to the homepage of this application, delete everything. And I will put H1 and I will say E sharp or NG e-shop. And save it and open again the browser we will see and G-sharp. So in this way, we are serving the application. We put NX serve and the name of the application. 71. Creating the Applications (Admin Panel App): Okay, In this lecture, I'm going to show you how to add more application for your workspace. So if you remember, we have to create two applications. First is the e-shop itself, where the customers are going at entering and browsing our products. And the second application will be the admin panel for this e-shop. And in the admin panel, I will see how I can edit my products, edit users, and edit orders. So let's create now the Admin application. So here in the panel, I will use this for keeping serving of the NDA application. You can open multiple terminal windows by clicking on this plus. And here you will have another terminal window. So you can now create a new application. So we need to execute some NX. And this NX command will be a generate. And at novel is the name of the company which created any X Mono repo. And then what the type of the application I have is angular. And then I will say app, create for me application. And then I named the application which I want. So I will say here admin. So Admin app, or admin, or admin E sharp, any name you are free to select. So I will create an admin and then we will see how it's creating the application. It will ask me first for what is a styling system which I need for this application? I'm using always SAS. You have freedom to select which one you want. I'm going to use SAS. And then it will ask me another question about if I am going to use routing in this application. Actually, it's going to generate a new module for me for routing. We will see that later. So don't worry about it. Just make yes, and we will talk about that later. So in this case, creating the application. And we will see now in our file explorer, we will see that we have admin and N G sharp, and every application has end-to-end test. So now let's try to serve with this application. So we can run this application in the another window. We have a terminal here that we are running our application already, which is NGA e-shop. But we can now also run up to application together. So let's make a clear. And then we will see NX serve as we saw previously, that we do serve. And then the name of the application. So it will be admin. And as you see here, it's very smart. It's telling me that this port is already in use because I am using this port for the previous application, which is N G sharp. So here it's asking me, do you want to use another port? I will say yes. Then it will select random port for me. And then I can open it in the browser with this port. If you want to select a custom report, you don't let an extra generate for you the port. You can just put minus Minos port and then the number of the port you want. So I am choosing 4,100 and run this command. And then we will have that our application is running on that port. So if we go again and to the browser and browse to local host, we have 4,200 is used for energy shop. Let's open another tab. And we will try to say local host 4,100. And we will get here the admin, which is admin application. So by going back to the application route or application route, as we saw previously, we have this custom code already. Let's remove it and then try to make each one. And we will say, for example, admin panel. We will save it, go back to our browser, and we will see that it got updated to the admin panel. So in this case, we are running now to applications together. 72. Creating Application Level Components: Previously, we have seen how to create the structure for the application. And in a theoretical way, we said that some applications has their own components. For example, as you see here, that the e-shop application has E-sharp homepage component and also banner and category banner and product list component. Because these components are not used in other applications. So we put them in the application level. So this is the meaning of application level components, but the library level components, they are the components which are located in the libraries or in their shared libraries, like the login component and register component. And in this lecture, we will see what are the comments which creates for me the components in the application level. So we will create first a homepage component. And inside that homepage component, we will have header and footer. Let's do that practical and jump away from theory. Okay, So we are here now. We are going to create components, especially for NG shop application. So we are not going to do for the admin. We will see that in the next step. So first of all, we are going to use also the command line for creating components. So as you saw previously, we have already a default component, which is called app component. This app component is the entry point for our application, and this is exactly what we see in the browser or the entry point of the application in general. So as we saw previously, that this component can call also another components. So we can create another component, and let's call it here in the app component. So first of all, we open a new terminal and creating a component with n x will be the same way. How are we creating application, but it's mostly similar to Angular. So we are going to have an x generate component. If you are used to Angular, you can say mg generates component. But here we are saying an x, g, which is a shortcut for Generate and then component. And then you can specify the name of your component. For example, I want to say home page, for example. And then because you are using an X workspace, you need to specify the project. So we need to specify the application. So the application we have here is N G sharp. So I will put minus-minus project equal to NG shop. So here in this case, I will have the component created in the NG shock to be sure that your component is created in the right way, you can dry run your command so you will not execute anything. You will just see what their common did. So you will not see any change of the structure here. You will just see here in the common line what it did actually. So we can say minus, minus a dry run. So run this command in the remote, don't do anything. Let's press enter. We will see that we got error, I think because I have space here between project and N G sharp. So let's try to remove this space. And then try again. We will see that it's really working. So when you get that error, you who have to be careful about the command to not have spaces between the command and the value. And if you ask how I am returning to the previous comments, I am using up and down arrows on the keyboard. So then you can go in the history of your comments. So as you see here, I use this as the last one. We will see that the component is created in apps. You shop, source, app, homepage, and homepage component. And as you see here, it should be located here. So apps and you shop source component and then here. But normally we are locating the pages inside some folders. We are locating the components inside also some folders which express their functionality as we will see later. So because this is a page, I would create a folder, call it pages. And inside this pages, I will put the homepage. So how we can do that? We can do it very simply. We just say pages slash and then you can pass the name of your component. So when we press enter with a dry run, we will see that the component is created in app Pages folder, homepage, homepage component. So as you see here that we have created a folder inside the application. So let's try to run this command without dry run to see what exactly it's doing. So when I click on Enter without dry run, I will see that I have created a component or a folder with my component. So in the same way, Let's create another component for the product lists page. So we can say the same. I say pages. Product list and then project name and G-sharp. So I will press Enter, and then I will see that I created another component inside pages. So I have now two components. And every component or every component folder will contain the HTML template where I will write my HTML and the styling file, and also the testing file, and also the TypeScript file where I will grab data to the front end. You can also structure it in different way. You can say pages and then say, for example, basic. And then in basic you put Homepage Contact Us, for example, about us, et cetera. And another folder inside pages, you can say, I want to create a product folder. And inside that product folder, you put the product list, product detail, product orders, et cetera. And if you see in the common line, you will see that these files are created and some files are got updated. What file is updated? It's the app module inside this application. As you remember, we have previously defined that the module contains multiple components, so its container of components of my application. So here I am saying that this module will contain multiple components, which is AB component, the basic one, and then the homepage component and the product list component. And then we can try to check how these components are working. So we have here, for example, homepage component. It has a PIE paragraph and homepage works. So let's refer to this component, refer our application to use this component. So in app component level, I will write the tag of this component. So how we know that tag of this component, you can go to their component ts and you will see something called selector. And in this selector, you will see that it's created by our company name and the component name. So we can copy this one, the company name Previously we have defined when we define the workspace. And of course you can change it as you want. So for example, I will say here, e-shop homepage. So we need to do that. So I can do here. And then I copy this one and paste it here as an element or as a selector. And I press Save, and I press a for this one. And we have previously that our projects are running. So it's compiled successfully. And going back to the browser, we will see that this application is running already and we have component running there. Let's add also the other component under it. So we go back to our application and we will use also the selector of the component. So I will press here grew bits. We can keep it and of course you can change the name as you want, but there are rules. We will see those rules later. So here we have creating that second component. I save, it's compiled successfully. I go back to the browser, I see those two components are working. So this is a way how to create components with NX command line. And we will see later how to structure better and better. 73. Routing to Application Level Components: Welcome back. In this lecture we are going to talk about routing, routing the components. So I want to have some URLs to refer exactly to my component. So I want, for example, the page for a product list. So I will have a link where it will say localhost 4000 to a 100 slash products. And then it will lead me to the product least component. And I would like also to have the homepage component without any suffix or without any route, like it will be the default route. So I will have here a homepage component for the default route and for the product list, I will have localhost slash products. So let's do that and see how we can generate the routes. The routes basically are related to the application level. So you need to specify that outs in the application. Also, you can have specified routes in the library, as we will see later. But now let's do the application-level routing. So I will go to application module here. And in the import, I go here and I say router module. Call for me router module. You see this extension, how it's very great. It's auto importing the components which I want, all the modules which I want. So I don't need to type import router module from Angular outer. I just dive the class and then it really imported automatically when it's available. So to add a specific route, you need to have router module dot for root. And here you are going to specify your routes. So here we have the first parameter, Is that out? So first of all, we need a route for homepage and a route for the product list page. And this route is normally an array of routes. So we need, first of all array and inside of this array we have the objects of that out. Every object of that out, you need to specify the path which you want to define. For example, I want to define the default path and the component which this bath is growing to refer. So I will say that component will be the homepage component. And also I will have another path, which is, for example, the product list path. So I will say here bath products. And inside this path, I will say that component is product list component. And then when we go to the browser, we will see that when I go to localhost that I still have Homepage work, product least work. Why? Because I need to specify their outer outlet, which is based in the application component or in the root component. So to do that, we go to the app component and then we need to remove those and say router outlet. We need to specify this tag or this selector to specify the router outlet. So this router outlet will guide me to the right component based on the link which I provide. So when I save and go back to the browser, it's compiled successfully. And then I will see only in the route that the homepage component. And then when I want to add a product list, I will say products as I specified in that outs, I will see that product list work. So this is how we are defining the internal routes which refers to another components. But first, I would like to have a clean code. So let's do some refactoring. We can put this array in a variable so we can have a clean for wrote. So I define here a constant, call it routes. And these routes has a type routes and which is also automatically imported. And this is equal to my array. So let's do like some better formatting here. So we have here the path, first path and also the component. And then I pass these routes constant 2, 4 root, and save it. Then we will have our routes here. In more advanced level, some people are creating a special module for their routes. But you can also do it in that way. But no problem, we can't keep it in that way. And we will see later when we are refactoring our application, how we would create a special module for routing. For now, this is what we need exactly. We have now internal routes. We have the path which is the default one, is going to the homepage component and also the product which is going to the product list component. 74. Master Page with Header & Footer: Okay, in this lecture we are going to make a header and footer for our application in the G-sharp. And of course we are going to know how to create a master page. So every page in our application will have header and footer. So if you remember the creating of components in Angular or in NX was in this comment as we created before the product list, we are specifying the project name. So here I am going to replace these types. So I will have here, for example, a shared, shared folder, which is like a shared components. And I will call first one is header and inside and you shop. And of course, I want to have also another one which is called footer. And now as you see here, we have a shared folder with footer and header. So let's call this components in our homepage. So we can say here, call for me the first component. Let's go to the ts file to find the selector. I will put this one. And also the same thing for the footer. Add when we save and go to our browser. We are now in the product list page. So let's go to the homepage. I will see that I have header, homepage itself and footer. What if you see before that the product doesn't have header and footer. So we need to add them also there. So the best way to do that, we need to make the header and the footer like something like shared. So we can go here again and cancel this calling. We are going to app component. And inside this app component, we will place the header component and the footer component and the outlet where we are rendering the components, it will be in the middle. So if I go back again now to my browser after deleting this from the homepage. So we don't need them anymore. We have them now in app component. I go to the browser that the product list has also Header and Footer. So I go again to the homepage. I will see that homepage also has header and footer. In this way, I guarantee that I have a master page which contain always header and footer and the content is changing based on the route which I am specifying. And false file structure. Again, we can say that we have a shared components and pages. And pages. We have product-based homepage and also the shared components footer and header. And also the app module got updated with the new component which we have already added. So we have here header component and Footer component. We will see later how to make the styles and structured the headers and also the all components and the homepage component, exactly how we got it as a design. 75. Naming Component Selector Rules with ESLint: I would like here to mention about the naming convention of our components. As you see here, it's starting always with the name of the company or the name of the workspace which we are created. So it's better to have a special name which is based on the application when you are using components only related to that application. So I would say maybe we can rename this for example, to end you shop for example, header. And it will be in that way, we have it as a specific component for the energy shot. So the same thing I will do for the footer, and then we need to specify the naming also in the components themselves. So we need to change the selectors. So we replace this with the NG shop. And also for the header, we are going to change this name to shop. So after we save these files, we need also somewhere to change it in the ES lane. The ears land is a tool where it's specifying the linting for my application. So it will fix my errors when I am going to build my application or when I am going to deploy the application. So here, when I am running the ES lint, then it will tell me, no, you have a problem in your selector naming. So please change it based on the rule which is in the ES lint. So when I go to the Eastland RC file where we have the configuration, we will see in one of the lines of this configuration about Eastland. See that we have what is the directive selector and what is the components of vector. So the prefix is always blue bits because we have named our namespace or the workspace based on that company. So we need simply to change it to end you shop, then we will not have any ears lengthening problems. And also, you can specify what is the style of the naming convention. So you can say, I have a K-Pop case, which it will be like how we have it here. And you shop minus footer, or you can specify a camel case. A camel case comes like this, so we don't have minus, we have a capitalization. Normally in Angular, we have the directive with camelCase and their components electors are coming as a K-Pop case. And remember, we are editing the ES lint file, which is located inside the application. We are not editing the main is linked file because as you remember, we have ES lint file, general one, and then we have an application specific ES lint file. So here we have to put our migration, which are related exactly to this application. 76. Enabling Live Coding Linting: In the previous lecture, we saw that we need something called linting and we saw that we are modifying the ES lint file. And we said that the ES lint is helping us to fix issues in our code. But how I can see this powerful ES lint that helping me to fix my code live. Like when I am typing some code, I want to see what mistakes I am doing in this way after installation of the extensions, of the recommended extensions which we have before, and also the recommended extensions which comes with the NX. We see that ES land is not enabled yet. So you need in VS code, you need to click here on ES lint to enable the live lending of your code. When you click on it, it will ask you that the ES lint extension will use Node module Eastland for validation, which is installed locally. So do you want to enable that? Do you want to allow that? Then you would just say a low everywhere. When you allow that, then they ES lint comes active. And then you will start to get errors and mistakes of your code. As you see here, I got here and red error. Why? Because it's saying, for example, that I cannot have a constructor empty. Or for example, I come up have empty function. This is linting rules. And of course, you can modify this lending rules as you want in your EMS Lane file. Another example here that I got an error about naming the selector of this component. Because we before said that we put a rule that every component must be prefixed with N D sharp, E sharp. So here it works fine. We don't have any error and any problem because we specified that in the ES lint file, we said that everything or every component must be prefixed with NG shop. So when I go back again to that component which caused me and a problem and I put NG shop. I will see directly that I got that is everything is fine. Sometimes these errors are annoying, so you can exclude them also. So we need also some rule to add it to this ES lint file. So we can't say that non check for me about empty core functions. So you have a lot of rules you can modify. Then you can build your environment as you want in the way to help you to code in the best way that you want. So sometimes it's annoying to see these errors, even you are not doing a big mistakes. So you can disable some of these errors which are bothering you. So when you put the mouse on the error, it will ask you for unexpected empty constructor. So you need to have to fix this. So how to fix that? You will know the rule from this link. So when you click on this link, it will ask you to open it in the browser. And when we go to eight, we will see that this role, so you can add to your ES lint file these rules so you can turn it off. So if you want to do that, we just copy this and go back to our code. And in the ES lint file where I am placing my ES lint rules where we wrote this NG shop. We can add a new rule by doing comma, and we copy these two rules. So no empty function is off. And also I want to turn off the empty function for TypeScript ES length. So we can just also remove this part. We don't say give me error. We say just turn it off. So when I turn off this rule, I will see that this error is gone. And also we have here another error. We will see that its lifecycle method on, in it should not be empty. It's also angular ES lint broad. So also making this rule, turn of this rule, it will help you also to turn off this error. But for me, I would like to keep it. There are a lot of roles you can configure in your EMS land. So you can also configure them based on the documentation of ES lint library. If you go to the website, if you go to Google, you will find this library. It's called Eastland. Eastland has a lot of roles. So you have, for example, rules, unit test, but you are interested about the rules. You can check in the documentation, all the rules which you are interested in. I think what we have now is enough. Just again, a reminder, you don't need to configure this rule only in application level. Because if you remember, we have ES linked file in the application level and also a global one. You can configure it in the global one. So then in this way, you will not get any errors among all applications and libraries which you are going to create. So I added here, save it, and we save it here. We remove it from a specific application rule. 77. NX VSCode Extension: In the previous lectures, we saw how we are creating components through the command line using an EQ CLI. But NX made the life more easier by creating and extensions, which will make a speed up for our coding and generating of components, modules, services, et cetera. When you set up a workspace, the project comes always with the recommendation of extensions, as we saw previously, novel angular console. And this extension is already available in the extensions by searching for NX or in ECS console. So you can start this extension by clicking here. And you are always able to use the common line of NX, but in some GUI graphic user interface. So for example, I would like to generate a component. So I go here to NX and click on Generate. And then I will get a list of generator will items in Angular. We saw previously that command line how we are creating application. We saw also how we are creating a component, as we see here. We can also generate directives. In armed guards, a lot of types of elements which are provided by angular. They can be created here. Let's, for example, create a component. Again, as we saw previously. I will get some information that I have to put the name of the component, the name of the project, and also module. If I want some specific module and the style which is used for this component, you can, for example, CSS or SCSS is depend on your choice and many other options as you see here. So if you remember that we have two projects here. So we have admin and ND shop, and we will work on this course on both of them. So let's generate, for example, a page for the admin dashboard. So we can say that I want component, call it a dashboard. And the project name is admin. And as you see here, every time I am typing something, it's executing here, the command, but with the dry run flag. So as you see, I create a dashboard in the admin project and then I got it. Dashboard admin project. But I wanted in a specific folder. So I will say pages slash dashboard. And it will again run as a dry run and we will get it here. So as you see that we have all ability the same as a command line. So I'm going to fill this field. So we have here pages slash dashboard. The project is admin. If I want some specific module, nor I want to keep it in the app module as you see here. And also they use a style is SCSS, I prefer that, and also the change detection strategy. And we can keep it as default for now. And there is another, and there are another options which are really, for example, not so important for us now, but we will need them later as we see. But here also we need a selector. You can specify some custom selector, as we saw previously for the components. So I can say admin dashboard. So here we have admin dashboard and then we can have skipped test. For example, I don't want to generate the spec TS, which is this one, which is used always for unit testing. So you can also skip that. So all of that is can be possible inside this UI. So when I click Run, then the command will be executed. So let's try that now. I click run and I see the comment is executed, of course, without the dry run, so it's really executing. So I see here the dashboard component is created here and the app module is updated. So you have two choices here. You can use always an x to generate, also run projects, and also do a test and build them, which is like a GUI to make easy for you everything to not type in the command line. So for example, I want to run the project admin. So I go here to run. Then I select serve or build. So I will select Admin Center, and then I will click Run. And then it will also do the cell for me. So a tool select some port and I can run it on the browser. So as you see here, it says that the project is running on the browser, on the port 400, 4200. So if we go here, go again to the project, run it, and then we will have the admin panel. So as you see, that is everything is possible through GUI, but it's up to you if you want to use the common line or this GUI. 78. Creating Shared Libraries Through Command Line: Okay, Now we are going to a new step. We are going to build a shared libraries. As we talked previously, we saw that those applications are sharing some libraries for a specific goals. One of them, for example, u i libraries and also you there and authentication library. Another library is product and category library. And we talked before why we need to do that. And as a quick reminder, I would say the reason was because we are going to share the same components between these applications. So I need to have a login component for the admin panel and the issue of application in the same time we saw previously how we created components for specific application. Now we are going to see how to create libraries and create components inside those libraries. I'm going now to do it with the common line. And in the next lecture, we will do it with an x2. I threw the extension in VS code. So we go back to our project and I am going to open a new terminal. So by clicking on this plus here. And then I am going to execute the command for creating a library. That command which is used for creating library is NP x and x generate. And then novel, which is the name of the company which created in x. And then I will say workspace. And the type of the workspace will be lib, which means it's library. And then you can pass the name of the library which you want. For example, I would start with the first library, which is called UI. And let's try also to make it in dry mode. So with dry run, I ensure that law library will not be created, but just I will see what the command is doing. So let's press Enter. And as you see here, that the library is created specifically in this path lips UI and with its own ts config sources and code. And of course, another files could update it like the ts config. We will see why and also Angular JSON, NX package JSON, et cetera. So what we will see later that this library is created in lips because we have lips UI source code. And as you see here, we have application libraries which are shared among those applications. So let's try to execute this command without the dry run. As you see here, the library got created. And we are seeing here in the File Explorer, we see that it has its own library or own modules. So you see here that the UI has a source and leap and this leg here. And you can have index file for exports, as we will see later for calling those libraries. Said I think here also that you can specify a read me for this library. For example, you can say UI, and you can give, for example, description for this library. I would say this library contains the UI components which are used in the company, for example. And what components, for example, we have banner component, we have slider. We have, for example, another thing like stepper, etc. So as you see here, we have everything described for this library and it has its own README file. Okay, let's dig more in the files. So we see that the library is created here. So in this level, not after the source and in the lip, I am going to create my components. So we will see how to create components later. And now we have this UI, you either TS, which at the file example, just for showing you how to export functions, export methods, export modules, as we will see later. And also we have index.js. This index ts is used for exporting everything from this library. For example, I am going to export module. I'm going to export, for example, component service. So we need to list here all exports which we need to export. And then we can use them in another places, like in applications or in another libraries, as we will see later, we don't have to dig now in this index file, we will see it impractical how we can use. And again, we need also especially Estlund configuration for this library. If you want to specify something not general and specific for this library, you can add the rules here. So in this case, only this library will be sensitive for ES linting based on these configuration rules just is used for testing and unit testing. We will see also how to use or how to do a unit tests inside the libraries in another sections if you want also some special TypeScript config rather than which are in the general one. Because as you see here, we have ts config dot pace, which is the main ts config which is created here. And also there is a ts config or TypeScript config specific. Again, for this library, what did the difference between those files is just about how to create a references. It's only a tidying the files. So you don't need to care so much about that. So if you want to make changes, as we will see later, you can specify them in ts config dot library, which is extending the main ts config, which is located in the same folder. Okay, what the files are got updated as we see here, ts config Bayes, JSON is updated. So why it got updated? It got updated because it added a new path for this library. We will see how to use this path when we are going to call this library or when we are going to use component in this library. So here we are going to save this path somehow. And we will see later who you are not going to use this path for importing components or importing modules or services. But to use this shortcut or this short part, angular JSON also that updated, we can see why, because you know that in Angular, you must specify and define every project which is created in your library or in your old project. So as we see here, we have applications, and then we have our library. And we see the root of this library. We see the source route and all configuration which are needed to configure Angular to make this library working in a good way. And x JSON also get updated because we added a new library. So it has also UI and tags. We will see the usage of these tags later. Okay, cool. So what is important for us now that we created a library? We will see later how to create the library again, but with, not with common line, but with this extension. So we would use this generate or NX extension to generate a library which we are going to implement and use these libraries in our application. 79. Creating Shared Libraries Through NX Extension: Okay, Previously we created the libraries using the common line. Now we are going to use the extension, the extension which I showed you before in the previous lectures, which we downloaded to Visual Studio code. So in this lecture, we are going to create all the rest libraries which we need to build our project. Previously we created the UI library. Now we are going to build users and authentication library, products and category library and all those library. So back to Visual Studio Code, we click on the NX extension and then we go to Generate. And for generate we are going to select a library. So here we have to put the library name, so we will call IT products. So because we have previously UI and now we have the products and we create later the users and the directory. If you want to specify some specific directory we don't need, we want to place it in the lips, as you see here. We have here lips and we want to place it here. So everything is going fine. And we are going to click Run. And after executing this command, we will see that lab I barely got created here. And we will see that now we have UI and products. Now let's move to the second library, which is users and authentication. We call it users is enough. And then it will create also a dry run. And let's dig more about the comments or parameters of this library. First parameter is the styling or the styling system which is used inside the components of this library. I would use always scss. Of course, you have freedom to select what system you like. Also, if you want to have a specific directory for creating this library, you can define not only ellipse, but you can define another directory. So you can specify the directory here, but when you let it empty, it will be created inside lips folder and add module spec, which is a module which is created here. And this module has a test file. So when you enable this test file or when you enable this option, then you will have a testfile unit test file, Something like those. So if you don't mention that, then you are not going to have this spec file, but it's easily and you can create it that manually later. Buildable is generate a buildable library. Of course, we need always to build all of those libraries which we need for our production. But by default, this generate buildable library can be executed when you are going to execute build command for this library, as we will see later, enable IVY is for enabling for a libraries, then it, you'd use these compiling method in Angular. Angular has many compiling ways. One of them is IVY. Ivy is a complete rewrite of Angular rendering engine. If you know more about this, you have a o t and also that is IVY. Ivy promises huge improvements for your application. With IVY, you can also compiled components more independently of each other. So you can enable that for this library and no problem. So I got an error here that enable IVY must be only used with buildable. So we need to enable also this one for this library import pass. We saw previously that in the ts config that we have some specific path which is generated. So you can hear also specify your partners based on what you need. For example, the products has generated with Linda company name, with AD, and then the name of the library. And the same thing. If you want some specific naming, not like this, then you can specify it there. But I want to have the same lazy loading modules is used also for not loading the module directly. When you are running the application, you will use these modules or libraries only when you need them. As we will see later, we will use the both types. We will use the lazy loading modules and the immediate molecule. Then in turn, as we saw previously, what is a winter is used for this library. I prefer always to use ES lint. When you specify the lazy loading module, you need to specify the pilot module. Which module we'll call this module. Normally, it will be the application module, as we will see also later. If you want some specific prefix for the library components or directives, as we saw previously, then you can specify it here, so you don't need to go and edit the ASM file. For example, I would use also here, users publishable. I think no, we don't need that library publishable. Routing it the same way how we saw routes in application level. Also, we can have routing for the library level, so we can configure that also. And also there are another options like skipped formatting files for, for example, for prettier and also skip package JSON to not add dependency to backend JSON also to skip ts config, which is to not update ts config for development experience. No, we need all of this stuff and tags. We will talk about it later when we are going to call this libraries in our applications. Unit test runner is also for unit testing we are going to use just as we will see also in the future. So let's run and execute this command. And we will see that all the command got written here with all parameters which I need. So we don't have to pipe in the command line. So we just need to do some clicks just to generate those comments. And as we see that we have now the user's library got created the difference here that we selected fairest, that we configure it with a router. So we have already the router module, but for example, the products library doesn't have a router module. And also we talked about some specific prefix for directive and components. We will see that we have it here also. So we have users, not the company name. So we have camelCase for directives and K-Pop case for components, and the prefix is always must be users. Now let's create the last library which we need, which is called orders. So we already products UI users. Let's create also the orders library. So I will replace this with orders. Everything the same. We have here, no directory, everything is defined already. And we replace the prefix and all the other information which are defined already. So we click run and we generate this library, and it will be located near the other libraries. If we go again now to the ts config base that those library all created here. 80. Creating Components Inside Libraries and Use them in the Apps: Okay, in this lecture, we are going to know how to create a component inside the library. For example, the banner component, which is inside the UI library. And we will see as well how we can use this component in the application level. For example, in N G sharp application also here we can use the command line for creating the component or the NX extension. I'm going to do that in both ways. So we have previously created those libraries, UI products, users, and orders. So let's first create the component using the NX extension. I will go to annex extension, click on it, and then generate. And I would use the Generate of schematics from Angular because an x doesn't have this generation for the components. So we would use this one, schematics angular component, which is creating an angular component. Let's click on it. And then we can give you their name for their component which I want to create. For example, I would give it, as we saw before that we have banner and the project. The project is the name of the library where I want to create this component. As we saw previously, we have many libraries. One of them is UI library. And then I'm going to use the another options. Let's go quickly over them. So we will go first that we will see that module. What is a module which you want to define this component for? As I told you previously, we have the module containing multiple components and every component must be related to our module. We can keep this module empty, then it will use the default module of that library. Because as we see here, that products, for example, has a default module called Products module, then the component will be placed here or the declaration of the component will be placed here. So I go back again to our generator. I will select the style system. What is the Style System I want to use is SCSS, as we agreed from the beginning in this project. Also, we need to know about change detection strategy. This strategy is defining how the component is getting updated. So for example, I have a component which contain the text, for example, the banner itself. So I want to update the text of that component, of that banner from outside, from another component. So here I can choose the strategy, how it will get updated. Default is always the component, is listening for the changes on push mean that every time I say Please update yourself, then it will get updated. But if I push a new text to the component without informing the component that there is some update coming, then nothing will happen. So always you can choose the strategies. I will explain that during the real-world explanation of our project. For now, let's keep it as a default. Some people prefer to have a display block on the host level, like the component itself will have a display block. For me. I keep it empty because I don't need it. Entry component, this is deprecated method. We don't need it anymore. Export, you need always, sometimes to export the component if you want to use it in another modules. So if I want to have this banner component to be used in other modules, I need to export it. So for now, let's keep it like this or you can define this as an exported component. Flat means that we want to create this files of this component on the root level of that project. For example, when I create this component, it will be created here and it with its own file, not inside a folder. So for me, I would keep it inside a folder and use it inside this library. So it's better to not check this flat in lifestyle if I want to include inline styles inside that component, as you know in Angular inline template that I don't want to have separated file for the template. So this component will contain inside it the HTML code or you can put it in separated file. When you check this, then the component will be created with its own template, without any HTML file. Because every component in Angular must contain a JavaScript file, HTML file, and the styling file, which can be CSS or SCSS. But for me I would keep them separated files. Lint fix, this is deprecated. It's not used anymore. The path, if you want a specific facts in your component to be defined, you can define it here. You can say the folder where you want to create this component. But for me, I keep it empty, then it will be created inside the library, which I target. Prefix, as we saw previously, that we have every component has selector. So we need to define what the prefix of that selector. So for me, I would say always, every component inside UI library will have prefix UI. And also here the selector, it will ask you what is the selector? The selector should be created here. So I would say banner, skip import. It means that don't place a component inside the module, as we saw previously, that the module contains multiple components. So I need to not put it here. Skip Selector specifies if the component should have a selector or not. Now we need a selector. Skip tests, then it will not generate the test files which we need for unit testing, which is ending with SPECT of Ts. And at the end, we need to know what is the type of that component or the type of this item. It can be directive or component. We keep it as component which is be located in the naming law. So we will have like banner.com dot ts view encapsulation is the view encapsulation strategy to use in this component. So you can keep that empty for now. So when I run this command, I will see that I am always getting error. Cannot find NG module uses keep import option to skip importing a module. No, we need that in module because we are going to use it in another component or in the application level as we saw before. So for that, we need a module. Why we are getting this error? This error comes because you, either library doesn't have module and because we have created it through the comment line using MPI x as we saw previously. But the other components or the other libraries we have there, which we created with NX extension. They have module, but the UI library doesn't have any module. So let's create also that. You can create that module manually like the others, or if you want, you can also use the NX generator. With an x generator, you can also create modules, as you see for example, here we have schematics, angular module, and then you specify the library and you specify the path. And that's it. Exactly like how we do with their components. For now. Let's keep it, for example, do some professional work to do it manually. So first of all, I will create a new file. I will call it UI dot module dot ts. And every module in Angular must start with annotation NGO module. So as we see here in products module which is generated previously, we have that NG module and imports and then the name as a class of that module. Let's copy this one and use it in our UI module. Just we need to rename products to UI. And in this case, I will have my generator or my module ready be used by the generator. So let's try again and let's run it. And we will see that the comment is created or generated. We see that n degenerate schematics angular component name banner project UI style is CSS or SCSS and then export. And if I go to the module itself, I will see that there is declaration and exports of the module or of the component which I created. And here is the component. We have HTML template, we have the CSS, we have also the desk file and the TypeScript file. So let's generate another component using the common line. As we saw previously, we can execute with an extension or with the common line. Some people doesn't like the extension, so they like to do some common lines. The common line we have here is Andy generates schematics, angular component, and then you specify some properties which we want. So I'm going to copy this one and open a new terminal. And then I will paste it, and then I will rename the banner to be, for example, slider. So we will have slider and here also as well as slider. So through the common line, we do these comments. So what I need to change is not mg, it will be an x because we are executing NX comment. So here I will say NX generate schematics angular component, and then I specify the properties. And then if we run it, we will see that it's generated with exactly the same values which I wanted. And it will be near its brother, which is called banner. Okay, now let's see how we can use those components in my application. Because we are now in a library, we are not in the application level. So as we see, we have applications and libraries. And in the application, I want to use these components. So for example, let's get this banner 1. We can create, for example, anything inside it, like we can say a paragraph banner works. And we would use this component in that library. So how we are using a component in general, I just go and choose the selector. I will say, for example, it should be like this UI banner. And this selector. I'm going to take it and place it in my application. So I will say here AB component. And I will say, for example, we can put it inside here. And I want to say this one, UI banner is UI banner. But we have problem here that u i banner is not known element y because it's not known as a module inside this library or inside this application. So I need to take the module of the UI and imported here. Then the application will know that there is a component called UI banner. I can use it from the library, which is called UI. How we can import the UI module or the UI library. It's very simple. I go to the app module. Then I write here UI, as we saw previously, module. And then this UI module, it will be imported from the path. So I will say import UI module from, and then I will specify the path though. We have the organization name and then the UI. So with that, I will have access to the UI module inside the UI library. So as we saw previously when we created the library, the ts config is changed to define for us some partners which I needed to use from other libraries. But I am still getting error here. Why? Because the UI module is not located in this path. So elipse UI source index.js. Let's navigate to this one. I will go and check it, and I will see that I don't have export of the module. So what we need to do is just export star from then I will say lib and then the module itself. And when I save and go to app module, and then we will see that everything is fine and is defined. And if I go to app component, again, I will see that I will not have any adult here Because you, I banner is known by the application because I imported the module of UI module. So let's now run the application and try that out. So first let's save everything and you can run your application using the command line as we saw previously. Or you can also use the NX extension. So you just say NX serve, and then you'd specify which application you want. So our application is running now, and as we see here, that it's running under local host 4200, the port. So I am going to the browser and then I will see that we have this one. And then I refresh the page, and then I see that the banner is inside this application level. So we are using actually the component which is created inside the library UI, inside the application level. 81. How to Call Libraries Check Paths: Okay, Now everything is good. We have specified our component, we imported it from the library and we use it in the application. So let's remove it from here now because we are going to use it in another places, not here as we will see later. Now I am going to repeat the same idea just to confirm it and fix it for you. So when I want to import a module, I can use always the path. The path is defined in the ts config file. And inside the config file, we can always modify this path is as we want. So we see that this path is referring to this file and always in Angular or in TypeScript in general, when you want to export some modules or classes or for example, models, you can always use this concept. So I have an index file where I am always listing all my components which I want to export or modules or services. So for example, I have in the UI the service for grabbing data from the database. Then I need to place it here in this file. So I will say, for example, export, then everything from the file, for example, which is called Library. And inside this file, for example, there is this service. So everything you want to use outside of this library, you need to export it. And then you will use that bath, which is specified in the base or in the ts config Bayes to use it in any application or even in any other library. For example, in the product I want to use also the UI. So I go here, then I say that I want to use the UI module inside these products module. So the same way always. So this, we save that time or finding the path where we want to locate the module, or we want to locate what we want to import. So in this case, we have unified path and it's defined everywhere, all the application and all their workspace, see it. Then. I will not have any issues with defining the path in the right way. 82. What about Shared Style Files: Okay, as we saw previously that we created a components, and those components comes with a styling file. And in this tiny file, you can specify the styles specifically only for this component. So you cannot use this styles outside of this component. So I would say for example, I will give this a class example. I will give it like color red. And inside the style or the CSS file, I will say color. I will give a class, call it color red. And the color will be, for example, red. And when I go to the browser and check it, and then I will see that the component is not showing here because we remove the call for it. So let's call it back again. And we go again to the app component. I say you, I banner. We will remove it again. It's just for testing. I see that this color is working here. So when I use this class in another component, then we will see that this class is not giving any effect because we are using outside of that component. So let's go to the homepage component again, and let's try to use that class. So here we have this class color red. We are in Banner component. I will go now to the homepage component which we created before. So I will go here and say color red. Go again to my page. And I will see that there is no any coloring because this is styling is specific for this component. You cannot use it outside of this component. So this is view for example, for me, it's not so much good because I would like to have everything is shared because I am using a shared library. So I am using a shared workspace. So I would like to have also the styles are shared among all the application. This is one of the reasons. So my idea to avoid that, that we can create a folder near those folders so we can make inside it the styles and everyone inside this applications and libraries can use these styles. So let's try that with this class and we will see the results. So first of all, I will open a new terminal. And then I am inside my, for example, organization, the workspace. I'm going to create a directory, I call it styles. And then we will see that this style is created here. Let's create a file inside the styles. Call it, for example, style.css. Okay, and now we can use this dial SCSS inside any application. So for example, I am going to use it inside and you shop. In any shop, we have already a styles file. And inside this styles file, you can import whatever you want from outside of this library. So I can import that file which I created outside, inside this file. So the entry file for styling of this application is this file because it's specified in Angular configuration. If I go here to the angular configuration file. So I will see in the assets or the styles that it's using this file. So apps and you shop source styles, SCSS. So I will know that my project is using only these styles file as entry style. So let's go again to that file and import the external file which I created previously. So I will open here quotation, and I will go step-by-step outside of this folder, outside of the application level. So over more. And also over then I am here. I can see, for example, apps, lips. Then I can't see maybe the styles here, the folder styles, and then use the style CSS. So here when I import this file, then all the components inside this application will use this style. So when I go back to the component and I will say, for example, in their lips, I go here to the component, cut, the style. Let's cut it. We don't need it here anymore. So we need to place it inside the public style or the shirt style file. So I place it here and we remember that we call this class here inside this component. And also in the homepage component where I wanted to color also the homepage works. So we will see at the end that these two components shared one class type or pause it of only internal one classified. So as you see here, we have Homepage work and banner works, and they are colored in red. So both of these classes or those components shared one class. So we can use all of these, for example, shared classes in all application and all the libraries which we want. So its better always to create a separate folder for your styles and share all the classes inside those tiles. You can also import libraries, as we will see later. You can also, for example, define some material. You can define some variables. The other benefits also about extracting the styles outside of the application or components specific is that we can use the shared variables. So for example, if I am defining a variable in my sum component, I cannot also use it in another component. So you know that in SAS you can define a variables. So for example, I would say primary, for example, color for my company. For example, color and the primary color for my company is green. So I want to use this valuable everywhere in my application. But if I define it inside the component, I cannot use these valuable. So in this case, I can use this valuable everywhere where I can create the styles files inside this folder or the shared folder. So maybe I would say that we can get rid of all this internal components because we have also not a good benefit here that we cannot see the variables which are available inside this shared folder. Because every time I want to use the primary color, valuable, then no, I need to import the styles again. So I need always to say that import inside this component all the styles or the style which I wanted to create here. So when I do that, then I can see the primary color green again. So otherwise, it will be a headache for me because every time I import this file in this component, then it will be a lot of import and we will end up with a very complicated structure. So for me, I would say try to avoid components stylings so we can delete this file In the components and also every component style we can delete the totally, we can create a nice structure in the style or the public style. So we can specify this is for the banner, this is for the homepage of the admin panel or for example, this is the homepage of the e-shop. So in this case, you will be able to have more control over all your variables and also over all of your styles. So remember, after you delete the styles, you need also to deleted from the ts file. So you will see that you get error here because you deleted the components style from here. So we have also to be careful about that. So afterward, we will see how we can structure slowly these files or this folder or the external styles folder based on our need, based on the application or based on the library, the most important for you now that we created a public folder, this public folder contains a public style. And this public style, you can use it inside the entry file for the styling in the application. So here we can define it here. And then we can use the classes which are available inside this folder or inside this dials. 83. Structuring Style Files For Applications (NgShop + Admin): Alright, now let's structure the files based on the practical of building the Ayesha, as you see here, that if you imagine with me that the structure, you see it in front of you, you, we have, for example, an header. We have the footer, and we have also some components between. So we can already define our structure based on that. For example, I would have a file styling, especially for the banner, for where is written the best products. So here this banner will have its own styling file categories as well as you see, we can also define their own styles and their own component. And also these components which are defined for feature products, they can be also used as a separate styling file. But as you know also, we have an admin panel. And admin panel is also using some features of the product. Or for example, we will have another e-shop but with different style. So in this way, we have to define our styling structure based on that need. There are many different ways to structure the styling files, but you can choose what is exactly needed for you. It doesn't mean what I am doing here is there. I think it's just the thing which I like, the structure which I like. So you can also do your own structure. I will show you how I did the structure for e-shop, which is combining the admin panel and the shop itself, and maybe for another future shop. So going back to our project, we are seeing here that we have structured some files. Let's close the apps lips and goes to the style. At, in the Styles, we are going to define the following structure. First of all, I am going to have a specific file for every application. So for example, I will rename this style CSS as admin CSS. And I will create another file, I will call it, and you shop dot SCSS. So in this case, I will have a specific styling for every application, okay, first of all, before everything, every application needs some configuration. Styling configuration. For example, you need to define what are the colors, what is a font, and how it look like, or which libraries you are going to use for as external for your, for example, application. Like for example, Angular material, awful example Bootstrap or end u-prime, as we are going to do in this course. So in my point of view, first, I will create a folder, call it inside the styles, call it a base. And inside this base, I will combine all the files which are always needed for every application and every library. I will give you an example. So first we can create a file, call it colors. But SCSS at inside this colors, we are going to define the colors which are going to be used inside the applications. For example, the primary color of my application will be the orange or the brand color. So here I am going to define two variables called them one, primary color. And this primary color will be, for example, FF three a 000, which is for example the orange. And then maybe I will need another color, primary color but in dark way. For example, when I am hovering over a button, I want to show it like a darker. So here we can call it dark. And then we can define our own color, for example, 29 000. So this is a darker, a little bit darker orange. So these two variables I am going to use in all applications. Okay? Another file is needed. For example, I need to have some configuration or conflict. So in this configuration, I'm going to define what is a body, how it looked like, and also the, for example, the links and for example, the fonts. So let's start, for example, configure the body. So in the body, I want to use a font family. Let's say Open Sans. Also, for example, always the default browser is sending me the links with underlying. I want to remove this underlined by default. So I will say text decoration of the a or the link itself. It will be, for example, none. Normally it comes underlined, but we need to do it as a non. So here I put the basic configuration which I need for my application or for my whole applications. Okay, maybe also, I will need to define the fonts which I am going to use in the application as you know, font-face. So for example, I will create another file. Call it fonts. You have freedom. You can put all of these files in one file. For example, you can put the colors and fonts, everything in the configuration file. But I am defining or dividing that based on files or based on functionality which I need. So in Google, there are some fonts which can be used directly. We can call them font faces. So if you want to use one of them, you just need to go to the browser and search for Google Fonts and Google Fonts. In the first link, you will find a lot of fonts which you want to use. For example, we need to use open sounds, as we saw previously. So based on our design, the designer told me that I must use this font. So I am going to have it. So first of all, you can select the style which you want to use. What example I am going to use this one. And I want to have the styling as well. So I need to take the CSS, which is needed for that. So you have here two options. Link in general, you can link it exactly in your HTML file or import. For me, I'm going to use this import. So we can use this one and go to the application and paste it here. So here we will have import this file or this CSS file. Some people are doing it in that way. So for example, they copy this file or this link, they go to the browser. And then for example, they based it in the URL. And then they will get this list. Some people are using or copying this list and using it in the application. Because in Google fonts, you can define what type of the font you need. For example, you can have light 300, italic regular. You can combine them all in one styling. So in this way, you can import all of them in one link. So for me, I prefer to use this way. So first of all, I am going to remove those, for example, this italic forms. So we can have like three weights. So in that way, we can have this import, we can take it, copy it without this styling tags because the styling tags will be used in the HTML. But here we are using the import inside a CSS file. So we can copy this Import, go back to our application, and then paste it here. So here you will see that we have imported all of this font to our application. Okay, so now let's try to test this. That's the structure. For example, I want to see that I am really using that font in my application. First of all, you see here that we have an error, and this error says that we are using a wrong style sheet because if you remember, we had the file here is called style SESS. So what we need to do, we need to go to the styles of that application, for example. And we are running the engine shop as you remember. So I go here to the styles file of that application in the application level. So here I go. And then Styles and rename this to their file, which I was creating in the styles or public styles. So if you see here that we have admin and NG shop, so then I will call ND shop. Okay, so now we don't have any error. Let's try to see how we can use this file. Because if I go now to the front end, I will not see anything. I will not see that font which I wanted to use because we don't import the files which are needed to the application. So the first step we need to do, we have to go to that specific style of that application. For example, this one end you shop. And we need to import those files, that color, configuration and font. So let's start first with, for example, the colors. I will go here bays in colors. I will import this file. And also I can import another file, which is the configuration. And then I can import also the fonts. So as you see here, I imported all of these files and then this file are used here. So when I save, the application is recompiled, I would trick the browser. I will still see maybe it's not used anymore, this font. Why? Because if you open the inspect tool, you can use inspect element using Chrome or Safari. It doesn't matter. We are going to use Chrome in this course, but for this level, I'm going to show you is Safari. So here we have this, we inspected on this element. And if we go, we see that we are not using this font because there is something overriding two sans serif. So how this happens, this happened because if we go to the application, application level, we see that we have the styles, okay, everything is fine, but We have here application component has some specific styles which comes with the index by default. So let's delete totally this CSS file. We don't need it. So I'm going first to the component and remove that. This file is doesn't have any styling because we are going to use the public styling. And then I use or delete this file and then save the component. And we go back to the application. Again. We will see all really that we have using the font or the right font and we have open sets. I would like to mention something here that the order of this import is very important. For example, if you put the color after the configuration, then the configuration file will not see what is inside the colors. So the order of this file is very important. So I would say maybe I need to import first the fonts. It's working because it's, for example, a styling, styling that the body is using this font. So when it's loaded, then it will be used. But it's very important to keep the order like that. So we have, for example, color, fonts and configuration. And in that way, we can structure that file. Let's copy the same thing to be in the admin file. So we have application also called admin, which will be the admin panel. So in the same way, we are going to use that for the styling. So in the styles, I will not use the shop styling file, but I will use the base one. So I will say here that go back one level and another level and then Styles and then use the admin CSS. So here this admin application will use the admin CSS, which is located in the public file styles, and the same thing. Let's delete also the component from here. So we can delete the styling of that component, which is app component or that old component. Okay, going back to our findings structure, you can also include another things here. For example, you can include something I like also to keep them in separate file which is called mixins. And if you know SPSS or SAS, you are using mixins. Mixins are functions which are used to be everywhere in the application. So you don't have to create a bunch of code. You can use this bunch of styles inside with one line. I want to create a Mixin. Let's call it, for example, reset list. And this reset list. For example, it will have a margin 0. And for example, budding is 0, and also for example, list-style will be none. So I am talking about the UL component that u l here. So how I can use it, Let's use it, for example, use this mixin inside the configuration file. So first of all, I'm going to import it and say here bays and then make sense. So here I have imported it already and I am going to use it in the configuration. But be careful here we will have problem, that configuration will not see mixins. You'll need first to put this configuration under this mixins. So in this way, the configuration, we'll see those mixes. So I will go here to configuration and then I will say UL, include reset list. And when I save, I will see that I am still getting error because I think because I didn't save this file. So when I save it and save this, again, the configuration, everything could go. All right, so let's see how if I flip this order. So when I flip them, I put the configuration before the mixins and I save this file. You'll see that I got the error. It says because I cannot see, for example, there is at least mixin. So in this way, it's very important to know that the order is very important for your coat. So we have to put it back, save and we will see that the application is running successfully. Okay, continuing the structure of what we need for our public styles. Let's take a look to our applications. For example, let's go to the end you shop. We will see that we have homepage and we have for example, footer header and also some product list. And all of them, they have still their own styles. We need to delete that. We need to put them in the public style so we can see everything there. So everything will be, for example, shared and we can use it everywhere in another issue or in another additional application. So my idea, It's my, my idea. You can create your own structure which you want. Maybe you will not like this structure, but I am giving you the idea. And then you can decide based on the structure of your project. So I will say here I have the styles I would create, for example, apps folder. And inside this app folder, I will create a folder for every application which I have in my workspace. So I will say here shop in general. And then I will create another folder for the admin panel. So I will use these folders to have the styles of specific applications, components, the components which are really related to that application. It's not related to the library or a public configuration. So I recreate here another folder, call it admin. And for example, inside this shop, we had, for example, the header and footer inside the shared, you can follow the same structure here to not be lost. Or you can also, you create your own structure based on your need to not duplicate a code or duplicate some styles. So here I would create a folder, I will call it pages. And another folder I will call it shared. Exactly like how we have in the apps. And inside the shared, I will create a file tour dot SCSS and another file which will be header dot SCSS. And if you need really a styling for those pages, you can create a file, styling file for that page. So in my case, I am going to use a library. I'm going to use, for example, the Bootstrap. Then I will not need to have a structure or styling file for the page because I will use that library to organize the grid and the components which I need. So for example, as you see in this XD file, I'm going to have everything as component. I will have navigation component. I will have, for example, not navigation. We can have a header and a footer. And for example, those will be components only what I need for the this page or the homepage is the grid. And the grid will come from the library, which I am going to use. But anyway, let's create now the file. And if we don't need it in the future, we can delete it. So let's say on page dot SCSS and then products least page dot SCSS. And here I have now two files and or four files. And then those files, I must import them to NDI shop, but those files are not going to be used. So I don't need to import them there. So let's do that. What I would copy this one, or let's call import apps, sharp pages, and then homepage. And another one for the product list. So I will say here that the product list, so we have, we can call this is the base. We can call this as an example pages and we will see another sections as we will see later. And we will have also shared. And those shared will be, for example, the import for the header and the footer. So we have here the shop shared header and another one for the footer. So everything I write inside this files will reflect what? It will reflect the end you shop because I am importing them here. And this file is used in the application level of N D sharp. So in this case, I don't need this dialing for those components. So let's delete them. So first I go here, delete this file. I'm making a clean up here. And also we delete this one. So we delete also the styling and header, the same footer, the same. So we don't need to keep anything related to styles in those components. Are ideally it, this one, I did it, the header component style, and also this one. So now everything is working smoothly. Okay, back to our file structure, as we see here, that we have created the structure based on our need. So we have now a specific application files and also the base. What about the libraries? We can also following the same way. For example, I want to create something for the UI. I want to create a style for the banner. So let's go there. Create a new folder. We can call it lips. And inside this libs or libraries, we can create exactly the same structure here. So we can have a UI component. And inside this UI folder, we can create a banner dot SCSS, exactly like the component which I am using inside the UI. I can create as well as slider. So inside this UI, I'm going to create slider dot SCSS. Also, I can include another libraries, for example, products. And inside this products, it should be inside libraries. I'm going to have, for example, we can call another component which we didn't create yet. It's just for example, is product item SCSS. It's exactly the item will be showing a product. So if I am going to use these components or this tile is in the front end as well, I need to import them. So I go here, I say lips, here is Section 4 ellipse. I am also going to import those leaps component. So we have here U, i, we have a banner, we have slider here. I must put a semicolon here also. And then we have these files here. But imagine if we are importing all the libraries styles here, we will have here a very huge file. So what I prefer that I create a file in every library. For example, I call this UI dot SCSS, which will include the styles for both. So I can copy this one. I can say not you, but exactly directly on the folder. So we have here the slider CSS and banner CSS. And in my ND shop, instead of using the component itself, I can use directly the UI library. So I'm going to say here, not the apps, but we say lips UI and use the UI SCSS in this way, if I go by clicking on control to this file, I will see that also these files are imported. In this case I am using the banner and the slider. But if you want to use only the slider, of course you can import it here. You don't have to import everything for you from the UI to reduce the file size of the build CSS because you know that SCSS will be converted to CSS to be suitable for the browser, then this file will not contain, for example, the slider because you didn't use it in the shop. So in this case you can import only the manner. You don't have to import everything. But for me in this case, I want to import everything. So I put UIs, CSS, and this UI UX css is here already. So let's create folders for the other libraries. So we have users who uses will contain, for example, the login component and register component, also orders. And all of them will have their own component, all stylings, as we will see how we are going to build this application. All right, so we saw that energy shop has its own styles on imports, and also the admin has its own imports. So in the application I have here, the admin, I have here the shop itself, the specific components for the specific components for the admin. And here I am importing the styles for them. So in the next lectures, we are going to build all of this structure. We are going to build it slowly. And you will see how I am going to use every file in specific application and how I will decide that in which location this component styling will be. So for example, I want to create a product item component. I put it here. If I want a create, for example, a checkout page, I will put it for example, in the shop specific application page. As I told you, I repeat again, you have totally a big freedom to build your structure in your own way as you like. But here, the structure is very important for me and very user-friendly or developer friendly. Because as an Angular developer, I am going to use SCSS and use these files based on what I need to build different applications using an X. In the next lecture, we are going to see how to use external libraries like Bootstrap, end u-prime, and import the files here. And we will see the big features of using a public style. The importance of putting these files in a public folder on the root of our workspace. 84. PrimeNG Material Installing 3rd Party Libraries and Include Styles: Okay, in this lecture we are going to learn how to include external libraries, such as Bootstrap or prime end D, which we will use in this course in our project. So first, sometimes you need to have some external already style components which you can use inside your project. So I go to another external libraries such as Bootstrap and then install it, and then I build my project based on that. And in this lecture, I want to show you how to include external libraries inside our styling files. So first of all, let's install one library. Let's go, for example, to Bootstrap. Bootstrap is only styling library. It doesn't contain, for example, the angular components like prime end g. So we go, for example, to bootstrap. I'm reminding you, we are not going to use it in this course. So it's just an example. So I would go and select a bootstrap, go to Bootstrap website, and then I go to get started. And here you will see a multiple options for installing the library. The first way for using or including a library is using the direct CDN, which is a URL you can provide inside your project, and then you use that style. For example, the simplest way for that, I can copy this link, which is provided by Bootstrap. And then I go to the project. So I go to one place of my CSS file where I am including the main CSS files as we saw previously. And type import URL. And here we include the URL which you copied. So we paste it here. And then we load the project. Everything is fine. The project is running already. And let's try one of those modules which are included with Bootstrap. For example, I select a button. Let's copy this part. One of the buttons I am running now, the project engine shop. So I go to the end, you shop, for example, homepage and app-based this button here. So we try it, we run it, and I see that we have here the button is styled, so we imported directly online the Bootstrap library to our project. But in this case, you must have an Internet connection. So when you disconnect the Internet, you cannot work offline and then you are not able to see the styles. You are not able to load the styles from the Cloud. There is another way that we can guarantee that we are working offline, which as we see here, that in getting started we have a download. You can download the files themselves and include them in the project, or you can use the npm package management. So when you run this command in our project, so I open a new tab here for running the command, paste it here, and run the npm install Bootstrap. So it will install for me the library locally so I can work offline because as we saw here that we have here the remote link. So how we can include what we installed inside Law Library. So it's very simple. So normally the library comes with a name. So this is the name where the library has a folder in MPM module. So you have a choice. So you can include the library by navigating to MPM modules. So I go here and I go one level up, I go to node modules, search for Bootstrap, and then this, and then the CSS. And here you have the CSS files. Or another way you can do it is very simple that you just have to use this sign. And then you call the library folder which you want. So I say boot strap and then you want to know to which CSS file you want to include. So normally it's written in the documentation of the library. So it telling you that I am going to this folder to have the package and install it or included in my project. But if you don't find it, like how we have here in Bootstrap, you can't navigate by yourself in Node module folder. And then you can navigate to the CSS which you want. I'm showing you this way to have more knowledge about how to play inside node modules. So I go to node modules and then I find the Bootstrap, and then we will see normally every library comes with a destination build. So when you see these holder, then it means that this is a build version. So this what you want to use normally, or you have a SAS Virgin has you see here in Bootstrap. So the Bootstrap has Sass file and also it has the CSS file. And this is CSS file as minified as well. So the path for us is least CSS and then Bootstrap CSS min, or we have another path which is SCSS. And then you navigate to the SCSS file of bootstrap, where it's including all the files which we need here. You can also include some specific files only. You don't have to include everything like you want to use a grid and you don't want to use all other stuff. So you can include what you want inside. So for me, I will include this file bootstrap. So I will go here after this sign bootstrap, I-type SCSS as a folder showed me. And then I put Bootstrap SCSS. It's exactly the same path in old modules. So in Node modules, we have a bootstrap folder, which is this one, and then SCSS. And then I go directly to Bootstrap SCSS to include it. In this way, I included everything of Bootstrap. Let's save and try it out again in our browser. Then we will see that the button is working even if you are disconnected to Internet because the library is already installed on your machine. So back to the browser, you will see the button is here and start. There is another way for including styles inside your project. Normally in Angular. Using Angular JSON. Angular JSON is a file where you can configure your project with a files which can be included by default with the project when you are building or combining the project. So when I go to Angular JSON, I see that every project has some specific configuration. So one of this configuration is a Styles. Styles is an array where do you can include anything you want for your styling the project? So if I want to include the bootstrap, I would use the same string and add input for this array, but the path will be a node modules. In these modules we have Bootstrap and then as we saw previously that we have a css and then bootstrap another SCSS. So here we included the CSS in our project. Remember that you need to restart your project after this change, because this change is a configuration change, you need to restart the project again. So let's remove it from the SCSS file and then restart the project. So to stop the compiler, Control C on the compiler. And then I run it again. It successfully compiled and running back to the project refresh. You see that really moved the library from the SCSS file, but we have it included in Angular JSON file where I can include the styles. What I prefer, which way I prefer the way where we are including the files here. Because in this way when you include especially SCSS file, you can have access to some variables of that library. As you know, in SPSS, you can define a variables. And those variables can help you to adjust this library to fit exactly on your project. For example, if we go to bootstrap again and we go to the grid system. And in the grid system, as you know, we have some predefined variables or values for sizes which can be used for mobile or for computer or for a tablet. But as I told you before, the benefit of including the SAS file is we can use some features of that library, of that grid. We can adjust it. So we have, for example here SAS files or the SAS variables like grid columns or agreed gutter width. So whenever I go here and change this variable based on what I need in my project, then all the Bootstrap will behave based on that change of the variable. The same thing. For example, there are some mixins. I can also use them. We will see that deeply later after we are building the project, how we will use those variables, how we will use those mixins of this library or any library to build our e-shop in the right way. 85. Installing PrimeNG: Okay, As we decided previously, I'm going to show you how to install prime N D library in your project to run and walk with it. First of all, we need to go to their website of prime NGA, which is prime faces.org. And then you click on prime NG and then demo. And here you will be specialized for angular component under Prime NG. So if you go to demo, you will see all the components which we need for our library. We will see all the components later when we are working with the project. But now let's install the library to our project. And in the next lecture, I will show you how to work with this components of this library. So first of all, you need to go to get started. And get started, you will see two things you have to install. First, prime NG and then prime icons. Because m prime NG library and components, there are icons and those icons should be installed separately. So let's do that in our project. First, let's install prime NG and then prime icons. Going back to our code, we open a new terminal for installation. And we type npm install, and then prime end and save flag to save it in depth dependencies enter and we are going to have it installed in our machine. Another library we need to install, it's called prime icons. So let's install it as well. We go to npm install prime icons, and then Save, okay, Now we have everything installed and successfully installed. So previously we did some update on Angular JSON that we added bootstrap library. Let's remove it to not have conflicts with Prime NG library. So you need to be sure that you are not installing multiple libraries to not get conflicts together, especially if they are using sometimes same naming of classes of CSS. So we save the angular JSON and then we restart the project like here, we have it running, then we need to stop it. And then run it again. And after that, I will go to the end you shop and import the library prime N G. I will use the way where I am going to import the files of prime end to my main engine shops, SESS. So here we can create a section called it libraries. And here we have to import. And then we put the sign which we agreed before about. And we put prime N G. But I don't know which file. You have two ways to know which file. You can go to node modules as we saw previously. Or you can go here in the documentation to see what file you have to include. So it says here that you must include those files. So let's include this one which we are contained by icons, which we need, as we saw previously. And the second one is theme. We need to install a theme. The nice thing with Prime energy, it comes with multiple themes. To be able to select the right theme for your project. For example, let's select this one. There is a purple, it will change immediately on this view. So you have a dark theme, you have multiple themes you can use. For this course, I am going to use saga blue. So just like this, you have to copy this part. Or you can copy one of those themes here. So I am going to use saga blue as we agreed. So here I will have another import and sign, and then here I will include the thing. The last thing we have to include is the library itself. So we copy this one. And then we do another import. Again. We put the CSS file of this library. So here we have included everything regarding this library. We save that we see everything compiled successfully. We don't have any problem because we are on the right path. We didn't have any arrow here. In the next lecture, I'm going to show you how to use one of those components in this library. So it's very easy. We don't have to do a lot of work. It's just like exactly how it's implemented here. Prime energy is very well documented, as we will see in the next lecture. 86. Using PrimeNG Components in Our Project: Okay, now as promised, I will show you how to use one of those components of this library. So first of all, we go to this library. Let's browse some components. For example, we have the accordion prime NG comes with very nice documentation for every component and it shows you how to use every component. So first of all, we can go to the documentation of this component. We need to import the accordion module to our application module. So let's copy this line and we go to our project. And we will see that we have two applications. And every application has application module. Of course maybe we will have multiple modules as we will see later, but now we have only one application module. So let's work here. So I'm going to import this accordion module first. And we go to the imports here to include it inside our NG module of application module. And then let's see that documentation. What is telling us one of these examples is showing us that we have to copy this HTML code. So this HTML will be pasted on the page where we are going to use this component. For example, let's go to the homepage. So if we go here in our application, we have pages. One of these pages is homepage. We can remove this button which we created previously. And then we paste this code here. Okay, we run the project, it saved. We go again. And then we have two local host, 4200, the port. And we will see that we have the accordion, but we still miss something. There is a problem because we are not using the animations. If we go to get started again in this library, you, we need to install the animations. All we need to import animation module. So we have to import this module, which is already installed with Angular. We go again to our code module. And then we put it normally after their browser module. And we imported here. So then we have imported the animation because this library is using this module. So if we go back to the browser, go back to our project, we will see that the accordion is working mostly the same way you do for all components. It's very well-documented. You can do whatever you want. We will use most of those components which are in this library when we are going to build our project. 87. Overrride PrimeNG fonts: I would like additionally to mention that after we are installing the nk prime components, we notice that it's overriding the fonts. The font, which is we, for example, we were planning to use Open Sans, which we have installed previously, but I would like, for example, to install or use that in the prime engine. The problem is that For prime NG there is some specific case. It's not the only saying that we want body and then we use Open Sans. But you have also to say after importing, of course prime energy, you have to say B component, like this class, P dash component. And then you can continue working. So in this case, p component is the entry point for the fonts of prime energy. So body is not enough, but also p components. In this case, you will let your application and the components of prime NG use the font which you specified here. So for that, the application level, when I go here, for example, to NG shop, I put the configuration not here at the beginning, but after using the prime NG and importing all of the libraries of prime NG. So after we got everything from Prime energy, I go and update the configuration of the peak component and the body to use that font. Just to mention this point for you in case that you don't see your font is applicable in your applications. 88. Installing The Grid System: Okay, I know that you are very motivated to start coding and to start the real-world project. But the last thing, please forgive me that I want to show you how to install a grid. In every application, we need a grid system. A grid system which is showing the structure of the application. You want to know what I mean. If you go to a library, you will see something called a prime flex. And this prime flex is a system which is showing you the grid to lay out your components based on that grid. And it has very beautiful functionality and it's very dynamic. So you can use it and fit your application on every platform, like a mobile or tablet or a desktop. If you don't know about the grid system, we will see that later in detail, how to build our application based on the grid system. But first, if we go to this grid system, it has its own setup. So first of all, we need to go through the setup. We need again to install one library, Wine Library. It's called prime flex. Exactly something like prime icons or prime NG itself. So first of all, we need to go to our project and install prime flex. So we open a new terminal. And then we go here, we say npm install prime flex, and then say, OK, now this prime flex is installed. Let's see how we can use it. Let's pick up an example from the library itself. So we see here that prime flux has multiple grid system. One of them is the grid system and flexbox. So we are going to use in this course that grid system. That grid system is very dynamic, which will fit our application on mobile tablets or desktops. So as you see here, there are multiple examples. Let's pick up one of those examples. So we have here first this be grid. But before we see that we have here a class. But this class come from where we need to use it. So first of all, we need to include this file in our library, exactly the same way how we did previously with other libraries. So we copy this path. We go to the project. Again in energy shop dot SCSS. We import this library using this sign and we have it now as CSS. So when we save, we see that the project is running successfully. Now we are able to pick up an example. Going back to the library grid system that's pick up one of those examples. Like for example, we can say this one. Go back to our code, we go to the homepage and then we paste this code here. We go to the browser. To our project, we will see that this grid system is working. Because if I disable this library, Let's comment out this library. Go back to our project. We will see that they are aligned under each other because default that div tag the whole space. So with a grid system which we installed, we will have the system which is fit for our application and we need it for mobile, desktop and tablet. As I told you later, we will use all functionality of this grid system. Now we are ready. We have built the structure of the styles. We have structure of the files and the folders. Now we are ready to start coding and build the application. I'm going first to start with the admin panel. The admin panel where we are adding products, users, orders, and also categories and do all the crude operations on them. 89. Introduction: Admin Panel Overview: Welcome to a new section. Here we are going to build the admin panel application. The admin panel where we are going to control orders. We are going to control products, categories, and all the operations on them, like add, edit, and delete. So as an overview, I am going to have a login screen. I'm going to login to my using my account here. So I will use, for example, this account. I am admin, of course, the normal users cannot also look in. So we can only as admins looking, we will have a dashboard as you see here. How many orders I have, how many products, how many users in my shop, and how much total sales I made for my shop. So as well, we will have an overview on the products. So you can as well aided products. You can delete them. You will see how you can as well make like conformation. They are logs and you can edit and products. For example, I will update this one. You can click on update and you would get all of those notifications. And as well, we can work with categories. We will see how we would use as well the color picker. We would add like basic forms as you see here. And we will use the icons and of course, the orders where we will have the status of the orders which it's bending or processed. And the user or the admin can change the state of the shipping or the order. So he can have like shipped or delivered. And based on that, the data will get updated here as well. We are going to have like some control on the users or their customers. We will see who is admin, who is not. We will have like list of countries, how we can know from which country he is. And we are going to add the information, use a password, and then we are sending that data to the back-end in the right way for the functionality of admin panel without any missing thing, we will see also how we can upload images and we have to use reach editors. We will see all of the information which we need really to build a real-world applications and grab data from the database as well. You will use the logout button so the user can log out and go back again to the login page. We will see how to protect our path is so the user can not go to any page until he get authorized. We will see how we will add a token, how we will grab that token to our local storage and use it. How we can get it from the database or from the backend and use it in the front end to know if the user is admin or not. All of this will be in the next sections. And we are going to build that step-by-step using prime NG and also another technologies which we need for that. 90. Building the Shell: Okay, Now we are going to build the shell. What I mean by the shell, as you see in this photo, that we have a sidebar and we have a content on the right. So this white area will be full of the content which I am going to navigate to. So when I click on products, I will see table of products, or for example, I will see table of categories. I will see Editor for the product. So in this case, I need the shell. I am calling it a shell because it contained like a fixed side where it's sidebar is fixed. I don't need to update the sidebar every time I am navigating to a new page, but I only need to update the content. So as you see here, we need two components. One component is the shell itself, like the page where I will locate the dashboard and items and also the sidebar. The sidebar, it's also its own component, will contain the logo and its own links. So let's do that in the code and we will see what we will need for that. Okay, now, as a first thing we have to do, we have to configure the right application. As you remember, we have created two applications. So first one is the admin obligation and the second one is ND shop. So for that, we are going to work on the admin application because we are building now the admin panel. So let's configure it. Well, so first of all, we need to import the styles, which is in the public styles, and we did that previously. Second, I want to configure Eastland. Eastland as we remember, it's fixing our code when we are doing some mistakes, odd when we are importing some unnecessary libraries, etc. So for that, we need first to fix the prefix for the directives and the components in Angular. As you remember, we created a component that this component has a selector and the selected should follow some rule, like a prefix. So we need to have a prefix admin for every component. Of course, you don't have to follow this rule. You can name your components as you want. But for organizational stuff, it's better to have it like that. So I would go to ES lint. And here in this part, the attribute of this electrode directive will be prefixed as admin and also the component would be prefixed as admin. So in this case, every component must be prefixed with admin. Also, the App component must be prefixed with admin. But as you remember, in Angular, we have N3 component, which is app component, which is called an index HTML file of the project. So I am in the project level up. And here I have index. And this index we are calling the basic HTML which is needed for the project. So for that, we have here as well admin. And here as well, admin for a closing tag. Now we are ready and our application following the rules of ES lint. Of course you can add more rules based on your needs. I'm not going to have them all. I just want to show you that there is some file called Eastland that you are following some rules you need to do for your code. So as we talked previously, we need to create a shell. Shell will contain a sidebar and the content. So for that, we need to generate two components. One is shell and the other is a sidebar. We can do that through an x console. We click on Generate and we search for a component. We click on that and we give it a name, for example, shell. And the project is admin. We talked previously about all other options. So I will give this to a CSS and then I will click on Run. But first, I need to have a structure for the files and the components. So it would be better if we are putting it inside a folder. For example, we have here something for the pages and we can create another folder. We call it shared because the shell is shared among all the application. So we can check the path. We see that, okay, up shared shell and then the component is created. Let's run it. And we will have the file or the component is created here. Nice. So let's do some clean up. Like for example, we need to do the admin prefix and also we need to remove the CSS because we will have the CSS in the public status. So let's remove this file. And the goal for that file, we will do that for every component we are creating. Another component which I need to have is the sidebar itself. So we go again to generate component. We select this one and we say shared and then sidebar and in the project admin and all the same. So we run this command. We will have in our file structure, again a sidebar. We clean it up and we make this prefix as a sidebar admin and really move the SCSS file. We save and we will see that the components are already imported in the module. Let's go back to our compiler. We are running already that application and D-sharp, we need to run the Admin application so we can go again and x serve. But we say the application name is admin. So we are running it now to check if everything is working fine. We are getting some arrows here because we didn't update the file of styles of that Admin application. So if you remember, we are working only on ND shop, not on the admin. So let's copy the same things which we had in G sharp and paste them in the admin, except the part which is really, really specific for the application. So we have here Apps shop. No, we don't need that in the admin. We need only something specific for the application admin. So we can remove this part and run the project again and check if everything is working fine. We go back to style CSS, where we call the admin. In the style application level, we press Save again, and we will see that everything compiled successfully. Now as a component structure, we are ready for going to the next step where we are going to call those components like the shell and the sidebar to show them in the application. For that, we need to configure routes. And this what we will see in the next lecture. 91. Creating The Routes: Okay, We talked previously about the routes. Now we are going to import or build some routes for the admin panel. First of all, we need to have to fill this array. So we need, as we talked previously, to define a path is, and those passes will refer to the components. But how we will do it in the way, how we build the application. So as required, I created the route's array. This route's array, which will have components or objects, and every object will have the path and the component which this pass is referring to. So for example, the default one will refer to the shell component. When we save that and we try our application, we will see that we still have admin panel because we have the app component, still have this title. So we need to say to this app component, to the fair and user out how we can do that. We just say router outlet and we close as a tag router outlet. So when we run this, we will see that it's referring exactly to the shell because the default path is referring to the shell component. Okay, as we talked previously, we need to divide the shell to two parts, one side bar and one content. Do that. So I will go to the shell component, remove this part, I will create a div, call it admin wrapper. It's up to you. You can build the HTML code based how you like. And inside that rubber, I want to call the admin sidebar, which we created previously. And near the sidebar, we need to create the content. So I say live admin, for example, content. And what will be inside here will be inside it, the content. So how we can refer that? First of all, let's see if everything is still working. We go again to the browser, okay, sidebar works. We need here to feel the content. For example, we need the dashboard, as we saw previously, that the sidebar way contains many links like products, dashboard, and orders. So the content will be always different. So in this case, we need to create dynamic content. We can do that also through their routes. So I will say that this path has the shear component and these paths have a children and the children will be also routes. So the children will be array as well and it will contain objects and every object, we'll have a path. We can call it, for example, dashboard and also component. So we need to refer to dashboard component, which we created also previously. So when I save and then I go to the browser, I still see everything empty. When I navigate directly to dashboard, we will see that nothing happened because the dashboard, okay, we are on the right path, but we cannot see anything in the content. So how we can fix that? We are going to go to the shell component and say that this child or this component has also router outlet. So when you want to display the children of this component or their children paths of this component, you need to place also a router outlet. We save that back to the browser. We will see that we have sidebar works and dashboard works. And when you create another path here, for example, we call it for products. Then you will refer to products component, and it will be called and rendered inside the shell. So in this case, I am not updating every time the sidebar, I am updating only this part. And this how we handle the path is in our application and we will see in the future the benefit of that, that we can guard all of these routes, like protect all of these past so nobody can access to its children as well. In the next lecture, we are going to style admin wrapper and admin content to have the target design which I showed you previously. 92. Admin Panel Navigation Sidebar: Okay, Let's start out with the first thing. First, I want to create this sidebar. As you see here, that we have the logo and we have some navigation buttons. Inside this navigation buttons, we have icons. So let's create that. Okay, as we saw previously, that we create an admin wrapper. Then we have the sidebar. We go to the sidebar template. We are going to make the div. Div is sidebar or admin sidebar. And then I want to define inside the sidebar first, as we see previously, that we have a logo on the top. And also I want to define the links, the links which comes under the logo. So here I need to also to import an image. The image is already, I have it in my assets folder. And if you go to the Assets folder, I pick it up from the design and then I put it in this location of the folder. So the assets is the application level. So let's go back and create the links. That links as normal, we need to create unsorted list. And this unsorted list will have list inside a list item and every list item will have a link. And inside this link I define my strings which I needed. For example, I need a dashboard. I need as well, for example, the products and the orders, et cetera. As you remember, we had an icon before the text. So after the text we have an icon. Let's go to the prime end the library, because we install this library already, we copy these two lines of code or this one line of code for importing the icon. So first of all, I go to the dashboard again or to my sidebar, and I pasted here. So for all other links, we can create another list. And then we can rename those items like products. And we renamed, for example, categories. And also we need orders. And also at the end, I need users. And of course we need one link which is called log out, where the user will log out from the admin panel. But first let's put the right icons because we have here pi check, so you can find the icons I also in the icon library. So we have here all the icons. So you just pick up the name and paste it. So for example, for dashboard, I need home, for products, I need a briefcase, four categories. I need a list and for orders, I need, for example, shopping cart. And for example, for the users, I need users icon. So every icon need the name which can pick up from the library. And for the logout, I have something called sign out. Let's save and go to the application and see if everything is working fine. Okay, We have everything is fine, but without any style. So let's style the sidebar in our public styles folder. So first of all, I will go to the public styles. And here I have already defined the admin folder. So inside this admin folder, we need to have something called shell, shell dot SCSS, and then we imported in the admin. So here I have a shared And I say import from, for example, there are apps and then Admin, and then Shell. So I need to import that one. So after here we need to write our stylings here. So first of all, I need to have, for example, their wrapper, the wrapper and the main, so that our upper will have all sorts sidebar inside it. So let's have their upper first. So inside the shell I create admin class. And this admin class will have a rapper. And inside this wrapper, for example, I have a height 100%. And for example, I have a batting 0 just to initialize it. And then a margin will have a 0. I'm just initializing the whole dropper. And then we need to create the sidebar class and the sidebar class, as we saw previously, that it is inside and it's prefixed with admin. So that's why I use this ampersand minus sidebar. The position of the sidebar will be fixed because I don't want to scroll the sidebar as I will show you later. And the width will be 175. This how I got it from the design and the background color. For example, I have a black and also we have a height. We can give it 100%, so it can be feet on all the page. So what about the main content? The main content which will come near the sidebar. So here I need to have also ampersand main. And inside this main I will have a width. What is the width will be a calculation of 100% minus 175 pixel because the sidebar has 175 pixel. So here I have also a margin. I need to push this main content mostly to the right. So I will say margin left, it will be 175 pixels. So if we go here, we will see that we have the sidebar and also we have the content here. And as you remember, we had the dashboard route. So the dashboard route, we see that it's really are and in their content. And we can be sure of that my opening the have tools and then we check the admin main or the admin wrapper itself to see that everything is fine. So let's do more styling. First of all, I need to have the logo in more nice way. So I will have a logo, and this logo will have a padding like 20 pixel, and then it will have a width about 100%. So it can fit exactly on the sidebar, inside the main content of the sidebar. At inside the logo, we notice that we have an image and inside this image, I will give it max-width 100% to not go out of their content. So everything is fine in the sidebar and the image. Let's tie now they're links, that links also they have their own class which is called links. And then I need to style every element of the links. So I will have the class links at a side, this class I have URL, and the URL will be initialized with margin 0 and padding 0, because sometimes it comes with some values, so we need to initialize them. And their least, we will have a display block to display it like a div. And the least style will be non tutti, more of these dots near the list item, and also the width would be 100% of their contact. And as you remember, inside this list item, we have a link and this link we are going now to style it. So first of all, we give a class, and this class has a color, and this color can be a white. And we can give these links batting. So it can be more spaces between these links. But first about the color, I want to show you a trick. As you remember, I talked about some, some defined variables of colors which are defined in their library of prime NG. And those variables, you can't see them in the dev tools. So as you see in this list, there are already defined CS as variables for their colors. So you can pick up the color which you like and mostly are usable because you can use them anywhere in your style, which comes with that theme. So to use that color, you need to say var and you put the name of the variable, and then it will have the color. And if we check it, we see that it's really having this color. Okay, so now everything is ready. We need to have a display block for the a link so they can have effective width and also effective paddings. And as we see here, that everything is working fine. But first we need to give some hover color, like when I put on the mouse on one link, I will have a color. So first of all, I have, for example, a background. Let's pick up some color from our list here. So I will plug the blue 500 or 600 and 700 anytime anything. So you can put, for example, var and this via blue 700. And then what angle? But we've got a browser. I navigate and IC that the holder is working fine. So let's style those icons more so we can give like more spaces. So if you remember that we have I element inside the link, as you see here. So we have the I, we need to style it. And this I will have, for example, a margin, margin, right? Like I want to push it away from the text. I give it the eighth pixel. And also if you want, you can give like some margin top. We can give it like a 0 to initialize it if it has some margin before. And also we can give a float left, so it can be pushed to the left mostly. So we save and we see that everything is working fine. Let's now give some special styling quarter their logo Alt button. So I will say here class that it has some specific class which is called logout. And this class I will define it here inside the a. And the logout button will have a color, which is, for example, we can give it a lighter color, like a blue. We can say 500. And in this case, we will see that it has really different color. As you see here, there are some whitespaces like the sidebar is not directly fitting on the page borders. This because the HTML component or HTML element is not initialized world. For initializing the elements, I would advise to use a library called normalize dot css. And this library will initialize your webpage or HTML code from beginning, and then you can work with it in the right way. So it's doing some initializations for the application or the HTML before you start to code. So that's why I am going to put it on the top of my CSS file. So here I will call it, and it would be the same way how we are calling every MPM library. Because if you go inside this library, when you press control and to this library that you will see that we have initializations of everything, like HTML sidebar progress everything. So here we have the initialization and we will see that it's really working fine. But we still have this space on the top. This because I want to initialize also the sidebar to be on the top. As you remember, I put this dial on fixed. So when I put it on fixed, I need to make the top to be 0. So we go back to our code and we say top 0. So that's why I don't want to have a scrolling in the content because it will have a fixed. So when I scroll the content, the sidebar will stay fixed on the right and it will not be scrolled. I want also to give some color instead of black to the sidebar to be more nice and fit with the design. So as you see here, that everything is working fine. So now I need to navigate among these icons or this links. So when I click on them, I navigate to the page. So if you remember in Angular we have something called router link and you can add it to the HTML element, like a link or a. And then you can navigate to a specific place. So I am going to add every link based on the route which is defined in the module as we saw in the previous lecture. So I will have here, for example, a dashboard and products and other things like the categories. And as you remember, we have everything defined in the module. For now we have only the dashboard, but I am going to add for the rest. So I will skip this video to do it fast. Now we have everything inside that alters, but just be careful. I moved it from the a or from the eye to the a because if you, if you put it inside the eye, then the navigation will work only when you click on the icon. Let's try that. And we will see that we are navigating, right? But when I click on products, I get error. This is because the product navigation is doesn't exist in the app module. So we need to add there out here, as we will see later. 93. Disable Backend Authentication For API's For Frontend Purpose: Okay, back to the backend. As you remember, that we have created authentication for our APIs. And those APIs are protected now. So we cannot do anything without logging in for creating the control panel application. I want to disable this authentication because the authentication will come after we prepare everything like the goodies, products, alders, and also the users. So when the authentication subject will come for the front end, then we can enable them again. So to disable the authentication, we go to JWT, JS file in our backend. Then I'm going to comment out all of these unless, and then in unless I am going to allow everything. So I will add one line here, I will call it URL, and then it will accept a regex. And this rejects will be exactly the same as here, but except this prefix. So in this way, I am going to allow all URLs to be called to the back end without any authentication or authorization. This is temporarily. So just comment out this part and add this part because we are going to delete it after we activate really the back-end. But for now, I want to use those APIs without authentication. And in a later video, after we finished in the backend totally and the front end, then I will tell you how to activate them and we test our applications with authentication. 94. Categories Service Get Data from Backend: Okay, now let's fill our table with the real data, data, which comes from the back-end. For that, we need to create a service which is called category service. And as we see in this graph, we have the category service located in products library. So in this way, we need to create it there and link it to the admin panel up. So let's do that practically and we'll see how we can grab that to the table. So we have our table ready and we need, for example, to fill this array from data not hard-coded, but from the back-end. So let's start doing that. First of all, as we said previously, that we have the service located in the products library. So we are not going to have the service in the application level because the service is shared also with the other application. So we need to put it somewhere where it can be shared for all applications here. So when we go to the products library, which is ellipse folder, so let's close everything like applications. We have ellipse and inside the loops, we are going to have In products, our surface. So we can create service using an ECS console. So we can use go there and generate and search for service. And here we have the first option. And we just need to put the name of the service. So I want to have it in a folder, services and then categories. This, we still have the name and always observe what is going on here with a dry run because it's showing you where the file is getting generated. Project will be products, which is product library. And I want to skip that tests. So when do you generate and click Run? See that this library is generated. You can't control and click on this link. You will see this that we jumped directly to this service. So here we have contiguity service. We are going to grab data here, okay, as you remember in a postman that we have from the backend service or localhost 3000 API Version 1 categories. So when I send a request, I get the data from the backend. So I want to see those data in the front end inside our table, which we see here. So first of all, let's have the HTTP request because we can request the data through HTTP protocol. So first of all, we need to import HTTP client, which is located already in Angular library. So first I need to call Import. And then HTTP client from will be at angular and then slash command, slash HTTP. So from this library, I can grab all HTTP clients, so I can make HTTP calls. So how we can use this library or this service, because this is also service. So here I go to the constructor of the service of category service. And I say private, I define a variable which is the type of it is HTTP client. And in this way, I can create an HTTP, GET, delete, post PUT requests. So let's do now our first goal. So we have a method we can call it Get categories. And this method inside will return for me data which comes from this HTTP service. So I will say this dot http dot get, I want to get some data. And this data will come through the URL, which I assigned here. So I will copy this URL and then go back to my code. And I will say, give me this data from this URL. So after that, we will have all of this data. But in TypeScript, I want you to have the typing. So I want to specify types for every type of data I get. So for that, we need to create types. First of all, what this returning for me, it's returning for me at least of categories. And this category can be a model. So this model can be created here. And I say that I want category array. So let's create a file here. You can use also in ECS console or you can use as well the normal like manual. So I create a folder here, I call it models, because in the future, we will locate also the products model. So first we need to have category model, exactly like how we did in the back-end. So contiguity model will be also type Ts and we say export. We are creating a type. You have option, you can create it as interface or you can create it as a class. So for me I am going to create it as a class. And this class called category. And this category will have ID. Exactly the same data which we had before. And this ID has a type string. And also we have a name which has a type also string. I'm putting this question mark to make them optional. So whenever I create a category or for example, some category, then it will not tell me or you are missing the ID. So if I'm missing the iodine or groping, I just want to have my front end stable. So here we are not creating object, we are creating variables, name and icon, as we saw front-end. So here we have now the model. And I want this getCategories to return for me array of categories. So I will say here that I can return, or this method we've returned for me array of category. But we have at a problem here because GET request or getMethod from HTTP service is not returning the data exactly how we want. It's returning them under something called observable. And this observable is something like you can imagine with me that this service is waiting for the back-end to response and then It's observing the data until they come and they say, Okay, now I have the data, you can grab them. This subject is for our x js, I will go deeper when we are going to use NG RX, you will understand more the observable for now. And the front end is waiting for the data and the waiting coming through observables. So it will not return for me category array, it will return for me observable. And inside this observable is categories array. So first of all, we need to have here 0 servable. And when you don't know how to import it, just control and space on Windows or control dot on Mac. So it will tell you import Observable automatically. So you see it here, and we see that it's important here. So, and then I want to specify a type. So I say that the type of that which comes inside this observable is category. And we need as well to import this category which we created previously from the category model. But also in that way, we need to say, to get that it will return category array. It cannot be like this. So we need to say that GET, be careful that we are going to return a data which are category array. So we can tell also to the getMethod. So then we will not have this error because here it's better to specify the data type which is coming from the gut. So this GET request will know that it will return category array. And I have the link at the end and everything is fine now. So we save. And then we are going to use this service in our aggregation. So we will see how we will import this category service and use it inside the application of categories or admin. And here we will see how we would use it in these categories list to replace this hard coded data with a back-end data. 95. Use Categories Service in Categories List Component: Okay, so for now we are going to use the categories or getCategories method in category service inside categories list. So as I told you before that we have imported a Service HTTP client the same way we are going to do in categories list component. So I want to import the service in the constructor. So I define a variable. We can define an instance of that service. So I say private category's service. And inside this categories or the type of this category service will be categories service. But from where I will grab this category service from the library of products. So if I go here and ISA, as we saw previously, import the good or service from. And then I will say at Blue Bits and the name of the company and the products, I will notice that it doesn't have any type. I still have the error module. Product has not exported member, so we need to export it somehow. So going back to the library, again, we will see that we have here index.js. So I need to export from services which are located inside the library. So I will go here service and then I will say category service. And also we need to export the model which we created. So because we are going to use it there. So I say also live and then models and then category. So now everything is exported. We will see that we don't have this error anymore. So here I will see that the category service, I can use it now. So I don't need anymore this hard-coded data because we are going to fill this array from the back-end. But we can say that these categories has a type category which comes from these products library as well. We imported it. So, and here it will be array, and then it will be empty array at the beginning. And after this component got initialized, we are going to feel this array. So how we can do that? I say this dot getting good service, use the getCategories method. And then if you remember that we have an observable and I told you that the front end is waiting for any action comes from this observable, so of any movement of any change of data. So first, I need to say that I want to subscribe myself and observe these data. So when they are some change, then catch it and let's use data. So I want to use or subscribe to this observable which is returned from getCategories. Because you remember it's returning for me observable which type category. So here we have at the subscribe and then we specify in the callback and in their callback we will get the response of the data. So for me, I will call them cats, for example, categories. And then callback will be a method. And in this method I say this dot categories, the variable which I defined here will be cats. And then I save. We see here that in the compiler we don't have any issue. But here I think we have issue. Let's open the console and check it. We see that we have an error detected circular dependency and the null injector arrow. This comes because the application module didn't import the HTTP module. So every time I want to use a library, as we saw previously, that we need to import that module. We used in category service, the HTTP client. So we need also to attach the module. You have option to use that module inside product module, or you use it in the application module itself. I prefer to use it in the application module because we are going to import multiple library. Then if we important in every library, then it will be duplicated. We will have like HDTP module imported many times. So to do that, we go to the app module. Then here we say in the modules imports, we say that give me HTTP client module. And this will be imported automatically because you are using the plugin and we have it here. I like also to organize the code a little bit. So I have the imports, the basic imports here, and then the components, and then the UX components or modules lyse, everything is working fine. I go again protected categories and I will see the heads mydata games successfully. Sometimes, maybe you'll get error than there is no provider. Four categories service. So it's better also in the application module, say that I want to provide this service to be used in this application. So because we are using this service inside the component which is located inside application. So I have to import it as well. So we can import this service. We can say directly that providers provide for me categories service. And this category service would be provided here. And we save and we assure that everything is going to be working fine. So as you see here, we have the data which comes from the backend, exactly how we have it in the Postman. As a quick recap, as you remember, we imported the service, we imported the model, and then we used these categories. We remove the hard-coded, and then we use them in this table. And this table is rendering the data based on what it comes from the backend. And as you see here, we have in the data or in the HTTP network requests, we have our request, which comes with the categories which are located here. We see exactly the same data which comes from the backend. 96. Add Categories From Use PrimeNG Forms: Okay, now we have our table ready or data coming from the back end. Let's add categories. As you remember, we have disabled previously the authentication for the back-end. So now we can add categories without having been authenticated. We will activate that again when we will have the login and the users. For now, I'm going to add a new category, how we are going to do that. So normally the user behavior will go to a new and then I'm going to add another component. And I will see another component here to add the name of category and the icon. And then I press Save. I show notification to the user that the category gut successfully added. And we need to go back again to table and see our category added to the database and do this table. So I said we are going to a new page when I click on New, so I need a new component. So let's generate this component. I need to generate a new component which will be in the admin application under categories. So first we go to the NX generate component, and then this component will be under Getty and the name of the component will be category's form. And then the project will be admin. And again, we do the other stuff which we did previously, styling and skip tests. And then we are being sure that everything is fine so it's added to this path. Okay, perfect. We click Run and then we see that the categories form got created. So here the component is ready, we just need to add also the navigation to 84 categories least you remember we created the router link and this router link, I will give it, for example, form. And then in the module, we need to add a new path. And this path will have the same structure and we give it antiquities slash form. And here we are going to call the categories form component we save. Let's go back here. We click on you. We see that we are navigating to the form module or form component. So now we are going to have the structure here. We are going to have the form here. So I would like to have the same as its structure like we have this card and also title subtitle, and then the content with controls comes here. So let's copy the same what we did in the categories list. So we copy everything and we paste it here. We remove that table which we had already, so we don't need it anymore in this component and then we are ready for that. So here we don't need anymore and new, we need also to make it as AD. So for example, create. So we save, we go to New, we see that we have a create. So let's change the text here. For example, we can say Add Category. And here also, we can say here. So we have now the title and the subtitle have been created. And also we need, for example, user is used to have the controls here. For example, create and a council. So let's create another button near it. And also we can change this to see Khan dairy and also these two primary. And here we have create and this we call it not create, but cancel. And after that we have everything created. But as we see here that we have like the art sticking on each other, these buttons, this because that we need to provide some margin, right? But then I think in prime NG, you don't need to have to create a class Michelle clause and go to the styling and then add this margin and is not prime NG providing you inside the grid something like ready classes, which are called spacings. And those spacing, as you see here in this example, you can space between the component between leaves, between columns. So you can use it in a way you want. So how we can use that? He said here that we need to have a B first b minus and the property like margin, for example, or padding. And then you can say position top, right, left for example. And then the value, and the value can be from 0 to six, and it depends on the space. So we can use, for example, for this button. We can say that for me, this button, B minus margin, right will be four, for example. So if I go and I will see that spaces here. So let's make it smaller. We can make it two, and we have this base here. So I need to put those buttons on the right, so we can't do that as we saw previously. We just need to change this to the right. But we don't see any change because this, you need also for toolbar component, you need to specify also the left. So even it's empty, so just make it like this and you will have it on the right. So let's also change the icon so we don't need it anymore. We need icon like go back or go out. So I have the icon already ready. So it's called arrow. Go. Left. Here we save and we have, the icon is already here. Okay, now let's go back to our form. So what I need to do is just do some clean up. We need to remove this router link because we are not clicking on Create. So here when we click on Create, we need this to save as a form in the database. So first we need to create the form. Let's take a look. Two prime end. Gee, how it's using the form for me, I need to textbox 14 to the name of the category and one for the icon of the category. So first of all, we go to prime NG and we check how we are using the input. For example, you see here a lot of input types that are input, the group's input mask, input switch, and also input text. And as you see here, we have this input text. But if I want to use this one, I need to follow the documentation. So I need to import also text module and then I can use it. So let's do that. I import the text module to my modules. If you remember, we have U xs module here. So I import it here. Again, put it here. So we have input text module ready, so I can use their component. So let's start basic. I want to use this one. I have here. And I go to the form, or for example, here I create a form. And this form, for example, will be empty. And inside this form, I am going to use a grid again. So I will give again a div dot py grid because I want to put them near each other. So I have here div called, for example, for and also to not miss here the p. And also another one for another text. So here, 12, we save it, go back to the application, we see that they are near each other. So let's add some margin here in the space between the toolbar and the form itself. So as you remember, we have here the property em, margin or for example, be margin bottom. I need to specify, for example, five. So we will see here that it gives us some space, but here we need a labels. So let's add also some labels, or C example in prime NG. So we have here multiple labels. But everybody is suffering how to align those input text and for example, a checkbox or how we align those icon with the textbooks or near the button, is always a suffer with a form. But prime N G solve this problem by creating agreed, especially for the form. It's very great. So if you go to the grid system OR prime flex, there is something called form layout. And in the form layout, you can select the lay out which you want folly reform. So as you see here, this what we need exactly vertical and a grid. So we can go here and see this, the code of this form. So we go here again down to vertical and degreed. We see that it's using some class called Floyd. And also it's using form grid and the grid. So let's copy this part and paste it in our application. So inside the form, I have a grid, I remove here everything and pasted go to the application. Again. I will see that very nice and guided for. So let's rename the things so we can make this as a name. And also here name, the label is named like name of category and everything is fine. And then icon. And I need here also icon. And here I click Save. We have now everything is working perfectly. In the next lecture, we are going to see, when we click on Create, we are going to read the data from the form and create the category in the database. 97. Add Categories Form Bind Form Data: Okay, In this lecture I'm going to show you how to bind data from the name, an icon of the category when we are clicking on Create. So first of all, we are not going to add anything to the database. We just need to bind the data. So I need, for example, when I click on Create, you will see here in the console the data which I put here. So for that we need to use reactive form and also we need to use for module. So to do that, Let's start step-by-step. First of all, I will go to Categories form. I have everything here. So I need to create a form, form interactive, which can interact with Angular. I can read the data when I submit the form or when I click on any button. So far that in Angular we have something called form a group. So every form has a form a group. And this form group contains all the controls like this name and icon. So for that, we need to define that our form is a form group. So we can't have specifying this input or property. And we say that we are going to use this valuable form in my building, this form. So we see that we have error cannot bind form group since it is not known property of form. Why? Because we need to import for module. So we need to import two things. First of all, the forum module, which comes from Angular. And also there is something called reactive forms module. So here we have two components or two modules we need to import to our app module. Then we will see that this directive will work mostly. So we save app module and we need to know how to build this form. So in that TypeScript file or the code file of this component, I go here and I need to define valuable form. So as you know, in Angular, everything defined here, after I define a property or directive or the input, I need to have a variable. This variable is available or must be available in the TypeScript file. So we can do that and say that form for me is a type of form group. And this form group, as you see, it's important automatically from angular forms to build a reactive form in Angular, we need to use a service, this service called form builder. And to call this service or any service, we use private form builder. We give a name and I import this one, form builder and also comes from Angular library from forms forms. So as you see here, we have now the form builder. And on initialization of this component, I need to define what are the group members of this component, all of this form. So I need to build the form somehow. So I say this dot form is equal to this. The service form builder. Give me a former group or a group. And this group will contain of multiple members, which are controls. And the controls which we saw in the HTML file. They are the name and the icon, and they are controlled here. So we have to define them as well here. I will tell you why later because we need to use the validator for that. So angular will interact with this form to spot every error that the user can port. So I go here and I say that name. So I need to specify exactly as the inputs which I have for this font. So I have here name, like name of that category, and it will be array. And this array, for example, now default value of it is empty and then I define the icon and the icon as well. It's empty on initialization of this font. And also, we need some property which is called color. I will show you later how to use the color picker up to pick up a color and implemented and inserted in the database. Because as you remember, our category has also a color. But now I am just starting simple as possible. So we leave only name and icon. So now this form, expecting that it has name and icon inside. And this can be in the HTML template. But how we can say, okay, you, this control, you are related to this form group. We can specify that by a property which is called Form Control name. And this form control name will have the same name which I specified in the form group. So here I must have also the name. So here I say that, that this input and this field is exactly follow the name of the category. The same thing I do also for the icon. So I specify here again icon. So in this way, I connected the form. With reactive form, which is here. Okay, why we are doing all of this? Now let's see how to bind the data and read from the inputs. Now that all of our button create, which is comes now. So we need to bind some function to this button. When I click on it. How we do that is very simple. I go to the HTML template, I go to the button, and then I say that a clique. And then I say on Submit for example, this any method you can define, any method you want for this button and we can't test this method. So I go here and do the TypeScript file I defined out of energy on it. I define a method which is called onsubmit. Let's console log something like for example, something like I am the button. So here we have the button which is clicked and it will console log for me in the console I am button. When I click on it, we need solid to save also the template. So when I click on it, I have, I am the button. Okay, let's bind the data now. So we need to have a way that we read the data which I input here. And then I put in them in the console. How we can do that? First, we need to go to the TA is filed and onsubmit method, steve of ion at the bottom I say this dot form, which we build already, dot controls. And then I specify the field, for example, name. And then I say value. So I need to have the value of this field. The same thing I do also for the icon. So I go here, save, and then I create, and I see that I have empty because I didn't specify anything. I specify here. And I will see that I got the data. So I will say category is health. And also the icon is, for example, icon health. So when I save or click, I will see that I got the data. So now we need to read this data and put them in the database. But first, let's do some validation. For example, as you saw here, that when I put empty value, I see that I didn't get any error and the data is sent. So I need to show to the user that you cannot send, for example, Mt name and empty icon. So let's do that. It's very simple that when we are creating the form group or the form builder, we need to specify that this field is required. And how we do that. We do in a way we call a library called validators. And this validators has a property which is called required. And also it has another property like max or max length or e-mail, etc. For now what I need is only a required. So this field will be required. So I cannot submit the form only when it's full. So when only when the user put data inside this textbox, Okay, now if I click, I see that I still be able to submit. For example, let's do it in a way that if the form is not valid, then don't console log anything. But when it's valid, then console log for me the name and the icon. So how we can do that, It's very simple. I say if this dot form is valid or invalid, then don't do anything when you click on the button. So just return. Otherwise, console log and do the name and the icon. Because if you know that when I click return or when I have written here, everything after will not be executed. So here I save. And then I see that I don't get any empty lines. But when I put data, we see that we got the data. So from here, we guarantee that the form is really valid or not. But what about displaying a message to the user? Like here, for example, we say their name is required when he's submit empty data. So we can't do that very easy. We just go to the template and after input, we can't have another element which is called small. And this small has glass, which is called be invalid. And this class comes with Prime NG. And inside this, we can define what the method will be for the user. For example, name is required. I save. And we will see that this is always displayed. And which is a problem for me. I need just when there is nothing in this field, I want to display this message. But first we see that it's not there at the, because I think the class is wrong. We can change it to error. And we will see that it's talking. Yes. So now we have it a read. Based on the error class, P, Error class. So here we have to specify when it will be shown. So as you know in Angular, there is energy if so in ng-if I say when the form dot controls dot name is invalid, then display this message. Form dot controls dot name, dot invalid. Then display this message. So now we have it invalid, but when I put text, I see that it's disappeared. So now as you see here, showing and hiding things. But the issue here that when I go to Category I go knew I see directly that the name is required. I don't want to surprise the user directly with errors. I just want to show him the error when he click Create and he has empty field. So how we can hide it first. So we need to check if the user clicked on the button or know how we can do that is very simple that I go to here to the ts file and I say that is submitted is a variable where I can define always place your variables, always on the top before the constructor, then the constructor, and then the initialization. And I will tell you about also the private methods. So here is submitted type Boolean, and it has a default value which is false. So at the beginning, the forum is not submitted yet. Here I have a typos or have submitted. And then now we can go to the button on submit and IC first, this dot is submitted is true. So here we have the submitted is true. So I can say now that when this error is ng-if invalid and the form is submitted, then show me the error, but don't submit anything, then don't show it. So here at the beginning, we don't have anything. We don't have any arrowed. But when I have this, okay, I don't have any error. I can submit. But when I empty it, I see it again. Let's go back again. Two categories will again hear him of console. So here we say that when I submit, I get this error. Name is required. So I must feel some data here. So in this way, I show that this is foreign required. Let's do some quick refactoring. So first of all, I don't want to have in my HTML template very long name. So I can do that and I can make this type here in a variable. So it's very easy. You can use set and get. So how we can do that, we can define, for example, get category form will be a method and it will return for me this dot form dot controls. So when I want to access the contours of this form, I just say this dot name or this category form, icon, etc. So in this way I can access and replace also this. So I can say here, not form controls but Category 4. So I save it, test everything. We have everything working fine. So now we need to also to put it for the icon I go here. Also we have to copy the same. I say that icon is required. And here instead of name, I say the icon. So now we have the icon and the name fields are required and we are able to bind the data and see them in the console log. In the next lecture, I am going to show you how to send this data to the database so we can't see them also on our categories table. What we added here. 98. Add Categories Form Send Data to Backend: Now let's send the data to the back-end. So I have here a name and icon, and I will create category in the back-end. So how we can do that? First of all, we have everything collected. So we have here the data, we collected, the object, we collected the name and the icon. So now we need to have a service as well. If you remember, we had a service for getting the categories. Now we need the service for adding the categories. So what we need is to import category service and add the categories add category method. So first let's import it private category service. And then I say categories service. So it will be important automatically, as we see here from the products. And we need to go there and also define our method. So here, somehow I will say that if it's invalid, then return, otherwise, use the service and find add categories. But now we didn't define it yet. Let's go and do it. To go fast in, inside these files is that it's so easy way you just have to press Control and p. And then it will open for you all the files. You can serve them by name and then you can say categories, service, and then you will jump to the file directly. So this is like It will give you more productivity. Do not search for the file in the list of the files. So I want you to have create the glory and they create category. We need also to send the data. So we need to send the data of the category. So I have to say category has a type category. So I want to send category itself to the backend by this method. And this method will return this though the HTTP request dot post, because we are posting data. And this data will have first the URL. As you know previously, we have that URL here. So we have the same URL for posting the other as we saw in the back-end. And also we need to specify the data. So the data, I got them from here, I say, put Follow me that category, that's it. So now we have create category. I go back to the form and then I will see that in the product or category services we have created category what I need to pass our data. So we need first to create an a constant, call it category. This category has a type category, and this category will have the property name where it come from, from the category form, dot name, dot value, as we saw previously. And console log them and icon. So this category form the icon, that value. So in this way, I created an object. Here. It's not semicolon, but it's comma because I am creating an object and then I am going to send this category to this service. So let's try that. Now. I go to Create. I add, for example, health and beheld for the icon, I click Create. And I see that nothing is happened because also if I go to the network, I see that the front end is not sending any request. That's why because I told you that we need to subscribe to everything observable of the data server is sending me back. As you remember in hearing it, that this good is returning for me observable. The same thing, boss is also returning observable. And as we saw previously in the back-end, that the backend is sending me, for example, when I create a category, is sending for me that the category is added successfully. So for that, we need just to subscribe to this data so I cannot use the service as it is here. So I just need to say subscribe. So when we subscribe and this way it mean that really give me an execute data. So here I have health and then P health. And I am observing here the network. When I click Create, I see that the category is created and added. And when I go to their list of categories, I will see that it's added here. So just remember that you need always to subscribe, because if you don't subscribe, It's like you call the method, but you didn't do anything. So this HTTP request boasts will not be executed only when you subscribe to it. Okay, I noticed when I added this, I didn't show to the user, okay, This is added successfully, or he got error or something. We need to interact with the user somehow. I need to add, for example, a notification says that, okay, The category is added successfully and go back automatically. Two categories, table in prime end you, there is a module called toast. And this toast, you can always display notification to the user, something like this. So you can always show some notification to the user and they disappear automatically after some time. So we need to implement that. So first we need to import the module. As always we are doing. So here we need the module. I go to the UX of the modules. One of them here, as we said previously, Let's put the core modules first on the top. So to not have any issues. And then we have also the UX modules are grouped together. So here we have a toast module. Okay, nice. Everything is imported. No any problem if you get this error somehow that you need to restart the front end. So when you get that error, you just need to restart the front and again, and it will disappear. And to use this notification, you just have to call P toast. So when we go here and copy this HTML tag and we go to the form added to the top before the form, I say Pete lost. So I save it here, and then we need to fire this toast. So as we said, when I click Create and everything successful, then I will fire this toast notification. So how we do that? If we continue in the documentation, we need to call a service which is called Message Service. And this message servers will have ADD. And then you'd specify their color, which is success, and the summary service message and the detail of the message. So let's import the service. I go private message service. I also go here to the form. And also we have here many private methods. So here we have also the message service. So you just need to import it from prime end API. After that, everything is working fine. So I need to know after their category is added at taxes for I want to display a success message. And when there is some error happened, then I was a failed message. So as you remember, we said that create category will be observable and it will return for me some data. So as you see here, that this service boast is returning observable with the data. So what this data, it would be the category itself, how we have created in the back-end. So the new category. So here I will have a post observable. So here I will have a return type is observable but not observable array, it will be a category only single category, not array. So going back to the component itself of the form, I see that if I get a response, then I display a success message. And if I don't see any response or I get error from the back and then I display an error message. So how we can do that, the response, I get it. And then I will say here that display this message service severity. And then I will say success and the summary of the message and the detail of it. So here I will say that I have first the success message and the type is Example, success or the summary is success. And that I can say category or like message for the people or for the user, category is created. And also we have, when we get error, then we have to display an error message. So how we can do that after this bracket, we have a comma and we say that error, and this error will be a function. It will return for me the error message which I see in my data. So I will do the same here. I will get this one. I will say this.me dot add cyber t is error. And then I will display, for example, our category is not created. But first we need to add something which is very important. That is the template, the template of the host itself. So we have here the HTML template. We are going to look normally add them to the top of the template. So we save, we go back to our application and we go to New. We are still getting error. This is injector error because we are using message service and it's not provided in my app module. So first we go to the app module again. And in the providers, as we talked previously, we need to add the message service here. And then we have to import it. And we save, and we see that we have, everything is working fine. So now let's add some category and we see if we get the toast message or not, which is called, for example, computers. And then the icon will be, for example, we can select any icon, PCI, PCI, for example. I don't know if it's exist, but we can't see that later. So as we see here that we got another error. This because we didn't include browser animation module. If you remember, in NGI shop we added this module, but here we didn't add it. So let's add it again to our module. So if you remember, we have here a browser module. So we need to import the, also the browser animation module. And this will be important. Here. We say browser module, animation module from Angular, and then platform browser. And after platform browser, we say animations. So here we imported the animation module. So let's create again that category. We have to say computer and we can say PCI, PCI for example. And we create, and we see that category is created. And let's check our table. We see that it's really created and this created here because it's created and then we didn't get the message. So that's why it's created here two times. So let's make an error to see if the error is really working. So I go to their service, which we created. Let's make a mistake in the ABI for example, we can say with some letter like this. So when we add a category, we go again to new. I would say again computer. And we say PI BC I create, and then I get error category is not created because the back and respond to 4.4 not found. So let's put it back and everything is working fine. And we have the created category. Let's fought example. Put the user back to the categories table automatically after we create the category successfully. So how we can do that? I go again to the categories form component. After success, I display the message. I will set a timer and this timeout after it's done, then we go back to categories. So first we need to have a timeout, timeout or you can use it from note, our x js. And you can, inside this dimer specify how many milliseconds you want to execute it. And then I say to promise. So diplomas, like after it got executed, after two seconds, then what you want to do, say, for example, done. So to go back to categories, we need to use another service which is called location. And this location is a service. You can import it easily. So here we have also another service. We can call it like this private and we call it location. And this location is type off location, that location from Angular common. Okay, So as we see here, we have node modules, angular common. So we imported and we see that it's really from Angular common. So here we use also this methods or this service. We say this dot location and then I sway back. So I just want to go back where I was before. We save everything as a style. Again. We add, for example, another with say for example, I want to add electronics. And then the icon will be PI electronic. This is an icons are just random, we need to fix them later. So I press Create. And after two seconds, we went back automatically. So as we see here, that everything is working fine. We have that those two, we have the messages and we have also created categories. In the next lecture, we are going to see how to delete a category and how to edit the category. 99. Delete a Category with Confirmation Dialog: Okay, In this lecture, I'm going to show you how to delete a category and confirmation dialog for the user when he wanted to delete a category. First of all, we are going back to our table of categories. We need to add here some action buttons for each category, like a button for delete and botton for edit. So we go back to our categories list table. And if you remember, we have here the header of the table and the fields. So I need here first to have another header or another column on the header. Let's keep it empty. And here I want to add two buttons, one for edit and one for the delete. So instead of this category icon, we remove it and we add here two buttons. First one is a button which I copied from the top. It will have a road or danger. We can call it as depend what the class we are going to use label. We don't need a label. We can just delete it because we need only icon for this button and the name of the icon, it not be plus it will be PI, thrush and this trash. For me that there is a delete router link. We don't want a router link, but we will need a click. We will add that when we are ready for it. We need to add another button. And this button will be for editing. So we have here another button, but it will not have a trash, it will have an icon called pencil. And as you see here, we have PI pencil and then we save. And we will see that our application got updated. But here we need to add more distance between these buttons. I will add here a class. I will say p minus margin, right? Then to add we save and it will have this spacing. So let's check how we can color the buttons. If you remember, if we go to prime NG, we go again to the buttons and the button that we have a different colors. So these colors are called, for example, a danger. If you want to see all the code, you just go to the source and you will see all the colors here, all the code which is written there. So let's use two colors. First, we can use a danger for remove or delete. And also we can use, for example, succes with a green, which is for editing. So we save, go back to the application, lies, we have everything is fine here. So let's have a click event on this button. So first of all, we can add up method here, which is called onclick or click. Then here we have, for example, Delete category. And I want to pass also the category ID which I want to delete, so I can say Category dot ID. So in this way, I guarantee that I am deleting the right ID. This method will be declared in the TypeScript file. I go to the TypeScript file of categories list, and I add a new method after NGOs in it. I call this method DDD category, and it has category ID as a parameter, which is a string. So for that, we need to use category service contiguity service will delete for me a category through the back-end. So for that, we need to create the service which is deleting for me a category. So we go to our service. I said category service. And I added here at the lead category, which is accepting category ID as a string. And it's returning observable maybe of the leading category or maybe for example, only some object without specifying anything. And also the HTTP request will be deleted. So here we have also returned object because if you remember in the back-end, I am passing the ID to the URL and then it will be deleted. So as you see here, we have here the backticks and also the URL. And then I used the category ID, which is passed through this method. We save back to our component. We would use the category service. So we say this though, category service Dot Delete category. And then I pass category ID, which I got from the HTML template. But as you know, this delete will not be executed. So I go here, I say subscribe, and then I went for response. And this response, I can display a success message or a failed message. So for that, we need to have the message service which we had previously, and also the toast message. So we have here the toast, we copy it from the form. And also we added here to the top of the list in the component list. So here we have this one and we'll call again the messages service. So which is this one? We'll copy it again to our component or categories list component, and we call it, and we say exactly the same messages which we wanted to display to the user. So I want when there is some success ISA that success and category got deleted. So I say here messages or message service succes category is deleted. And also when there is an error, I want to show to the user that there is a problem. We cannot delete the category. So same as here, the brackets after, before ending the subscribe, I add the error ISA, the category is not deleted. So we save, we have everything is working fine now. And when I try to delete, for example, let's delete the one which is doubly located. And then we see that category is deleted. But it's not deleted from the list only when I go to another page, for example, to the dashboard and go back to category, then I will see that categories is really needed. So when I want to delete something, I want to refresh this table. So it's very simple. We just call the service again. So on succes of the deletion, we can say also again called for me this. So let's put category service of getting categories again in a method. We call this method, for example, private because it's only inside this ts file, it's not used anywhere else. So we can say Get categories. It's a method. Inside this method, I am calling this service. So first I call the method on NGO on Edit calling this dot getCategories. And also I am going after a successful message or successful response. I want to have this good categories again. So we save, we go again to the front end, try to delete something. Nice. We have refresh that they will, and we have the new data as Delete again. Nice, it's deleted and we have refreshed data. But for me as a user experience, I am afraid that when I click by mistake on this and it gets deleted. So I want to show a confirmation dialog to the user. So when he wanted to delete something, then he gets confirmation. If he really confirm the deletion or not. Prime N G has also a component called confirmed dialogue. And when you go to confirm dialog and try it out, for example, this one, there is a confirmation message with some icon and some text. Yes and no. This is exactly what we need for the meeting and confirmation for our deletion of the category. So how we can use this component, we can go first to the documentation and we will see that we have to import two modules, or one module and one service. So the first module is confirmed dialogue module. We can copy this one and go to app module where we are importing the module or the UX module. And then we add it to our UX modules. And we need as well to import a confirmation service. And this service, we are going to use it in our categories, least component. But first, we need to use also some HTML. So I need also to copy this code. I will say that we have here confirmation and icon and also a confirmed dialogue. Or it's better also to use the example exactly which is here, because it has more properties, because as you know, every component has a lot of properties. So when you find the property which you want or the example which you want, just use it the same. So when you want to see the example of this, confirm, just go to source and you will see here the exact example. So as we see here, that in the basic, he used this HTML tag p confirm dialog, and he gave it some style and also bays Z, index and some styling for the button. So we can copy this one. Go to Categories list, and we put it, for example here at the end. And now we need to have the service, so how he is using the service confirmation service. So I'll we see that he went, he click on the button, he executing a confirm one method. And this method will have these properties. So this confirmation service has a confirm and it has some options like a message, header, icon, and also when acceptance and when reject. So when I accept, I delete the category and display a message of success. But when I reject, I just do nothing. So we can copy this part, all of it. And we go to our categories list. So when the user click on the need category, first of all, we want to show him a dialogue. And this dialogue will be exactly from the confirmation service. But first, we need to import confirmation service, as we saw previously. So we need to have their confirmation service, which is imported from the prime energy. So we have here Message Service and also confirmation service. And when you press control space or control dot, you would get the Auto Import. Now back to the method, we will see that, that we have the confirmation message. So we can replace that with something like, do you want to delete this category? And also the header will be Delete category. So it's like a title of this confirmation dialog. And we give exclamation triangle as an icon to show that it's danger. So we move this bar chart, where is this category service? And we copy all of it with the arrow itself, and we place it inside the accept. Nice. So now we have the confirmation dialog, confirmation dialog service, and then we have the error and the messages. But on reject, I will not do anything. I will just keep it like this so we don't have to do anything with it. We save. And as I told you, maybe you will see this error. Just restart the front end and you will get rid of it back to the front end. We try it out. We will see that confirmation service is not provided. So we go to the app module, and again, we need to provide the confirmation service as we saw with the message service. So we back to the front end and we try to delete some category. I say delete this one, okay, We got the lead category. Do you want to get it this category? And then when I click Yes, I see it got deleted. And also table is refreshed and I got a message. But when I click now, nothing is happening. 100. Edit a Category: Okay, in this lecture, I am going to show you how to edit a category. Previously we made the Delete. Now we want to do the edit. So we want to make this button functional editing category will be exactly the same form for a new category. Just the difference that we are filling the data of category already here. And we need also to change this title to be edit category and also this button to be, for example, update. So let's start from beginning first. Let's give a function that we have 20. Click on this, we go to the component of the new. So first of all, we need to create these method. So we go again, two categories, list component. Here is categories least component. And on the button update we had here, delete, and also we had an update or edit. We have to add a function. So it will be exactly the same how we did with the delete. So I need to have a click, and this click will be update category. And I want to pass as well. They category ID because I need the ID to grab the data of the category. So here we type category ID. We go back to the TypeScript file, we go to Categories list, and we add a new method. We are calling it Update category. So here update category, and then I have category ID, which is a string. And this method will navigate me to the form of category. So it will navigate for me two categories for, so in that way, we need a navigator. So we need a way that when we click on that, it's navigate us to that component. Of course you can do it and away also in the HTML template, you don't have to have a click event, but you can also directly do it as a router link, how we did previously with a normal links. But I want to show you also how to navigate when you need that. The TypeScript file in Angular, there is a class which is called router. We can also import it in the constructor router. And it's router, and it comes from Angular router. And when we want to use this router, we go again to update category. And I say this dot router dot navigate by URL. And here I specify the URL which the router will take me. So it will be for the new component, which is the form component. And here we say, we have backticks. We, we say category form. And then I can specify the ID which I want to pass to this link. And then we say here that category ID is this category ID. So I want to go to this link like ISA categories form, and then I pass the ID where I want to navigate to. But the issue here that we don't have that link, we have only like the forum. So when I click on New, it will take me to the forum, but I don't have something with the ID. So let's add that to the app module. We go to app module file, and then we have here the routes. We will have a new route, which will be exactly the same as the new one. But we need to add here some ID. So when you assign this with ID or any key you want to use, then it will have like a parameter, like a variable. So you can use that as a parameter and read value of it in angle. And we want to refer to categories form as well. So let's check if everything is working fine. I'm going to save all, so all the changes will be saved. We go back to our application, it's updated automatically. We click on edit, we see that everything is right. We navigated to the right URL. And also we have here the Id, the Id of their category, which I clicked. So when I click on this one, I will have different ID. When I click on this one, I have also different ID. So based on that ID, I will specify that this forum is for editing or is for adding a new category. So for that, I am going to their categories form and define a variable. We call it edit mode. And this edit mode will get a value at the beginning, or as a default will be false. So it's not edit mode by default, but we have to make it as edit mode when we are navigating for editing a category. Okay, So how I can know that this form is in edit mode or not, this will be known by if there is parameter after this link, then I am in editing mode. And if I don't have this parameter, then I am not on editing mode. So how we can know that first I would create a method on energy on edit. I call it, for example, these dot. We can call this method check edit mode. So in this way, I will check inside this method if I am in editing mode or not. So let's define this method. Go down. And if you noticed, I am showing the internal methods. I am using underscore behind them and a flag them with a private. So then I need a way to read parameters from their link, from the URL. I need to know if there is 3D ID or not, how we can do that. If you remember, we use something called route. But here in fall there is something called activated route. And this, we can use it from Angular for knowing if we have a parameter in the URL or not. So let's call it. We have a private or router. And this router, it's called activated route. And this activated route comes also from Angular router, or it's better, Let's call it a route only. We go back to our method which is check edit mode. We go here and we say these dots, route dot, params, like the parameters, check for me the parameters which are in the current URL and then subscribe. So I want to subscribe to see and observe the link when I go to this component. So you remember, we are subscribing to observable. And observable is always giving us a new value. It's like a heartbeat, you can imagine every time it comes with a new value. So waste on the abuser what he is clicking when he click Add come to this component and he has ID or parameters in general in their link, then the subscribe would be fired. And then I can read the parameters which are coming with the URL. So to read this parameters, the subscribe return for me, firearms, for example, you can define a variable here. Then we have open arrow function and the arrow function inside it. I can handle what I want to do. So for example, if there is params, ID, if there is ID inside those params, and this will be exactly the same one which I defined in a module. So here, when I say ID, then I must search also for ID. But if I call it, for example, category ID, then I must here also search for category ID. So if there is an ID like the user clicked on edit mode and there is ID param in the link. Then make the edit mode as a true. Okay, so now we are in edit mode, we are sure that the user clicked on the Edit button and we are reading the values which comes from this category ID. Perfect, Let's save now and let's see if we can like weaker start simple. We can say for example, let's change this text to be ad is TD edit when I am adding a new category. And also edit is Td of ad, where I am editing air category. And also this button will have here update when I am updating the category, when I'm in edit mode or create when I am creating a new one. So let's do it is very simple. So we go to the template, HTML template, and if you know ternary conditions, It's like in-line. If so, when I define this input as two-way binding, then I will be able to read the values here. So for example, I can see variables. I can take the edit mode if it's possible to change it or not, or read on it based on that. So in this way, I can be able to read the edit mode valuable. So I say like was definitely conditioned the inline if condition, I say Edit mode. When I have edit mode. Then for me here, put for me here, edit category. But when I have not edit mode, then make it as add category as before. So here we have specified based on the value of the edit mode. If it's true, then it's edit mode. But when it's false, then it's category or adding a new category mode. Let's save it and try that again. We will see that we have ADT category, but when I go back to categories, I click on New, I will see that I have add category. But when I go here and click on this pencil, I will see that I have edit category. So the same thing I am going to do is with this button. So when is Edit Mode, then make it as create, but else make it as edit. So the button is already in the toolbar and is it here? So we have it here as a Create. So we say that the label will be available based on the edit mode. So when it's Edit Mode, then give me as update. And when it's not edit mode, make it as creates or when we save, we see that it has an update because I am or I have ID here. So when I go back to category. Haven't you, that it's Create. Go back to categories, edit, then it's update. So now we made as tactic change. So we have only that exchange based if I have here an ID or not. So now let's feel the data which comes with this form. So we need an API or the Ecole that it will grab for me that contiguity with that ID. Then I feel the data of that category inside these fields of that form. And of course, all of that will be on the edit mode. So when we go back to our function which we created here, we need to check if we have a category with that ID or not. So we have already these params ID. So I am reading the ID here. So I need a service to get a category by ID. And we have created that already in the backend. If you remember, when I go to category and I call it by ID, follows for example, I call this one. And I put ID after their link. And when I send, I will get that category from the database, which is exactly with the detail like name, icon, and color. So as well, we need a service. So when we go back to our service, which is category service, we need to have a gets category, categories, but one category, so it will be the same. But here I am passing the category ID, which will be a string. And also the observable were returned for me only one category, not multiple categories. So I will get only one. And at the end, I will have here the category ID. So I will have here like plus category ID. Or if you want, you can use the backticks feature. So we can have here back tick and also hear back tick and that dollar sign and then Isaac category ID. So in this case, we have the category ID. We got it exactly with that service, but we need to rename this and we have it as good category. So let's go back again to our form. So we can go here, two categories form. And then I will say this dot category, service dot get category. And this category will accept category ID, which is in the parameters. So I will say params dot ID and then subscribe as always. Then I will get, okay, So inquiry. And then I will do something. I want to set the fields of the category to be in the form with that category which I got from the back-end. So if you remember, we can reach these controls by using this category form. So we say this dot category form, dot name, dot set value. So I want to set value for this. So I have set value category dot name. So I am getting here that category and I am using the name of it, which I got from the backend to set the value of the field, which is in this control. So it's very simple. So here we have this one and also another one for the icon. So I will say though icon dot set value and then category dot icon. So let's save that, try it. Okay, We have heavily thing is fine. So we have, again, we go back to categories. We have here a beauty and we have health. When I click on health, then I would get here health, health. And also when I click on beauty, I have here beauty, beauty. And every time I click, I call the back-end to get the category of the current visited category or visited ID. Okay, so what we need now is when I change those fields and then I click on Update, then it gets really updated in the database. So what we need, you have to repeat with me first, a service which is updating for us in the database. And also we need to define the logic. When I click on the button, it will send update request, not any request, because if you remember, this form is made only for creating a new category, we need to check also the edit mode, and then we decide if it's update or if it's creating a new category. So let's do the logic of the button first. When I click on this Update button, as you remember, it's only one button. We are only just changing the text. So here we have only update or create, and then we have the method on submit and submit. I am checking if this form is valid or not, and then I'm creating a new category. So maybe after we collected the data of their category, like we know what the user entered in the form. We can check the Edit Mode. If these dots, edit mode. Then update for me that category. Else. Then do for me, I create category. So for that we can define a method. We can call it this dot update category. It would be a private method. And this method will accept for me a category. So I will send that category data which are collected from the user, and then I will send them to this method. Else. Then I will say also another method, just to make our code more clean and more readable, we can say Add or Create category. And then I pass again that category data. So we need to define two methods. So this method is already defined here, we have it already here. So we just say private add category, and this category will accept category data. So we can say that we have here also category. And then we can cut this part of the code here and then pasted in at category. So we have add category inside this method. So we need to add update category. It will be the same. So we have here private update category and then it will be a category and also it will be type of category. I always try to show you that to add always types. So it would be better for you. And more code friendly or developer friend. We will do some refactoring later based on the rules. For example, I am not using gear that response so I can get rid of this parameter. We will see that later. So I want you to see the video which I want to do about refactoring. We refactor all of this code, check our problems. Everything is cleaned to deliver it in very clean way. So what is the difference between create category and update category? The difference that the create category, I don't need to pass an ID of their category which I want to update or create. But in update category, I need to pass the new category data and also the ID of the category which I want to update, which is this one. So for that, I guess that all of this method will be exactly the same as add category, except that we need to have also the ID. So I will say here that we can copy here everything and paste it here. But we have not here create category, but we need an update category. So updating a category with using the category which I want to update. But as I told you previously, we need as well the ID. So let's create this service. First, we go again two categories, service, we create the service and then we will discuss about the ID, how we can get it. So first of all, we have here create category, it will be exactly the same. We just need to replace this one too, date category. And then we read that category. It will return for us a new category which is outdated. But here instead of post, we need to add put. And with this PUT request, we can update the category. And also we hear, as you remember, in updating the request, we need to go to put, we need to pass all. So the ID of the category with a new data. So it's not only about getting and sending a new data, but also we need to pass also the ID. So we need here somehow, like we say, plus category dot ID. Okay? But this will come undefined, I guess, because we didn't specify in this category that we have also ID. So how we can do that, we go back to our form here. So we say that, okay, I have here update category. But if you remember that category which is passed here in the method, it has only name, an icon, but it doesn't have the category ID. Okay, if you remember, we got the category ID from where when we were checking the edit mode. So in the edit mode, I can define also a global variable like near this edit mode, I call it current category ID. So I say current category ID. And this will be, for example, a string. And at the beginning it's not so because it doesn't have any value at the beginning. So when we go again back to the edit mode, we need to have this check edit mode. And then after I assign the edit mode, I say this dot current category ID will be params dot ID, because if there is ID, then assign it to current ID. So when we save, I think here we have an issue. We are missing the end of the subscribe. Bracket, so we need to add it here. So just be careful when we copy paste some staff to not miss some brackets. We check our terminal. If we don't have any issue here, then we see that, okay, we have missing that the category is not defined. This is because I didn't save their category service. So we save it again. I click on categories. I want to update also the icon beauty, so not, not delete or update. So I will say here a beauty for example, we fix this issue and we remove this icon. And then we click on update. We see that we are getting error and our backend say that it's undefined. This undefined. Why? Because I read the category ID, but I didn't pass it to the service. We have here the current category ID. So we just need to build the object of their category which I am passing to update or delete or sorry, add with an ID. So I will say ID will be this current category ID. So when there is an ID inside the edit mode, then I send it to the edit mode. But when there is no, then I send it even There is no because the idea would be created in the database when I create any category. So let's save that. Tried again, we remove this icon and add here beauty again and here a beauty again, and we click on Update. We see that category got updated and we went back to the list this because we copied the same code, which is 4 add category. So let's just picks the texts. All we need here, getting good is updated. Category is not updated when there is some error. So when we save, try to edit this one. So we can see here be health update, lice, get a good is updated and it's automatically went back. And we have here the updated category. So as a recap and quick, so we need to specify if we are editing or we have NU. We are using the same form because we don't need to double negate the code. I don't want to create another four for creating or editing a category. So we can use the same component but in different conditions. So first of all, when I have a new, I just create a component, no problem or category. And when I have edit, I pass the ID of their clicked category. And based on this ID, I defined my things, I defined my logic. I say this is edit, this is update or not. And also I feel the data of the category. And how we did that, we saw that we are reading this value from the params. And by the params, I send again the function based on the Edit Mode. If I am on Edit Mode or not. And then I update that category or add Eliyahu category based on the edit mode condition. And of course, for every movement where I want to do, I needed to services one service which is grabbing for me the selected category from the database. And also when I want to update category, I created update category service, which is also located in the service to update the things from the database through the backend, which we are using the API here. 101. Add Color Picker for Category Color: Welcome back. In this lecture, I am going to show you how to create a color picker. Because as you remember that our category also comes with a property which is called a color prime. Ng also comes with a color picker control. So you can pick up a color and use the value and store it in the database. How we can use this color picker? First of all, we need to import the Color Picker module and then use it in our application module as I did here. So I have here the color picker module and I import it to our YOU exposure. At next, we need to use some component which is called pea color picker. So let's copy that one and go to our form. So I would like also to place it near the icon and the name. So we can have also here a color property. I'm showing you this because I want you to know how to add another properties so we don't have only name and icon in category of course may be we will have color, we will have image, we will have multiple things. So you can add your own properties based on your need. So I am showing you this specially lecture just to show you how to add another properties to be more practical. So we go back to our form and find the field. So we have here created a fields like we have a name and icon. Let's create another field. I say div. I give it a class which is B field, and also another class which is called P call. So when I press tab, I will see that they are assigned to a div as a class. So we need as well a label. So we can have this label for color. And inside this label will be the text color. And then we are going to place our component here. So we have here color picker and you model color. But as you see here, we are not using NG model. We are using Form Control name. Of course, this color picker, I'm sure in the documentation they mentioned about it. So we can see that in model-driven forums or in reactive forms, color picker can be used in a model-driven form as well. How we can do that, we just give it a property form control name, which is pretty simple. So we remove that part. We say, Okay, Form Control name. But as you remember, we said that every control name must be inside our form group, which we build in the ts file or in the code file. So I go again to my form builder and a group, and then I add the color property. So I say here, add for me color. And the default value, for example, can be FFF. So this color, the wide, which will be a default when there is no value comes from the database. So let's save everything to see if everything is working fine. Going back to our application, we see great that we have the color here. So we have everything. We have a color picker and what we are missing now that we need, when we are updating the color, we need to send it to the back-end. So first of all, as you remember, when I add a category, we need to pick up a color. And also when we are going to update category. So first let's add a category. So when I am adding a category and press on Create button, if you remember, we are creating the category object. We are having ID, name, and icon, which we pick up from the form itself. And then I am sending them based if I'm in edit mode and all if I am on Add mode. So we talked about that previously. So I need also to send the color. So it would be exactly the same way. So I will say as well, color will be this dot category form because we define the form in the form that we have a color as well. So I will say color dot value. But here we are still getting a problem. We are having issue saying that the color is not assignable to category, like the color doesn't exist in the category type. So when I go to that category, I will see that I already don't have this property, so we can't add it and also add it as optional because sometimes I don't need it and it's also optional. So after that, when I added it, the error, these appear. So now let's try to add category based on what we have done here. So I go to our application, give a name, for example, PC games. And the icon will be a PC. And then I will give a color. For example, this one red. Or let's give it like this to be like recognizable. And then I click Create, just watch out to your network what we are sending to the back-end. So when I click Create, I see that gets a GUI is created. And the color which I sent is exactly that color which I selected. And when I go again to edit this category, I will see that the color is set back to glue this because that we are not initializing. Also, when I click on edit mode, as you remember, we are initializing those fields, those values. So what we need as well to initialize the color. Doing that is pretty simple. We just go again to our categories form. If you remember, we are doing check edit mode and inject edit mode. When I have edit mode, then I am setting the values of those fields to initial value which I get from the database. So we are just going to need to add this category form dot color and then set value of the color to be category dot color, which I got from the back-end, which I got from the database. Because if you remember, also, our backend is sending us the color because we saved it in the back-end. So when I click Save, okay, go back to the application. We see that the color is initialized and which is a great thing. So here I have that color. Sometimes I don't have anything. So because it's getting a black or something like wide. So this already has a color in the database. So when I go to Categories and I want to edit, I will see the original color. But as you see, I don't like have it like this. It's in the same line of their label. So we need just to put this icon or this color to be in the same line with those inputs. So to have the label on the top and under it is a color. It's very simple here. I am going to do it's very quick. I will just add a BR. Br is a breaking line. So when I save, I will see that I have here a breaking line and I have that color, which I can pick and update my category based on that. So let's add also that column to the list of the table. So we can have here id, name, icon, and a color. So to do that, we can also go to the list. I have here another td, which is category that color. And also I have a header. So we will have a header of the table which will be called color. So we can have it as color. And also the value or the TD be that category dot color. So when we save this form or this table, we will see that we have the color. In the next lecture, I am going to show you how to beautify this table. We want the user to be more friendly with the UI. Like I want him to see the icon itself and also I want to show him the Recolor lot, texts and codes like this. So we want to show to the user the real or the reality of the category, how it will look like. 102. Refactoring Code & Beautify Categories Table with More Features: Alright, in this lecture, I want to show you how we can display the color and the icon on the table list of categories. So first of all, as you remember that we are using Icon Library, which is provided by prime end. And this Icon Library come always with a Class II and then BI, which is shortcut for Prime icon. And then you specify the name of the icon. Of course, you have the option to not use this icon library. There are a lot of icon libraries. You can use them just you need to replace the styling file which we had previously and which we created in the public files. So you just need to go here and say that I don't want to use, for example, prime icons. I want to use, for example, Google material icons. So in this example, we are showing how to use prime icons. So if you remember in our database that we are just storing the icon name. So for example, if I want to use one of those icon, for example, I want a compass. I just go here and say that the icon of this category will be a compass. And then I click on update. You have two options here. You can store all the name of the icon, like PI icon, and then store it here. Or you can also, you just put this prefix and hardcode, this prefix which we need here in the table in the HTML code. This depends if you are going to use this icon library or not. So if you want to use different icon library, then I advice you to store all the name of the icon which is in this field. Or if I am going to use only prime N G icons as I am going to do here. Then I store only the suffix of this icon, which is the name of the icon. And here in the code, I go to the field where I am getting the icon name. I exactly how we are using the icon. And this icon will have a class which is called P icon and then the prefix itself. But we do it in different way. So we say ng-class will be exactly like, for example, we put it also in brackets so we can use a variables inside the NG class. So the ng-class in this case will be the prefix itself, like PI plus category dot icon. So I say here that I don't want to have a prefix or suffix, but I want to use that category icon, but everything is here hard-coded. So when we save, we can see that we are going to get the icon in the table. So here we have the, for example, the compass. I want also to change this, for example, health. We can give it another icon like for example, we can have this heart, so we can go here and replace this. We say update, okay, Give it to me as a heart. And also we can change this to something like In the icon, something like this, th large. So we can have this one as well as an icon I updated. And then all of them will be placed exactly how I prefix them in the table. Otherwise, if the name is wrong or doesn't exist in the icon library, then it will be empty here. You can as well resize this icon and make it bigger. It's also written in the documentation that you just need to add. Also font-style, which comes here. So style, font size, you give it, for example, to R, m. So we can have it like that. So here I have i and then I give it as time. This style will be saved to our EM. And then we will see that the icon got really bigger as a user or front end user, I am not interested about the ID because it's so long and I am not interested how this ID is displayed. So maybe we can remove this ID column from here, so we don't need that anymore. So we just remove it and we can have only the name and then the icon and that color. So as you see here, we will have a new table and then we have the color for the color. I advice you also to replace this to be the same as the color. And it will be a homework for you. I will create a homework after this lecture, I want you to show me how to replace these hashCode with the red color. So I want, for example here a div, which will show, for example, the color of this hashCode. Okay, What about adding a sort feature for the table? So for example, if I click on the headers, I can sort these columns. So I can sort by name in this case. So let's activate that. I go to prime end table and check how we can activate the sort. So as you see here, we have a table and then we have here a sort. And this example is showing us how he is sorting based on what you click on the column. For me, I want only one column to activate the source-based on. So if we go to the documentation, we will see that he is attaching an attribute to the header of the table. So where he wants to show all sort the table based on. So I want, for example, to sort based on the column which is called code. Or I can sort based on a column which is named name. So we can do that also for our table. So I can go here and copy this part where it suitable column. So I go here and I go to the name field or their name Header where I want to sort by name and place it here. So then we will have a sort of a column name. And when I save and go back to our application, then we will see that it's clickable and it's sorting. But it's not showing me the icon where I want to sort like, for example, from a to Zed or from Z to a. Then I want to add also another field which is called P source icon. And this is a component which can be used to display the icon of the sort. And as you see here that he placed at after their name, it will be after the name which we created here, the text itself. So it will display the icon which we want in our application. So when we go back and we will see the icon, then I will know that how I am sorting. There are more features can be added to the table. But let's now keep it like this for the category. Because as we said, we start simple, but in the next lectures for products and users, we will add some filters like search for product or for example, toggle or for example, resize the columns. That's what we have to do, which is all documented here for now. As I see that we have a beautiful table. Unless when you do this and you display the coloring, I will add it also to their code of this lecture. But first, I want you to do it as an homework and post your assignment on the code repository or on the codebase of the homework which I will attach after this lecture. 103. ESLint Fixes: Okay, In this section, we created a lot of code and we wrote many things. So I'm sure we did also many mistakes. So let's fix them using Eastland. Eastland, as you remember, is extension which we installed on Visual Studio Code and which comes by default configuration with the NX. So here, as you remember, we have a prefix like admin and also some other rules which you can specify. So let's go through what we created. First of all, we have categories form. We are seeing that we are getting an error here, that this should be prefixes as admin. So let's fix that. So first we have this fixed, I have another arrow we have here that type boolean is Boolean. We define here a Boolean and we said again that it's Boolean, it's not good way. So in ES lint is telling you only say that if it's Boolean or make it equal to a Boolean value. So here we have now that only false, then the code or the compiler will know automatically that this is a boolean variable. So let's check here the other code, as you see here, that we have also some mistakes like this response is declared but it's never read. So I don't want to use a response when I create a category, unless, if I say, for example, category and then name is created. So for example, I can use this response. For example, I rename it like a category because when we create a category, it's responding for me the backend with that category. So in this way, I have to say, for example, that type of that category. And then I say that he had category, I remove this part, use backticks at here, replace it with backticks. And I say that category, this category dot name is created. So when I replace that and go to the code, create a new category. I say, for example, PlayStation. And then the icon is, for example, play or something else. So at I select a color, then I will see that the notification would say category PlayStation is created. So exactly the way how you want here. And also for example here I don't use the variable, so simply you can just remove it to keep your easiest lane thing is clear at your code is clear. Also the arrowed if you don't want to mention the error, okay, So just delete that. We don't need you. The same thing for that is because you can also with the update category, you can do the same here. For example, I will delete it. And also here, I don't need that done. So we don't need it also the error. So as you see now we have a clean code, four categories, four components in the HTML. I don't think we have any issue. Everything is clear and find in categories list also. We have also something in the HTML. No, we don't have, we have regard to their list. Okay, we have here some error that this prefix should be admin, should be blue bits. And also, again, we need to remove these unused variables. For example, here, the confirmation dialog says that okay, when I accept, I do something, when I reject, then I don't to anything, so it's better to remove it. Okay, What we created as well in the app module, let's see if we have any problems. Okay, We don't have any problem here. Also, we worked on the category service as you remember. So here we had also created some staff, as we will see in the next lecture, we need to replace this with 100 variable, because as you see, we are repeating the same URL in every core. So here we need also to refactor that. Here it's giving me an object is say, don't use object as a type. So I made a mistake here because object means any non knowledge value. So in this case, I would say for the example, let's erase it. For example, Delete category, it will give me an object in return. So I say any, so you can specify any for that type. So you can expect any response from the backend. So why do we save that? Okay, we don't have any linting issue, so everything is working fine now. We have a clean code. We don't have to bother ourselves with errors in the editor. In the next lecture, I am going to show you how to use environment variables. You remember that Angular comes always with environment variables, as we will see in the next lecture. 104. Products List Table: Okay, now in this lecture we are going to build the product table. So as you remember, we are creating the component and then we are filling the template, and then we call the services. So let's first create two components. One for the products list and the other for the products for. So as we do always, we go to generate in the NX console and we search for component as always. And then I will give it a name. Where is the path is Pages and then products, and then products list. And the project is admin. And again, we don't need any styling with it because we have public style. And also we have also to import or skip that tests. So that's it. And we check if everything is fine. Okay, It's going Admin, app pages, products, product list, and the component. We run it. And we create another component for what? For the form. So we have forum and list exactly like the categories. So we click on run. And we will see in our file list that we have two components in you, which our products form and product list. And they are listed under the pages. So as I told you in the beginning of this section in the article, I wrote that I am going to do the same with categories, so we don't have to repeat the same code. Bring the table exactly how we did with categories. We can just copy it and you can then adjust this table to fit on the product. For example, we go to the categories list and we copy the content of it. So I will get all of them here. And then I will paste that in the product list component where it's empty now because it's in you. And then we would get some errors. We can fix them based off our need, and then we can display the data of the products. This would be a faster way. I want to show you how to reuse the code and how you can implement reusable things. And as I told you at the beginning of this section, we are going to implement the new things such as categories. How we can do a select categories, and also how to image upload of the product. And also how we can have a reach textbox HTML editor for description of the product. So we can focus on the new things and the previous things which we did before. We can only copy paste them. So as you see here that we have to start on the toast, okay, that those two will stay the same, which is displaying confirmation messages about deleting or editing. And here we need to have the title to be a product. And here list of all products. And again, we need to replace. We have a button which is a new, okay, we don't need anything here. And also we need to replace these categories variable, which would be defined in the constructor before the constructor here. So I can say a variable which is called product, and this product is only an empty array for now. So we can save that. And we go again to the HTML template and then we need to replace those columns. So for example, at the beginning we have the product name, if you remember. And we need as well an image if you remember that in our back-end. And then we need to have as well price so that it's sortable as well. So I need also to sort by price. So I need to have a sortable field here. And also we need to have a stock, like how many of this product in my internal stock or in my stock. So we can also replace those with stock. Then we need a column as well for that category. So we need here to have a category these products belong to. So we can have a category and we will see how we can connect categories with the products as we did in the back-end. And now we needed here in the front end to display the name of the category. If you remember, there was filled in the backend which is showing when this product is created. So we can say created at, so we know that this product in which time is created. And we can also sort based on that. We don't need to sort by image and this field or this column will be follow the action like the buttons of edit and delete. Okay, let's move on to the body. So here I have a product. I will show you how we can reduce this code at the end of this section as optional. So it's optional up to you if you want to refactor this HTML and reduced in this code. So you can't let it like this hard-coded the table. Some people doesn't like it. They like to use a loops here. So they can loop in some constant or some columns which are configured EHR already. And then they can replace or place their columns based on that array. So what here now we are hard coding things. In the future, we will see how we can refactor that as optional. So for now, I can duplicate all of this. I need here product name. So we can have here product name, product, as we said image. We can have as well a product, product price. So we have here as well price. And we can have a stock, how much in the content or count in stock. So remember, this field must be exactly the same which we created in the database. So if we go to the postman, if you remember, if I go here and I want to show you when I list the products, so I get the products here. We have here a rich description, image and the brand and also price rating reviews is featured, name description, you remember? So here we have also some count in stock. So this what we need which is called count is dock. So these fields should be exactly the same which we are using in the front end. So to not have a conflict of code, you can use different name, but let's keep things consistent and more stable between the front-end and the back-end. So then I need a count in stock and also we need the contiguity. And here we will have also issue. We will show it later because as you see here that we are okay getting that category. But the category is object. So inside that we can say category then name. But I want to keep it like this now just to focus on it and to show you how it's really exactly coming from the database. So now we need a product category and at the end we need a column for created at. So we have say here, created at. And it should be exactly the same field, exactly how it's here. So it's not created at its date, created. So we have to put the same thing here, other things we don't need so we can delete them. We need also to delete this part. We don't need color, but the buttons, we need to keep them just we replace the methods so we can say a product, did it product, and as well, we need to have update product. And here we don't have anymore category ID, but we have here a product ID. Other things are exactly the same. We don't have to do anything. Let's check our application unless we have to go to app module, I will show you why. So we go to our application again and click on products. We see that we don't have any route matching the products, so we need to add routes the same way. We have three routes, four categories, categories form categories, form ID for editing the product or the category. The same thing exactly. We need to do the same, but we have to call IT products. And here products form. And again, a products form. And the component here which is automatically imported is product list component and products form. Let's move them up to be with that component part. And then we can use them in the application down. So we can't have here products list. And also we need to have here categories or products form component. So we have here products form component. Everything is fine. We save, we go to the application, we don't have any error. We check here products, okay, we have now everything and all columns. But we have empty data because we had empty array. So what we need to do now is just checking and grabbing the data which we saw previously in the Postman and place them in our table and see how we can create the service Exactly. Also like the goodies and create the model of the product. 105. Products Service and Get Products From the Database: Okay, in this lecture we are going to fill the table which we built in the previous lecture with the data. So as we see here that we have the data comes from the database and also from the backend with some fields for all products, like list of products. And this is the API which we had already. So first of all, we need to fill this array of products, exactly how we did with categories. So first we need to have a service. I think the service, we can also place it in the products library as we did with categories, so we can hear the same. We can also have the category service, but we can replace it and rename it to product service. So we have here products. And then I will have here the file which is called product services.js. And then I want to have to export it to the modules or to the module itself of the library. So we can have here a products and we need as well to have a model. So the model will be exactly as the fields of the product. So I am going to fill them fast to not waste sometime. So we can have here a product's file. We can call this also a product. And I am going to fill all of this information exactly how we have them in the backend. So I would like as well to keep this same naming of the fields which comes from the backend to keep everything consistent and don't have conflict with their back-end developer. So we have here the name, like a string description is a string. Description is also string, as we saw in the backend, image, will be a string which will be the main image of the product. Images, which will be the least of the images of the product, which are like for example, we will use them for a gallery as we will see in the future. Also a brand which will be again string. And the price is, should be here. A number, not as a string. Category will be type of category. So I imported here that category from the category model and I placed this category as category. So count in stop will be a number and also a rating will be number. Number of reviews is featured. So we can display the product in the homepage or not, and it will be a Boolean. And then the date created, which will be a string date. And also here we need to import it or export it. So we need to export this model so we can see it in other places of our project. So we can heave as well products. So we will have product and as well category. But here we have to rename it not products, but product because we are giving a class only for one product. So we will have here a product and category. So now we will go to the service and we rename everything. So first we need to have products here. And as well, it will be the same URL because we are saying the same URL for the back end. And also here we will have a products for the prefix or suffix of this URL. And then let's comment out all of the stuff so we can start one by one. So what we need now, we have products, so let's make, get products. And it will be exactly the same, but what it were returned array of products which were not to return for us only categories, but it will return a products. So we have here a product and the product. And then we don't need these categories so we can remove it because it's not used anymore. Okay, so now our service is ready. We just need to go to the application level and then we can use this service. So I will go here to the application, to the product list. And as you remember, we did that also in categories. So let's do that quickly. First, I need to call product service. So I will say here product or private product service, which will be from type products service, as you see, it's already known, so and it's imported from the workspace and the name we have here a problem, It's ES lint issue, so we need to call this as admin and then we create a method. We can call it this dot get products. And we are going to implement this method. So I go down, say private, underscore get products. And in this good products, I will say this dot product service that gets products as we saw previously, and then subscribe to this library or to this observable as we saw. And then the products will return in the call back of the subscribe. And then I can say this dot products, the variable which I defined here will be as well from products. So I am aside ink, this product to the products which returned from the backend. So after that, Let's save it and tried to update our application. And we see that we got the whole data which we need. Okay, not everything is perfect, but let's go one by one. Okay, The name is fine. The image, we need to replace the image. As we will see in the next lecture, the price is okay, fine. Stock, the number in stock is okay. Both category is object. So we need to find a way why it's coming like that. So if you want to know what is returning from the back-end, in the front end, you don't have ability to use postman, then you can go to network and check your calls. So for example, here I have called the category or products. So products, I got all the products. Here. I go here again, and I see that category is, object, is not like one field. And this category, as we remember, we made population for this one. So here we have category and then their name. So in the HTML of our application or of the template itself, we have to say that we are not going to have the category only but category dot name. So that's why I am telling you to keep this same typing. Now, I can't see category dot name and I don't have any mistake or any error. And as we see here, that category came exactly as we want. Okay, What about the date? The date, as we see here, is formatted from the format which comes from the database. To fix this format, we can use something in Angular called the pipe. And this pipe, if you use it, our search for it in Angular library, you will see how we use it. So if you go down, you can see the options or the example how we can use that. You have to provide a date string and then or object. And then you say This sign and then date, and then you specify the option. There are a lot of options for formatting the dates in Angular, so all of them are listed here. Or you can also use one of these 3D formats like long day, full day, short-time, medium time. There are a lot of options for me. I am going to use this one which is called chart. So how we can use that? So we can go here and then we put this column and then we can say, and I want to have a date with short format. And after we save and try that in our application, okay, the date format games, really perfect. Okay, so in that way, we have formatted the date. The next lecture. It will be, as I told you, we will show the image which is coming here from the back-end. So see you in the next lecture how to implement this image. 106. Show the Product Image in the Table: It's very helpful that the user can see as well the image of their product in the table. So it's very simple how we can do that. If we go to the fields, you remember that we have the header image and then we are grabbing the data of the image. And the image comes as you are L, as we saw how it comes from the backend. And if we want to have an image here, we just replace this part here with image. And this image will have source and also alternation when it cannot be displayed. So if we want to use the product image, we just need to do that and place the product image inside here. So it will work. But I prefer always two chain that so you don't need to use those brackets here. So you don't need to use those brackets, so you can replace that with brackets like this. So this will be like to binding way or two way binding in Angular. So it will say that the input of the image or the image will be a source and it will accept variables. So it will accept angular variables, not, for example, strengths, as we know in the normal HTML. So here we have the product image. When we save, then we will see that we get the images. But as we see here, they are very big because they are not styled in the right way. So what we can do, you can also create some nails. So you can upload small images. So you need in the back end to create a field which is called thumbnail. Or you can do as well here, resizing by style. So you just go here and say style. For example, it will have a width which will be 100%. So I'm going with this way, which is a very simple, of course. You can also upload a small images where there's some nails with a fixed sizes and you will see them how it looked like right here. So for example, I have this product with very high, So I need to keep it in that way. But you can also create a square images. So this is just an example for you. You can do whatever you feel and perfect for you, for your table display. 107. Build Products Form Template: Okay, in this lecture we are going to see how we can create the form for adding a product. So if you remember we had the same category, we are clicking on you, then we are going to the form of categories and which will be here form for adding a product. So we can't use the same thing. We can start as a template from categories form. So we can copy this one, the categories form and pasted in products form as well. But we will need a different field. We will fix all the errors which we get here. And also we will use a new controls such as a switch, such as a rich text box, text area and selector. This is exactly how you saw in the demo at the beginning of the admin panel sections. So we would have the same toast which will be the conformation for adding product or updating a product. And as well here we are going to have a guard. And the guard will have a header, and this header will be here, product. And as well here our product. And here we have products as well. So I am going to make it like a quick because we have explained everything in the categories. So we had here as well the edit mode. So we need to define a variable which is called Edit mode. And this edit mode will have, for example, at the beginning of false value, we have a toolbar and the toolbar will have as well, left and right. It will have as well the edit mode, update or create one button for onsubmit and one button for on cancel. Exactly the same how we did with categories. Okay, we come now to the serious work. Where is, for example, the form group? So I need to define as well, a former group in this component, as we did with categories. In this case, we need to define another variable or another class member, which is called form. And this form will have a type of form group. And to build this form group, we need to use a service which is called form builder. So we will have a private here, and private will be a form builder. And this form builder is from the type form builder. And here we can have a private method. We can define it. So we can see these dots in it form for example, we didn't do that in the category, but I am showing you how to get advanced step-by-step. So here we are putting everything in and g on any, like when initializing the component. When I click on Add New, then this component will be initialized. So I am doing here the form, but now I am making it more understandable. So I will group it in one method and put it which is called in it the form. So we have to define a private method which is called in its form. And inside this init form, we need to have to build the form itself. So I would say this dot form builder dot group. And then we will start to build our group. Then we have here to say that this form is equal to the group which we are going to build now. So this group members will be exactly the same of the fields of the product itself. So as you remember, we had a name, we have the price, we had, for example, category, we had as well, image and images. I'm going to list them, all of them here and then we will explain them fast. So I don't want to type to not have wasting time for you. Okay, so as you see here, we have the name which is required and also brand is also required. Also the price is also required thing category itself, which will be coming also from the backend or how we can post it in the back-end. And it will be a selector, like a list you can select through it and search for a category, as we will see later. And count in stock description, rich description which is not required image. I think we can make it now for as an author required and also is featured. We can put it as well, not required. So in the same time, we need to build those items or this form controls in the template. So from the category we had already name, for example, but we don't need icon, we don't need color. We need to replace them with the right components. So for example, name would be stay the same and also brand. It will be as well a text input and we can replace that as well. So we can say brand here and also a brand here. And as well we can have here everything as a brand. And here we need to create like, for example, the shortcut as we talked about it previously. So we can do that like this. We say get product form and this dot form dot controls. And then we will have here, not getting good is four, but products form. So this is like our template, so we have to use that template every time we create. And uniform. I explained everything in detail, how we created every step of that form in the categories section, okay, we place this with a brand and as well, we need a price. So afford price, it will not be a textbox, it will be an important number. So an input number, as you see here, we can use something called input number. And this input number from Prime NG is so great. It's giving you a lot, a lot, a lot of options. I'm going to use this one which is called without grouping. So first we need to import the module. As always, I go to the app module, import the module of input number, and then place it here again in our u x modules. And then we can use or uses examples, so we can say source. And if we go sort, we will see without a grouping, so we need to use this one. So back to our template. We will not need a color, but we will need here a price. So, and as we agreed before, we are not going to use ng-model like two way binding like input and output in the same time? No, because we having here a form control and then this one will be a form control name for it will be a price and the label will be a price here. Well here price and we need as well price here. So when we go and check it, we will see that everything is correct. And it has here something called input ID. We can copy it and make it as a price as well. And this field is required. So we need also to add some validation notice to the user when he put or he doesn't put any value inside it. So we will say this product form dot price invalid and is submitted, then show me error that price is required. Also this is submitted variable. We can define it also in the component. So we say here is submitted at the beginning is a false. So let's see now what we have in the front end. So after saving everything, I go to the front and again, I will see that ad product. I have you create button, Cancel button. We have name-brand and price. And as you see here, the user cannot put any letters, but he can only put a numbers. So here we need to have a category, category. I prefer to use the list, as I will show you later, a drop-down and this dropdown, It's also comes as component filter, as we will see in the next lecture. Let's feel the simple ones. So I will add also the count is tok and description. So count in stock will be again a number. And this number will be lei, not near them. It will be in a new line. So I put affair as well to create a new grid which will be under this part. So as you see here, we have all of them grouped in this grid. But we can now create a new one, like a new row. And this row, because this form fields. So we can copy that same offer, the price and we say the count in stock. So I replaced them here. So we have now count in stock for everything, and everything is defined as input number. So when we refresh, we will see that our component gets refreshed with a cult in stock, but it's full. So we can also define a small, small lining. So we can say here I want only column 4. So I need to have this as a form columns as we see here. But as well, you can define a noodle in different way. So you don't have to create a grid, but you can say as well that I can also have a column, but it will be at wealth. You can have here four and 12, but when it doesn't fit, it will go automatically to a new line. You see here. And it's like we defined a new row. So this what I will do with a description. So we will have here 12 columns, four columns for the cult is talk. And as well, we will have here near it for the categories. So we can feel that as well, but we will not use input number four categories. We would use the dropdown as we will see in the next lecture. So we can rename this part as category and leave it as empty as you see here, I replaced everything as category. We would put here the input of the category or the drop down in cell, as we will see in the next lecture. And as well here I have a description and description will be a text area, and we can add also that. So let's be sure that everything is fine. We have your name, brand prize count is still category empty. We will feel with their category and then we have a description. And the description will be a text area. And this text area, we can also find it. So when I go to input text area, we will see input text area module. We can import it as well and place it here with our modules. And we have here the UX modules as well, and we import it. And then we will see the options of. So here we have a flow label. No, we don't need that, although the size, we can use the default one. So I can say maybe we can use this one. Go back to our template and place the description here. And we give it a name like a form control name, as we do always to not miss that. So we have here the text area form control name will be the description itself. So we save that, go to our application. We will see that we have a description. Here we have the description. You can also define height for it. For example, this is like small. You can make it bigger. I think Prime NG provide that as you see here, we have a rows and columns. So you can also define that. So we can add that two rows and description we can make grows like seven. So we save. And we'll go back to the application. Nice. We have here the rows, and after that we will have a reach description. Reach description, we will explain it also ends separated lecture because it's a beak. We can add here also is featured field. So if you remember, we can use is featured flag. So we can use as well a switch, and this is located here is called input switch. So we can define our product if it's featured or not. So we can also import that module. Go here, import the module as well, and go import switch. Then we can place this here. And then we can use the input switch inputs, which will be exactly the same and this one. So we will have a new row. We can add it after category, like near their category. So we can add it here. So we have here that category we have as well another peform columns. We have here, four columns and replace everything with its features. So we need to specify that is featured is required so we don't need the validation. It will be enough like that. And then we have the control itself. We can copy it and then place it here. So we have here the input switch, and we can remove this NG model because we are using the form control name. You always, you need to check if this support that. So exactly its support form control name for our component because we have building these controls inside a group and you cannot use ng-model inside form group, otherwise you will get error. So it's better to use a form control name in this case for reactive or directive forms. So let's check that f is everything wanting. Nice. We have here is featured name, brand, and description. In the next lecture, I will show you how we can grab categories and how we will grab the data from the database as well. So we will see here the real categories which are listed here. 108. Dropdown for Product Categories with Filter: Okay, in this lecture we are going to see how to create the category dropdown with a filter. So I can filter and select the categories which I want and which are stored in my database. First of all, we need to have a drop-down component. It's available as well in prime NG as a prop down if you see it here. And then you will have many examples. Let's select the simplest example. But first we need to import the module of dropped down first. So we go here and import the drop-down module and then add it to our code. I have done that already so we can move on and go to example. So we have here a p dropdown options. And some cities, like cities will come like from the backend. And our back end will be their categories itself. So let's copy this part and go here and paste it inside our label. So we have here created already that category, and we have here their category is required and then we paste it here, but we don't have here options or cities. We have categories. So that list of categories will be placed in the input, which is called options. So that drop-down accept input called options, which will be the data which will be filled in the dropped out. And also the model. We don't need NG model, as we said previously, we need just to have Form Control name. This form control name will be category. So as we see here in this example that he defined a variable called cities. And the cities has array, our array which is name and code. And of course you can define any object or any structural you want. So we are going to do that first. Let's define the category which will be categories array. Let's define categories which will be an array. So for now it will be an empty array. And as he done here, we have at cities like an array hard-coded, but we will grab it from the database. For that, we need the category service which we created previously, and we have a method there which is called getCategories. So first, after that, after re-initialize the form, we say this dot get categories. So we will get all categories from the database and display them for the user to see which one is right for him. So we have here a private method. We call it a getCategories. And here we are going to use the category service. So we need as well to call the category service. So we say here private categories service. And this category service will be type of categories service, which is defined here already. So we can import it automatically. So here we have category service, and then we will say this dot category service dot gets categories. And then as you remember, we have here as a subscriber, so we can subscribe to it. And then we will get in the callback the categories. And then we opened and a function. And then we say this dot categories will be categories. So we loaded the categories array here. Then we will say that categories array got field. So let's save everything and try that. We will see that really, we got all the list. So everything is fine, is working Perfect. So we have here now the categories which we already created, and then we have them when we create a new category so the user can select among them. But let's add more feature like we can add a filter so the user, if has a long list here, doesn't have to search manually for it, he can type something and he will get the filtered data. So we can't do that very easily as we see in the example that he has here, something like for filtering. And one of them is filtering and clear icon. So the difference of this that he added option and another input for that filtering, which is called filter through. And he said that filtered through then filter by name. So he can filter as well by something. You can filter by name, by ID. So the user will, when he typed something, the data will be filtered by that value. And as well, he has created a place holder. We can as well copy it. So first we can copy this part and go to our products form and add these properties. So we have here auctions form control name and he filtered is through filter by name and then show clear through placeholder select category. So let's save that, try it out. And then we open, nice, we have the filter ready. So we have here for mobile, I want cars. So you see that we get the results immediately. 109. HTML Editor for Product Detailed Description: Sometimes we need to show to the user some detailed and freedom to create his product detail. As we see here that we can also with Prime NG, find out some editor which is called reached duct box editor. This reached Xbox editor. You can also style to your text. So for example, I want to have headings. I want as well to have underlying text so we can give the user the ability to color and do many things in the text and the detail description of the product. Otherwise, we will end up to Add Field for every special part or chew the user has to enter. But now we can give the freedom to the user with this great reach textbox. So let's add it to our product form and see how to work with it. So when we go to the documentation of this editor, we scroll down as well. We need to have an editor module. And this editor module we go and imported in application module as we do always for every module in prime energy. And then after we do that, we need to import or use a component which is called editor. And here the text, which will be as HTML and a style if you have some specific style for it. And then you return that text in your backend or to your API when you submit a new product. But the one which we want is not with any model, but with form control name, as I told you, we are using reactive forms. So we go here again to our form. We will create a new field and new live. We will give it a class. And this class will be also 12 columns with a label and will be the editor inside it. So I created that already here. So we have here a rich description as exactly how we have defined it here in the form. And also we have the editor itself and the Form Control name will be reached description. And I created a label which is called product details. So when we save that and we go to our application and we will see that we are missing something because we will see that this part is not working for our application. First, it has a dependency which is called a quill. And here is a great chance for us to see how we can include external libraries, JavaScript libraries to Angular application. So if you go down here to the documentation at the end, you will see that this is a dependency. Quill editor is an editor which you can install with npm install, and then you need to import it. So first we go and install this part. So we go, we open a new terminal and then we say npm install Quill safe. And after it had successfully installed, we need to import the libraries. So first we need to import script in Angular JSON file. If you remember, we have an angular JSON file which we are configuring the applications inside it. So we are going to configure admin obligation, not other applications, but only admin application in scripts. We can add this line. We don't have to go to step up because we have the node module in the same level of Angular JSON. So we don't have to go up a level or inside some folder. And as well, there are two styles file we need also to import them. So here, after we have the styles, after that styles, we can import this core CSS and as well the other one which is called Snow CSS. So after we have saved all of the things that changes were not take effect until you restart your application. We need to restart the server because we have angular JSON changed. And here I am going to restart my application. Okay, it's restarted but still complaining about some arrows which we didn't fix previously. So let's fix them and make everything works. So we have a problem that this onsubmit and onCreate or own counsel are not defined, so we need to define them. So I will copy this part, go to the component itself, component code. And I will say on submit one. And as well we have on cancel. So we define both methods. We don't have errors anymore. Then we go back to our application. We check how we have, how they're each editor. It's very great. We have now everything. You can type, everything you want. So you can have it's styled in their front end already as a user, exactly have it to the front end. So we will see later how we can display this HTML in the front end application in any shop. So the user has freedom to type what he wants here. And then we will see later how we can display this HTML which is displayed here, or which the user used in the product detail. 110. Product Image Upload Field with Thumbnail Display: In this course, and for the product, we have two type of images. First, the main image, where it will display the product image. And as well, we have a gallery. The gallery where they user when he go to product detail, he can't see multiple images of the product. So first we are going to create now the main image. And not only this, we will see also a display. When the user upload an image, it will say a small display. The image which he uploaded to make sure that everything is uploaded fine for the image upload, we are not going to use anything specific. We are going to use standard HTML. So first of all, I am going to have a div like this. It will be under the description as well. And here, inside this I will have as well a label and I will give it, for example, as a name, main image. And then we would have an input, and this input will be type of file. So we will have here a type which is called file. So I can upload files through this input. And for styling it, we will see how we can make it more beautiful. We will add some class and then we will say that this file type, it standard HTML, is accepting all the image. So we cannot accept any other file. We will accept only images. Okay, well, let's save and try what we have here. So after the application gets updated, we will see that we have a field here. But look, it's ugly. It doesn't have these main image and you know, like the label is not on the top and the file upload will be here. So I would advise you to add a class for that input, which is called input text. I got that from by inspecting on prime M and G inputs. And I got this class. So here we have p input text when you save, it will have more lifestyle. It would be located exactly under the label and everything will be fine. Okay, nice. So we are going to implement the upload. So when I select some image from my computer, then I need to have some display here that after I upload the image, it would be displayed here. So how we can do that, okay, first of all, we need to detect the image or the file which is uploaded. So I will say here that when I change this one, this field GF change, then I will have a method which is called on image upload, for example. And this image upload will pass for me the data of the file which I uploaded through a valuable add specific variable, which is called event. And you must put these dollar behind it. Then you would get the data in the right way of the image. So we can implement this method. We go to the TypeScript file and then we will say that here we have on image upload and this will have event as we saw. And then we are going to have the file itself and displayed in ASAM veil, the thumbnail itself. It will be under this, for example, under this input, we will have like a div, as always like small div. This div will have inside it and image. So we can have here a div, and inside this div we have image. And the source of this image will be the image which we uploaded. So we need to fill a variable which is called image display for example. And this will be as input for the image. So we must put it in brackets. So we need to define a variable which is called image display, which will grab the data of the file which we uploaded and place them inside this image. So let's do that. We define one variable, and this variable can be a string or a type which is called array buffer. And I will tell you later what is array buffer and why we have that. By the way, let's fix this linting we have here must have it as admin because we cannot name it like this. So we have admin products form. Okay, and then on image upload when this event happened, I would receive a file from the event, and this file will be defined. I will get it from the event. So here we have, for example, event. But let's see first what event is returning for me. So when I go here, I may console log. I want always to track the things I need to understand why I am going to do the things. So let's save that and go to our application and try to upload one image. So we have here one image, I have it in my PC, and then I will see that event comes with a lot of properties. And those properties which I need exactly is God good. And then something called files. And these files would contain my file which I uploaded. So let's go back. We can remove this. We don't need it anymore. We can then define a constant as we saw a file. And this constant will have event dot target. And then these target, as we saw that it has also inside it files. And these files, we need to grab only the first element because it's coming always with array. And we need to grab only the first element of that array, as we saw here. So here it has a ray and we need only the first element. So as always, if there is something inside the file, then we need to do something. If not, then we do nothing. So we have to make sure that the file, we got it right. Then we need to put the file content inside our variable, which is called image preview as a data. So how we can read these data in JavaScript, there is something called FileReader. And this file reader, we can read data through it. So we can create a new class of FileReader. And this file reader through it, I can read always the data which I want. So how we can read, we can say file reader, read as data URL, and then you pass the file which you want. So we have here uploaded the file, we got it. Then we create a FileReader and find reader has read as data URL, the file itself. Now I have that file itself as a data inside the file reader. How we can say something like this dot image preview or image display will have the data itself. So this FileReader come always with a method which is called onload. So when we load our data to this file reader, do something and this, we can define it. It has a callback, but in different way, it has a method. And then this callback, you call it like this. And inside this method, you can do what you want. It's event. So we can't do this dot image display and then FileReader dot result. And inside this result we will have our file data. So with this way, you can always read the file as a data, put them in some variable and pass them to the image input or the image HTML tag. Sometimes if you put this after you are reading the data or the FileReader, it will not work. So it's better to put it before it. Then the event will be executed after you read the data because it will know that there is something on lot because it's event and it must be defined before reading the data. So let's save that and try it. We can maybe try now to upload some file. So I go here again to my file. I select a file which I have already. As you see here, I got 0 is undefined. Why? Because I have here issue. It's file's not file. So it must be filed as you remember, our array. So I had a mistake here and I fixed it. Let's upload again the file. We go back here, we will see, great, we have the image is uploaded. So as a recap, quick recap, I uploaded the file. I created a FileReader, which is coming standard JavaScript. Let's web application read the contents of the files. So here I loaded the file, which I uploaded to the FileReader and then I assign it to the image display. But as you see, it's a big image. So maybe if I upload bigger image, it will take bigger than the space. So let's limit this image. So I would go here, maybe I can do some stuff using my experience in prime energy. I will give it, for example, this a class. And this class will be called P column, for example, to two columns. And this image will have style, which will be like width 100%. So it would be 100% of its parent. So let's save that. Go back again to our application. And then we try upload their file. Again. We go here. Guys, we have a very nice, so let's put some space between the image and the inputField because it's ugly like this. As you remember the, our classes, prime end classes, we can have margin, bottom, margin, top. So we can do whatever we want about the margin. So I want to put margin top two. And also if you notice that there is, because we use this column, it has some padding. So we can make also P padding left 0 for example. So here we can save it and then we try it out again. We upload a file and we see if everything worked fine. Perfect. We have now with the file and we are ready to submit this file to the backend, and then it will be uploaded through our back-end API. In the next lecture, we will see how to submit all of this data to create a product in the database. 111. Submit a New Product as FormData: Okay, in this lecture, we are going to see how to post a new product or add a product to the database. So if you remember, we have created the form, then we are going to do a Create. Here the things are a bit different from category. Why? Because we are not going to post the data as JSON. We are going to post them as a form data, as we will see now, this is because we have a files which is the image. So we must post the data as a form datatype, not as a JSON. Because if you remember, when we were working on the backend, I was showing you that we are posting or putting a product in the database, but with form that the format not with the JSON like the others. So in that way, you will be able to upload images with your form data. So let's move on. Then. When we create, when we click on this Create, we are going to build our form data. So let's go here and we have the method already, we defined it, which is onsubmit. I'm going to see if I have first the valid form. So I say if this dot form, like the form group which I have is invalid, then return. Don't do anything otherwise. After this return, we are going to build the form data, but before that, we need to validate the field. So after that, if you remember, we had created this notifications for the user to see if he has some errors or mistakes in the fields. So based on this required fields which we defined here, we build our notifications here. So we need to activate those, not vacation. So first of all, we need to say is submitted is true. So when I click on Submit, I have to say that the form submitted is true. So yes, it's submitted. So exactly like how we did with category. So after we save that, we try again and then we, I tried to click on Create. So after that, I will get the validation errors as you see here. Now we've, we will feel this data and receive them and send them to the back-end. So how we can receive with this data as a form data? First of all, we need to define a constant which is called product form data and is a type is formed that form data gums with a basic JavaScript in the browser. So it's not a library. We don't have to import anything. It's inside the JavaScript which we are using now, then this form data, we are going to pass them to the service, which will be at a product, and then we will send it to the back-end. But how we can fill this form that our first, So I need to move the data which I input here in the inputs to products form data. We just say product form data dot append. Then I specify the key which I want to append, and then the value of it. For example, I will say name and then I will say the control name. So I will say this dot products form, which is already we have seen is this got form controls dot name, dot value. So in this case, I have specified an append name to this value. Remember that this name must be exactly how we specify in the back-end. So exactly the fields which we specified here as well. And you do the same for all the fields. So like this, you have to do a brand and category and et cetera. But I think it's better to make it in a loop, especially if we have multiple fields. So I would say here maybe I can say for every control which I have here, do this key and the value of it, we just say object dot keys. It mean like give me the keys, not the values of this. The products form. Product form has multiple controls and I want to take the keys of them. And then I was say, map them, like go through all of them. And then i 2 will give me back the key. So as we said, because we are going over the keys, which we are here. So then after I get the key, we can do what this append for that. But first, let's console log to see what is going on here to make it clear for you. So I will say console log the key itself, and then console log for me this dot product form. And then I specify the key which I want, and then I get the value of it. It's exactly how we said here, like this dot-product form, dot name, dot value, exactly the same. So here it has an array and then I am going to read them. So it must print for me now that key, like name and the value, and all of them. So unlike for category, for brand, etc, I go back to the application. I feel some that are like product one we can say. And then the brand is Brian Guan. And the price is, for example, 500 and the count in stock is 20. And the category will be, for example, beauty is featured No. And then we have, for example, some description and another detailed description, and we have an image. So I'm going to upload one image randomly. We have it here. Then I will click on create. When I click on that and we see that we got the data exactly. So I have named Product 1 and then brand, brand one. Price is 500, category is category all of this because we are returning the object all of it and as well count in stock 20. So it's exactly how we needed. So how we can append those who just go through, we say product form, data dot append. And then we say that key. So I need a key, as we said previously. And then these dot-product form. And then I say the key itself, dot value. So go all over products form and then submit the value of the field. Then we say this dot, we can define a method which is called add a product. Exactly how we did with category, but these ones will accept, accept the products form data after we got upended everything inside it. So let's define this method. It would be exactly the same one which we defined four categories. It will be exactly like we will use product service, ad product, and then I will use all of this property. I like the message service. So let's do that quickly. I defined at a product both odd, so we have it as add category, but we need at a product and this ad product will accept not product itself, not the product as a JSON file, but we'll accept form data. So we have to say here, product data will be type of form data and then I will use a product service. So we need to use also the product service to add the service which is creating a product. And then I pass the product data to it. So first we need to call the product service. So we have it here so we can say private service, product service. We go down again to our adding a product. So create product. We need to define this method. So I go again to our product service. So we have it here. So after we go that, so here we put this method again and uncommented and we say create product, not category. And here we have product data. And here it will accept form data. And then it will return for me observable of a product model because I will get the product itself. And here also a product, and it will be a post request, but here it will be the URL for products. Here we have the categories we need to fix that. So we have here for that product. And then I pass the product data to the post request. It's exactly how we did with a post man. Now, I am building a phone data and send them to the back-end with the HTTP post request. So let's save it. And then we continue in our front end here we have the category nor it will return for me a product. And this product, it will be a product. And then we have the product model. We need to import it again. And here we need a message service. And the message service, if you remember, it's also from Prime NG. We have used it to display messages like Notification Service, which is located in prime NG. And then we have now everything is fine. Now we need to define that. The I need to display the product name and then I have a timer to return back. After successful adding of the product, we import this, which is from Rx2. Yes, you specify time and then you wait until it's executed or past, then you go back to the list of products. And then we need to have here some fixes like product, like on the text of the messages. Here we have product is not created when we get error and we now only missing the location. So we go back here and call private method or private service, which is called location. And this location will come from location in Angular. So let's try that. And then I am going to fill again my data here. I have brand, I have brand one. And always keep your eye on the network here, so we will use that always. So when you want to know what is sending or what you are sending to the front end or to the backend. It's better to use the network because you will see clearly what you are sending to the backend here, 500, 23, and then we choose category and is featured. Yes, we can put it as is featured. And here description and here detailed description. And then I send an image. So after that, we submit, okay, it's bending and bending again. So we are getting error in the back and I guess, and here I open the bag and again for you to show you the error, it's saying cast object ID field value, object, Object, Path ID category. Because if you remember, we printed out in the console log that category and it gives us a category as object. So I need to pass only category dot ID. I don't want to pass the whole category. We can fix that issue very easily. So we can not only send the category itself to the front end or to the backend, all of it. We can send only a specific value or a specific field. Because if we go to the documentation Of dropped down, the drop-down itself, because you know that we are reading the value here from the drop-down. So the value of the category in the drop-down is giving the whole object of category which includes ID, name, color, icon. Now, we need only the ID. So we need to say somehow that please this control and give me only the ID which is specified here, not all object. If you go to drop down documentation in prime NG, we see that we have something input with those inputs, which is called option value. So you can define an option value or a key of the auction. So you can't say that, give me only these key here. So we can't use that also option value and specify it as optional label here. For example, the option labeled, I said, choose from the category object, the name only, and display it here. But what will be the value, the value of this option. So I can't say option value will be the ID, the ID of that category which I am receiving with categories. So after we save that and when we are posting data to the back-end, then we will see that the category is not object anymore. It will be as well ID. So when I select something here, I'm specifying only ID, not the category of objects, all of it. I am detailing this point just to avoid, if you get some error like this, then you can know how to solve it. So let's fill this form again and we are going to click on Submit. So I feel that data already. I am going to press on create. When I press grade, I say product is not created because I got an error. Let's check the network here. So you see that we are sending everything fine. I go here and I see the headers. The headers of the request will be a form data and everything seems to me fine. I have the name, brand price, category. Look, that category comes also only as ID count is talk description, reached description, everything is fine but the image field is empty. And the response is saying, no image in there request. So we need to have somehow the image also in the form data. So that's why we are using formed data. For that. I need to say to form that append for meat also image, but the upending of the image is different way from appending normal fields. It's not like this way. It's not like I say, append the key and the value of it. So the value of their key image is empty somehow, even we have defined it here. But the problem using Form Control image here, it will not give me the real data. It will give me only the path of the data. Because if I submit, again with this change, for example, I have here form control name, then you will see that the data are coming only the path of it. So I'm not sending the path. I wanted to send the data exactly how we got them and how we build them with the FileReader previously. So if you remember, when we image upload, when I click on image upload, then I created a file reader as we saw in the previous lecture. So we need to pass the file itself. So how we do that? It's very simple. We go on image upload. And I say that don't take the form control name value, so remove that. But we go here and say that the Form Control name value will be the file itself. So it will not be the file path, but it will be the file itself. So how we can do that? If this file, if there is a file, then this does form the form which we are building in the point group. We say patch value, like add a value, value on a key which is called image, and then paste the file. As you remember, we have here defined the image, but it's empty. But now we need to define it and patch this value to the form itself. And another thing like we need to validate that because we are posting a file which is only image. So we need to say that for this dot form dot get the image itself. And then we say update value and validity. So here we have to use this method just to confirm that everything is working fine. We are updating the value because after we patch it, we need to update the form itself. So we just get this value and updated as a file which we bust. I have filled the data again and I have also image here. So when I click on Create, I will see that also it's still pending. I'm getting another error because it's saying product validation is featured, gas to Boolean felt value, it's empty. So we need to make this feature by default false or true. So when it's like this, then we don't, we cannot send an empty value. We need to send a false value. So it's featured must be by default as a false. And then when we changed it, then we read the value of it. Let's try that again. After giving a default value to the ISB features, then we click on Create. We will see the product is created successfully. And if we go to our product list, we will see the product image was uploaded and it's already on the server. So it's on the server side, got uploaded successfully. So as a recap, we did exactly how we do with categories we are just doing is submitted, check to the form is invalid. We don't do anything when it's invalid, then we are sending the data as a form data, not as a JSON, how we did with category. And then we are building those form data. And then we are appending this data. Two products form data. And then we are creating a method which is called add a product, which is using the product service, create a product. And then based on that, it will give me a success message or failure message. The main issue which we faced here that the image field cannot be used as a form control name because it will return for me here only the path. It doesn't return the file itself. So what we did to solve that, we said on image upload when we did in the previous lecture, we said patch a value to the form which is called image. And the value of it of this form control will be the file itself. It will not be the path. Then to make the things get active, we need to call this field again and then say Update value and validity. And as well, we have to be careful with the default values here because sometimes when you don't send anything to the backend, odd when you send a wrong type, for example, is featured was empty here, so I was using empty string. And for the back end it's a problem because the backend expecting a Boolean value. So the default value of this is Richard will be a false unless we are changing it. So when I go here and change it, it will read the value as a Boolean because we are reading the values from onsubmit when I am submitting a method. So let's do now a quick refactoring. We just need to remove those console logs so we don't have to have a console log and our code, and we have our product created already in the product list. 112. Edit a Product: In this lecture, we are going to see how we can edit a product. Exactly how we did with category. If you remember, we are clicking on one of edit to category and then we can edit and update. We can do the same with the product. So when I click on this edit button, I can go again to the form and feel the data. So how we can do that? It's exactly like in categories. I went to product list. If you remember, we have the button for the edit and we just say update a product and I am passing the product ID which I want. And then implementation of this update product, it will be these router navigate by URL to the products form and then the product ID, because we have defined this route already as we saw here previously. So now when we click on the Edit, then we will go to Add product. But the problem that we have empty data, we didn't get the product itself filled already in those fields. So again, we need to specify the edit mode. And then we say when I have ID, then I prepare the edit mode and then I grab the data of the product from the database and then place them in the fields as we did with categories. So let's do that quickly. As you remember in the template we have defined and edit mode variable, and this variable is defined here. So we need to specify and check the edit mode as we did previously. So first of all, we need to create a method which is called Jack edit mode and click Edit mode. It will be a private method. So where I can check the edit mode and read the ID from the URL, exactly how we did with categories. So we need the route itself, that out service. We can grab it and put it in our services calls. So here we have the route which is activated route and hear from the route. I can't know what are the parameters are passed in the URL if there is an ID which is passed as we did previously, then said the edit mode to true. And then we are going to set the fields of the products by the product which we got from the back-end. So first we need to define also a current product ID. So because we need that, as you remember, so we have a current product ID which is defined here, will be a string, and then we need to create a surface to get one single product. So if we go again to the services, we go to the product service, we need to create a method which is called get a product. And as we did exactly again with a category, we can define that method. So we can just say that we have a good product, product ID, product here to call the product model. And as well here I am going to get the product. And here we need the API URL, and then I will pass the product ID. So here the service is ready. We go back to our form and then for checking the edit mode, we need to call the product service. So I say this dot product service and then get a product, one single product, and then subscribe to the product itself. And then I will get the product from the backend. And then for every field of those fields of product, we need to specify the value which we got from the back-end. So we can delete this part. So we need to say somehow like this dot-product form which we have already. And then I go field by field name and the set value. And then I set the value with the product which I got from the backend and the name. So let's do that for all of the fields quickly. So I go here first to the category, and then I set the value of the category which I got from the product. And as well, I have that brand. And then the price in stock is featured description and rich description. Let's save at the trie that we go to our front end, we select one product, for example, this one. And then I will see that all the fields are filled perfectly, but except the field of the image that we don't have a main image here, we cannot see it. This is because the pity view of the image, as you remember, it's stored in a variable which is called image display. And in the image display, I can specify the value of the image URL, which I am getting from the back-end. So we can do that very simply. We can say this dot image URL or the image display. It will be the product itself, that image. So here we have a path already comes from the backend and with the image display. Let's update that and check it. Okay, we see that we have the image is already selected and displayed here. And also if we see that we are missing the category, the category is not selected because it's still by default. The problem that if you remember, we have specified the category by ID. And when I am going to the network and check what I am getting category, I am getting it as object because a backend is sending me the whole category with the product. We need to specify as well the ID. So I will say category dot ID. So here I go and I say set product, category dot ID itself. We try that again and we will see that the category is already selected. So you see step-by-step, you have to check everything is working fine. And then we are going to do the Submit of the update by me. For example, when I change the price, I want to submit the update of the price to the back-end. So the button on Submit was already defined as we saw here, but we have only add a product. So we need somehow to do the same way how we did with categories form. We need to check the edit mode. It's really it is mode. Then do update product, not an ad product. And if it's not, then we add the product. So I have here if this dot edit mode, and then I will go and I say that, okay, Do for me the update, otherwise, do for me ad product. So we need to define another method which is called Edit Product or update product. So it will be also a private method. It will be updated product and then it will ask for the products form that again. So update product, it will be on the top here we have it as private underscore, update product. And then I will pass the product form data, which has as well dive off product form or form data itself. So here we need to pass as well to the update, a form that because what if the user has updated the image. So exactly how we did with update category. As you remember, we have created the update category service and then we created a message and a timer to go back to the product list. And then if there is a failure, we display a failure message. Let's also add the update method, which will be in this product service as well. So we go again to the product service. So as well we have the product update and then we have the product data itself observable. It will return for me the of the updated product and as well, we need to pass the ID, but here are the things a little bit different. We need to pass the ID and we have them inside a form data. You can also get our grab the ID itself from product data. But in my opinion, it's better to add another parameter to update product, which is will be the product ID. So I will add here also a product ID, which will be type a string. And then I go to the product form again. And on the update method, I will add, if you remember, this dot current product ID, which we defined previously, and we grab it injected on the edit mode. So if you remember, we have here that checking of edit mode and we have assigned the current Id of their product to current product ID. So now we have all the method is working fine. We need just to submit the data. Let's save that. If we go to one of our products, like the ones which we created previously, I will see here that, okay, I have the product name, product brand one. I update for example, is featured. And in the description I say updated description just to be sure that everything is fine. And then we are clicking on update. So let's update that. We will see that the product is updated and we went back again and we will see that the product is really got updated with the updated description. Okay, let's try to change the image as well. So I will see here that for example, I have one of the image like this one for example, I update and we will see that it's also got updated as we see here. 113. Dynamic Validation Image Field Is Not Required In Edit Mode: So that's why I made the main image is not required field at the beginning because I am here showing only image preview, but I am not loading the image again to the input file here. So when I submit an update, and as you saw in the back-end, we did already that we are checking the image. If there is imaged with that request, then okay, use it. But if not, then keep the old image. If the user didn't upload any image here. So this how we did it in the back-end and how we are handling it in the front end. But we have issue here that if the product, when I click on you, I create a new product. I am not showing to the user any validation error here. Like for example, when I click on Create, I'm just showing the product is not created, but I am not showing any validation error here we need to shore some validation error. But on update, this validation should not be appeared. In other words, I want on edit mode, this is not required field, but onCreate, I wanted to be a required field. How we can do that? First, let's make this field as required. And on the template itself, we copy one of these small descriptions or the small tags We have here, the image, upload image and after the image here, we can, for example, put a validation error. So I would say that product form, like if the user didn't patch any image, then invalid and is submitted, then display error, say image is required. But this will be shown only when there is error and there is no image uploaded before. So we want to show it as I told you on Create. So we back to the form itself and then we make these image field as required. So we go here, this set the validator to be a required. So when I go to the front end, I click Create, I will see, okay, The image is required. And this case, I cannot submit any product only when I have image inside it. So let's try that quickly. I have created here a product. I feel the form already and I also uploaded the image. So when I click on Create, I will see that the product is really created. But when there is no image, then I will get an error. That image is required as we saw previously. But what I want now when I go to the Edit mode, I don't want to have this field required when the user is updating a product. For example, I am updating this one. Click on Update, I will get error. Image is required because the user doesn't want to change the image. So he didn't upload anything, but the field itself is empty. The way to fix that, that I don't feel the image field again to make it not required because otherwise when I update, I will send back again the file and the file will get uploaded again. And I will have replicated files in the back-end there. Good way that on edit mode, I can remove these validation rule. Then I can say when there is ID and this ID, when I get the product, everything is fine. I go here and I say this dot product for that image itself. And then we say set validators again, and the validators will be null, like as we said here, we have okay validators, but this validators now are nothing empty array. And to make this work, if you remember, when we batched a value of the image, we need to check for update value and validity. So we can again call that to update and refresh this form field to take all the changes which has done there, we can this dot product form image and then again update value and validity. So when we say this one, then we will see that it got refreshed and then the validator will not be active anymore. So when I go here, I say year 2002, and I don't have anything in this field and it's not valid because I don't have any file here. But when I click on update, it would work and it will update the file. But when I go to a new product, then this field will be required. I cannot create a product only when I feel the field here. So on edit mode, we have required and will not edit mode, it's not required. You can do the same for all fields. This image was an example only. 114. Add Products Table Pagination: In this lecture we are going to see how to add originator to product list table. Adding paginate her in prime NG is very easy. It's only a property, you can add it and then the variable will have a pagination. So when we go to prime NG and then we go to table, there is a category called page. And here you will see how you can use the paginated is only additional property, which is called paginated or through. And then you can see how many rows you can show in every page you can show as well a report about the page. For example, this showing one to ten of a 100 entries and you can't have a template for it. So you can specify a text which you want to display inside this report. And also rows per page option, which is this one. You can show also options of how many rows you want to display in one page. Let's add that to our table. I'm going to add the paginated to our table. So I go here and say paginate is through rows are 10. So we save that. We go again to our application. It's loaded again. And we will see that we got the originator. You can add the other templates such as shore current report or if you want to have rows per page option. So it's up to you. For me. I'm feeling It's beautiful like that. 115. Users List Table and User Services: Okay, as we agreed in this course, that we are not going to repeat the things again and again. So previously we made the categories table and it will be for the users the same. So for that, I create a component which is called Users list. And this user's list component has exactly the same how we had in categories like the toast itself, how we have conformation about operations. And also admin page, I'm going just to replace those to be users and also here users. And then we have again the New button for adding a new user. And also we have the table that they will value, will be users and also their fields, which we know everything about the users and how we got them from the backend. For me, I will display in the table only the name, email and if he is admin or not, and the country. And we can make also those tables or those columns as sortable or not. And for that, we have the user, and the user has a name. Email is admin and country. And we have the button Delete User and update user. And for that, we have created the route which are already defined previously, has we did it categories and products. We have the users, which is referring to the user's list component and the form which is you failing to users from component. So for grabbing the data from the database as well, we have created the services for the user. So the user component, I have the user service and the user service. If we go to it, it will have users get user, create a user, update and delete exactly how we did previously with categories. And the API URL will be for users. And I put the service exactly in the user's library, not in products library because we are using now the user's library. So the user's library would have a folder which is called services. And inside the services we will have user services. And as well, I created a model of the user exactly how we have it in the back-end, like ID, name, password, email, phone, and token. If he has a token, as we will see later, is admin, Street, Apartment, zip code, city and country. And we go back to the user list component. As always, when NG on it, I say get not categories, but get users. And these users, we have them already in the back-end. So we have here at users and also get users. And then I will use the user services to get the users and their subscribed users. And this.userId is will be the users which we have defined as a member class, which is array of users. And then I use it in that table as a value. And we check the front end, we will see that the user's list came like that. So we have here the username, email is admin, and the country, it's empty here because in the database that country is empty as well. We will update them when we will do the edit in the same time I did as well, that delete, which will be also confirmation dialog, like do you want to delete the user? And then the user can select yes or no, and then it will execute the right decision. So here we have as well delete the user and we are executing this code when the user is clicking on Delete button add, when I go to the user's list, we are calling again the confirmation service. So we need to confirm if they users should be deleted or not. And then when they user accept that, then User Service, we'll be calling a delete user with the selected user ID. And then I refresh the list again by getting the users. And then the message service, which will show me the user is deleted or the user is been deleted. And remember that we imported the user, the user model, and the users from the use of the library. I would like to add one thing here that I don't want to display is admin true or false? We can, for example, display an icon or we can display something in prime end use is called tag. And tag, we can use one of those tags based on the state if he is admin or not. So for example, I will display this tag when the user is admin, and I will display this DAG with this icon when the user is not admin. So let's do that. We can also import the tag module to our app module. And when we go here, we use it in our UX module. And we can use the example which is coming with icons. So he used it in a way like if we go to source, we will see icons that he used p tag. And then he specified some margin and then he selected the icon and then severity will be success and the value will be success. We are not having a value here, so we will have only icon. So we can use this one dag and go to our user list component. And here it is, admin. We are not going to check that, but we will say that use this DAG and ng-if will show this tag or not based if the user is admin or not. So I would say user is admin. So if the user is admin, so make or show this badge or this tag. And as we said here, we don't need the value. So we can save it and check it in the front end lice, we will see that we have this tag already and we can also use the appeals like it's around it. So we can't say rounded is true. We can set this tag as a rounded borders, so we can add it here. We have a rounded through, so it has input which is called rounded. So we save. And again, when it's not admin, then I will display the danger one. And I say that the user is not admin. So here we have another P tag and I say MET ng-if not admin, and then the icon will be another icon and severity will be danger, like red and rounded through. So when we go again and we check the icon of the icon for it is times, so we can take it and place it here. We save the application and check if everything is working fine. So as you see here, we have then the admin coming with true or false flow from here, I will not if the admin has this icon, so he is admin. If not, then he is not added. So I'm showing you this because I want to see how we can render the values inside that all exactly how we want. So when you wanted to play icon, you can display it. If you want image, you can display image as we saw in product. And if you want to display something else like a component, you can do it as well as we see here in Admin. 116. Users Form Add and Edit: Okay, in this lecture, I am going through the user form. The user form I have created exactly also as categories, as I told you, because categories will be our reference. And from that we will have a template and use that template everywhere where we want. I will go quickly to not repeat the same things. But if you want everything in detail, how we created this form, you are going to check the categories for. So the categories form. I explained everything in detail how we are building this form. So exactly how we did with categories. You know that the user model we have created previously, it needs a name, password, email, and other stuff. And based on that, I created the four. So everything is the same. We have a toast for confirmation messages and also the header, the toolbar which contain the onsubmit and cancel if you want to see it here more in detail, I showed you. So as you see here, we have the update and cancel and it's changing when I'm clicking on you based on the edit mode. And now we have the name, email, and also the phone. And as well, we have here the admin is admin and the street, apartment and other stuff. Of course, there are new things I am going to show you how to do them. For example, we need, for example, to show how to validate the e-mail, which is a new thing, and also how we can grab that countries to countries drop down. Now I have it empty. I want to show you how we can grab the countries to our drop-down from a library. And in the component itself, I am going on energy on it. I am saying init, user phone, and indeed user form. As every form we are using form builder, we have the name which is required. The password is also required, but on update is not required because as you remember in the backend, how we did it, we did it in a way that if the user doesn't put any password on updating a user, then it will keep the previous password, which he has already. But when he put something here, then it will update the password based on that. So exactly how we did with the image of the product, if you remember, the same thing exactly, we are going to do with the user for a password will be required when I am going to have the new form. But it will not be required when I am editing a user. So here we must do and handle the thing with a password. So as we see here, we have it required by default, and then we will go to check edit mode as we see previously. And then I will say this dot user form, the password when I am on edit mode. So either it's MOD is through set validators, it will be as empty array of validators. And then we say this dot password, update value and validity. So as we see here, we have updated this field after we are checking the mode. So when I go back and try it out, so we go to users or knew it would be required. And on Edit, it will not be required. So we can update if it's not required. So based on that, I have created the form as well. We are going to have the e-mail. The e-mail itself is also required. But it's not only required. What if the user puts something wrong? Like what if put like this, then we need to tell him No, it's wrong. Email. We can do that very easily. It's also that is another validator, which is called email. So we have to put a new array, like we have multiple validators. So I will say required and also validator dot email. So in this case we will have two validators. But when we go back to our form again and try to click on you, then say, for example, an invalid email, something like this. It's not e-mail. When I click on Create, I will say I will see that there is email is required. I don't want to have e-mail is required. I want to say that e-mail is invalid, but when it's empty, I would say, okay, Email is required. So how we can differentiate between two messages. So as you see here, we have ng-if user email invalid and the form is submitted, then display for me a message. We can have here two types of messages. So we can divide this message, we can put it inside a span and we have another message in another span. So we can have here two spans. One for the e-mail is required and one, the e-mail is invalid. But here we need also to check ng-if, what is the type of the error? So I will say here as well on ng-if for email is required, I will say user form dot errors. Is a required. Then show me this message. But if the error is email, then show me the other message. So we can put that as well here and say, instead of errors dot required, we say error dot email. So we save that and try it again. And we will see when I will put a wrong email, I will say e-mail is invalid, but when I put empty, I will see email is required. So in this way, you can differentiate between the validators inside your email, going back to our components. So we have here two validators. And for the phone, it's also required for the foreign as IC here, I used a new control which is called Input Mask. And this input mask, if you go to prime NG, you will see that I used this component. This component is just to showing you and help the user to enter that number in a right way. So as you see here, I have put a number and it's masking it. So using this is exactly the same. I imported the module to app module and then I used one of those examples are used, for example, the one which the font. But how you can specify the mask you want, you can specify it by putting 99 in this way. So when I remove this part as well from the mask, then I must have the mask in this way. So it's a masking. So the user will always put that in there, right way. So you see here I have the masking exactly as I defined it here is admin is a switch. We had seen that already in the product when it's featured or not. Street is a textbox apartment, zipcode city. And then we have the countries. In the next lecture, I am going to show you how to list their countries inside this list using some external library. But now, as we see here in our component, that we are able to do the same thing how we did with the categories and the product. So when I go first, I check the edit mode and I check if I have parameters over the user. So when I have parameter, for example here, which is user ID, then I am in edit mode. And in edit mode I am showing some information which I grew up from the backend. So I use the user service to get one user by ID and subscribe to that value. And then I set the controls based on the values which I got from the backend. But when I am on a New, then I am going to have add a producer. And this Add user will create a user for me. And then it will display success message and go back when they are empty. And the location, we go back to the user's list and if there is failure, it will tell me user is not created. We talked about all of this stuff in previous videos of categories and products. You can see them more in detail and repeat them if you don't understand something. I'm explaining here only the new things which are really important for you, which we didn't do previously in the course and the next lecture, Let's see how we can fill their countries based on some external library. As I told you previously. 117. Retrieving Countries to Dropdown Using i18n iso countries: Okay, great. Now in this lecture I am going to show you how to feel the country list. Of course, we are not going to have an array of all countries in the world. No, but we are going to use one library which is always getting updated with the code of the countries and the names. And this library is called IAT EN, ISO countries. And you can find it as MPM packages and you can install it through this comment. So I go to our users form component and I am going to have the country's list filled here. So we have now empty array because we are using it for the drop-down as we did exactly with categories in the product. So first of all, we need to install the library that stop our compiler and then paste the command of MPM install. And then we will see how we can call this library and call the list of the countries. Okay, as you see here, I have it installed already had. Now if we go to the user's form, we need to have the country's field, exactly how we did with categories. We can define a method which is called, for example, get countries. And this give countries, I am going to initialize a country's and getting them from that library. So we define a new method. We are calling it private Git countries, and it will be defined here. Okay, Let's go to the documentation of that library. I will go here and check. It says that I have to define a variable which is called countries, and then I will do a require. Okay, here it's using a JavaScript, but in TypeScript, if you want to import one of the libraries, you have to do the following. You have to go here. And after installing the library itself, you say Import and then artistic or star. And then you say, as you define, for example, a constant which you are going to use for that library. It's like I'm saying, import for me everything and put it in a constant, call it countries for example, list or lip like library. And then we say from. And then you define the path which is defined here. So you say, I want to import it from this library. Okay? We have defined that. We put it here and we will see that everything is still fine. We don't have any error yet. Okay, we go back to our GET countries. We need to register allocation and read the country's list. This how he said it. So we can't copy also this line. Say countries register locale and we have to do that, but we don't have countries. We have something called country's lip. So I will say here countries Lib then register locale and then require. And this required will ask from the library to bring the English JSON file which is located and it has all the country's list. You can as well use HTTP request to get this JSON. But I will show you an easier way. It's very simple for making it work. You can make it as declaration and you can say declare and then caused, require. And in that case, it will work hopefully. So as you see here, now we have at acquire and everything is working fine. And I have here the library. Okay, let's see an example to get all the countries. So as you see here, he said define countries and then he made the require and that he said console log with the countries, get names in English and select official. So let's do that in that way and try to see what we have in our console log to map the things exactly how we want for our dropdown. So I will put this code here. I replace this country's lip with this one. And then we can see what it's going to type for us. After I save, I go to the admin panel again, but we need to run the project. So as we see here, that project is running successfully. We refresh here to see what we are going to get in the console. Okay, In the console I, I got object. And this object has code of their country and then the name of it. Okay, But the way how it is, we cannot accept it like that. We need to have the countries as a list because our countries dropped down, accept countries as an array. So we can use or find a way to map the things which are inside this method as array. So how we can do that? So I will do first, I will get rid of this console log. We will use it for something else. So I will say that countries live, give me the names in English, and then we need to map on it. So we can't map on object by using a method which is called object dot entries. And in this method, it will allow me to loop over all the entries like they are an array. To explain it more clear to you, I will make, I will assume that this entries as array and I will say map, okay, I pray accept that map and this map has were returned for me entry by entry. To do some operation with it. So let's for example, console log this entry. So I will say here, okay, console log for me that entry. Let's refresh and try that again and we will see what we will have in the console lock. So as you see here, it's refreshed and we have all the array members. So the object always comes as first number is the key, and the second member is the Spain. So and we have all the arrays like this. So we can then with map return as exactly what we want. So in users form, we need the option labeled as a name and the option value as ID. So we can map based on that. So we can say here, this dot countries will be object entries over all the countries which are in this library and map over them. And instead of returning the object itself, the entry itself returned for me and object where the ID is entry 0, like the index 0. So we have here the ID and the name will be entry and one. So we will have the ID as entry 0 and the name of their country will be entry one for the second entry. So after that, let's console log the countries. So I will say here, console dot log again these countries. So after we save that, we refresh, we go to our application and we will see that we returned a list or array of all countries with the code ID and name. And if I go here to the countries, because as you remember we have this countries is array, empty array. And this array is used for options of this dropdown. So when I go here, I will see that I got all countries. And the nice thing that I can search through them so I can say Spain, okay, I got Spain and everything is working perfectly. And of course, I can then update my user. So I would say update here and then it will get me back and I will get here that country and is pain. So this is because what we are storing in the database, mapping back to the Rename, then you have to do also the mapping here in that list. So we have to make a function in their country's list. And then it will go and search for Spain and then get back the country name. And this method is provided here. So you can say their library, give me the name of the code us, and it will give you the name of the country, which is United States of America. As a homework for you or as an assignment I want you to do for me in the next lecture, the assignment that we get here in the list, the real name of the country, but not the name or the code of the country. So your work will be based exactly in Users list. So you need again to use this library in users, this component. And then you have to map or find out the name where we are mapping that field. So instead of this user that country, you need to do something here. This solution is also provided with the assignment and also I will attach it to the code. In that way, we have done everything regarding the user. So we have everything name, e-mail is admin and country. And as we agreed before, that the user for us is the same as customer. And if you want to make it more bigger or more complicated, you can't separate the users of the website over the customers because we are using here the user as a customer. And it can be admin or not, but it will be exactly the same way how we did with the users to attach a customers. 118. Retrieving Countries solution: Okay, As you see here, I retrieved successfully the full name of the country. How I did that? First of all, for the country in the country list of the users, I created a method called get country name, and then I pass the user that country. And because we are saving the country ID in the database. So let's check this country name. As you see here, I check if there is a country key passed to the method, then returned for me, Users Service doeth good country. Okay, so I defined a method is called good country in user service. So as you see here, they get country is using the country's lip or their countries library, which we used previously in the previous video. And then get name and then iPads the country key, and then the language which I want to get this. If you remember, there was something for registration of this library, as you see here, if we want to use it, we have to register they're located. So how I made that I removed that registration and I put it in the constructor of this service, of user service. So it will be called one time only. So I've already adjusted dislocate only one time because user service is called Only one time when I am initializing the application, I remove that from users for I removed it from here. So we don't have this calling of the library again or registration. We have only the same get countries method. And then I said these countries use the user service and then get. So I will go here to get countries. And as you see here, I am returning the same code object entries. And then I use the library which I initialized here in the user service. So in that way, we are using it only one time. We are calling it one time, and we are not having a duplication of registeration of the locale as we saw previously. So always when you have some duplication, throw the things to the service. Also, I did hear a mistake because I'm using countries inside User Service. What if I want to use Git country and country in another libraries, like for example, in orders or in products. In this case, I remove all of this and create a service which is called, for example, utilities. This utilities will give me, for example, countries, cities, for example, for texts transformation or for formatting of numbers. So we can use this utilities everywhere among our application or workspace. We will see that later when we will need get countries and get country in our project step-by-step. 119. Create Orders Components Table, Details and Services: Okay, Now we are here, we are going to create the orders list and the order details page. So for that as well, we need to do two components. First, or those lists where I will see the table of the order and also the order detail where I will see the details of the order as we are doing always, we are going to create two components. Of course I am using an ECS console. As always, I named a new component, which is called orders list, and it will be created an application or an admin. And then I have a lifestyle to not generate CSS file because we don't need it. We have public styles. And also I created a selector which will be admin or there's list, and then I skipped that tests. Let's run this part. And then we will see the next one, which is the order detail. Here we will not have form, we will have on the details and in details I will display the order and then I can change the state of the order as we do always with any issue. So here I will call the item as admin orders detail. So which will be the selector? And it will be exactly the same options which we choose for orders list. Okay, let's go back to our code structure to see if everything is created. Okay, we have now, everything is created. We have now empty component. Let's first make the orders list, the orders list. So it will be exactly the same as categories as well as I told you, we have the categories as a template. And if you remember, we have defined always the template of the table, which we used four categories. So I haven't going also to use the same thing here. So I will copy this part, go back again to orders list, and then we are going to do some stuff here. Of course it will not be exactly the same. For example, we will have only delete older, but we will not have, for example, update all that. We will say Sure order. Like we are going to see the detail of the orders because we are not going to edit it. So I'm going to rename that things quickly. So as you see, I renamed everything. We have now orders, list of orders, and then I renamed it sinks here. Of course, the order will not come with any new, like how we have here with category, because the order will be placed by the user in the shop itself. So the user will place the order. We cannot create here a new order. So in that case, we can remove this part. So of course you can still be able to create a new order. You just have to do the form again and follow what we did previously. But now for detail, I want to show you different things to not be the same thing which we did previously in previous parts. So I'm going to get rid of all of this toolbar which is used for creating or a new order so we can get rid of it as we see here. And now we will have simpler table. So as you remember, the order has some fields which we defined previously in the back-end. So now we are going to do also again, the same model which we have for the front end. And if you remember, we have created a library which is called orders. So in orders, we are going to place our model as well. So I will do that quickly. So as you see here, I created the order model. The order model contains something called order item. And the order item, it should be also another model. So we can create that model as well. So we have here another file which is called order item. So with this order item, I am going to place a new class which is called order item. And then we have this order item which will have Product ID and the quantity. So we will go back to the order item and import this order item. So we will have here or the item which is imported from order item. We have as well to remember that we need to export those model in the index file. So we have here as well, export star of the model itself. And then order. So we have here the order and as well we need to export the order item so we save everything is working fine as well as you see here we have here the order module which we created previously. Later. We are going also to create the services. So we will create now folder, Let's call it services, which we will place inside it, the orders service. So go back to our application. We will define another variable or another class member, which is called orders. And disorders will have a type order. And this order we have created previously, and it will be empty array at the beginning. Sometimes you get this error like property order item is missing in type undefined. So it's better to have like always the fields. Optional as always. So if you have this field as optional, it will not bother you so much the Eastland that it's showing you. Yeah. Okay. This is not defined. You mean you need to define it and then you create order item, etc. So when you define an array only, it's better to just make it an optional. And here you will have no issue anymore. And we add those as well to not have an issue here. So we will have the orders, orders array and ordered array is empty. So we go back to our template and we are going to add those modules or this members fields here. So I added those columns like user total price, and then the date ordered and the status. And here we will have the column only for actions. So as you see here, you can add the columns which you want based off what you want to display. So here I need only this, but of course you have freedom to add more stuff for you. So now we go again to the template here, to the values where we are displaying the values of the order. And we are going to remove all of this stuff. We just keep the action buttons and we will show only like the values which are in those fields. Okay, add, I added all of those fields. We will see later how we can make a bad for their status. Like we will show a color of the order based on the status of it. I would like also to add some ordering so we can't have order for their name, sorry for the user, for the prize. And also you can by date and you can order as well the status. So let's do that quickly. So as you see here, I have defined all of the staff to be sortable as we need. Let's take a look if we don't have any problem there. So I will go to the orders table. You see that I have error that I didn't define the route order. So we need to go to the app module and then we need to define the order as well as we saw previously. So first I need to have the order, for example, list. So it will be orders, list component, and we will have here orders. And as well we need to define an ID. So we will be enough, for example, With only orders. And then I will say for me the ID without, for example, the, the form itself because we don't have formed here anymore. So here we will say detail and we save. So going back to the application again, and after it's getting loaded, we will see that we can go to the order and see the users and the status and the date order. But we don't have data. We need to create a service to grab the data to the front end. Exactly how we said. Again with category, we can also copy that category service and replace the things here. So let's do that as well quickly. And of course you can use the ability of replace. So we have here category and you can't match the case. So I can match the case, this case or cases. So I will say replace category with order. So everything will be replaced immediately. And as well, if you want to have a capital letter, like some cases like this category has a capital letter. You can also replace it with capital letter order. So as you see here, I have also replaced everything to be as an order. Okay, It's very simple. We have as well categories, so you can also replace that. So we say categories is orders. Well here we need to replace it. As you see, we still have categories, but with capital letter. So we have here orders and also with capital letter, and we replace all of them. As you see now, we have all the orders, is ready or service is ready. We don't have to do and suffer so much with it. So we save it and then we exported as we did previously in another libraries. So I will see here Services that, okay, now we go back to our application. We are going to the list component and we will see how we can add all of these orders. It's very simple, the same exactly how we did with categories. We just need to do on it that we need to initialize or get the orders. So I would say this dot, get holders and get all those will be a method which I am going to define now. So it will be here, I get categories or get orders. And this here get orders. It will ask for the order service. So we need also to import the order service. So as you see here, I did that quickly because we have done that already in categories. And also we can do with here. So after that, I'm going to grab the data as well here, as you see, we have already the orders, but as you see, we have the user coming as object, object. But this is not the goal which we want to have it because we need to have only the name or the email. Because if we go to the network and check our example, that request which we created four orders as we see it here. Then we will see that the order items games in the way that they are populated. For example, the user is populated totally. So what I need is only the name, exactly how we did in the back-end. So in that case, you can display the name or you can display, for example, the email. So I am going to display only the name. So then I will say here that name. But if you remember, we have defined the user in the model as a string. So it's better to define it as a user. So here we would get the user from another library, which is called Import user. And this user will be from users. And as you see here, we will get the user and place it here. And then we will have everything is right, so we can get the name in the right way. So let's save that again and check our front end. Okay, I see that I got my name here. I have the total price and I have the date which I made the order, but it need formatting and the status is 0. So what it means 0. For me, I would like to have something like naming, like pending, shipping or shipped or delivered. So I want to show the status of the order which we are going to edit here. So the user or the admin of the shop, he can update the order status. So for that, it's better to do some mapping. And this, what we will see in the next lecture. 120. Order Status: Okay, in this lecture we are going to see how we can define a status for the owner. And this status, I am going to use the tags which we used previously. So I can show in some color like delivered, or it's a shipping, or it's in process, or it's, for example, received, et cetera. So I will show you how I will define those constants and then how will we will put this tag inside our table. So first of all, we have imported already that module to our app module. So we just need to have or defined the tag itself. So I am going to take this DAG and then place it in my code where I am retrieving the order status. So here we are going to place that tag. Let's refresh to see if everything is working fine. And then we will see that application is reloaded. Perfect. We have now here in you, Okay, we are going now to see the coloring. We are going to see how to adjust the text. As you remember, you can define your own mapping for the order where you can define that. You don't have to do that in the back-end. Back-end is only place for storing data. You don't have to handle what are the types of the orders. So the simplest solution for that, I am going to have something like the order text or the older status text and also the order status itself, like how it will be colored. So for that we can define a constant. So we can call this constant, for example, order status, and we can define constant here, or you can do it also in external file. I will show you when we are going to refactor this. So first we need to have a constant. We can call this constant order and then status. And this order status will be the object and the object be, for example, multiple objects. And those objects will be defining the label which will be like pending or processed or shipped, and also the color, the color which will be based on these values. So first of all, I will place the value as here, like this, as object like this. Of course you can make it as array or you can make it as object. You can hear also define keys as you want. So as depend how you are storing or how you are going to store the status in the database. For me, for example, the first one it will be labeled, I am going to call it, for example, pending, which will be the first status and the color. So the color of the badge will be the color of that tag itself. So as you see here in this example, he has multiple colors, so I am going to use the same colors. So we can have this also. We see that he is using success info, warning colors. So it's depend on you. So if you want some special colors, you can define that in CSS. But for me those colors are enough. So as a first status, that color will be a primary color as it's defined here. So we have here primary success, info, warning and danger. So we are going to use those colors. So first, I will use this color and then I would define another status, which will be, for example, the processed and processed will have the color like orange, which will be warning, warning color. And of course, I am going to define another color or another state which will be shipped and cheap to have also warning color like we are in process and we will have another status which would be called delivered. And this delivered will have success color. And then we will have like a rejected or for example, canceled or failed. We can call it. So we can make another field which will be called failed. So when the user to make a payment or for example, when the user asks for refunding. So we can make, for example, this color a danger. Okay, we have now order status. And this order status, we are going to store it in a variable which we recalled or the status because we are going to use it in the template. So I will say order status is equal to order status, the constant. So when I go here, I have that DAG here. So I would say that the value of this DAG, you need to define the binding. So we are going to bind a variable here. We are not going to use a static string because we have the string already. So we can't say that order status will be the order status itself. And the key will be ordered those status because as you remember, we have defined keys for the states and based on what I am saving in database, as we will see in the front end in any shop when I am sending the order and how we would update the order status, we will see how we are storing that in the database and then order status after with the qi dot name. And here I will get the name of the status or the label of the status. Here we must have a label, not the name. And then we need to define the color. But let's see first, if everything is working fine, I am saving everything. The application reloaded, Okay, we have here pending and we will see how we are going to change the status and then we will see how it will reflect in this table. So now we have the pending and we need now the coloring. So to color these tags, we need to define something called severity. And the severity will be exactly the same color which I defined in our constant. So I will go here. I will say like this severity and it will be also like a variable binding. We are not going to use a static text. We are not going to say like a danger or our string here. No, because we are using a variable and it will be the same thing. It will be also order status and then older that status code, which come from the backend and then will be the color. And when we save that, we will see that we are returning the right color. So when I go here, I will see that if it's working fine. So let's change, for example, the order pending state. We can change it, for example, to danger, for example, to see if everything is working fine. So I'm saving that. I go here, I will see that it got red. So we are on the right path, we don't have any problem. So as I told you, we define a constant in the order list component. And in order Greece component, I used also a variable or a class member because I am going to use it in the template. And then if you remember this value of the order status returned as 0, and this will be saved in the database for the order status. So 0 for the pending. One is for processing, three is for shipping, for four delivered. And we define all of this graph or dictionary here. And also we use the tag item because this type module or tech component asked for also for coloring and we made the colors exactly how this tag is working for. Formula date, as you see here, it's formatted like from the format which comes from the database. We can also format the date using the pipes, how we did previously with the product. If you remember, we have made or make the created at in this format. So we can do that as well for the order. So we go again to the field. We don't have a tag, we don't have this. We can have date order and place the short pipe formatting for the date. And all works perfect. So we have here the date and the status. In the next lecture, we are going to create the detail of this order so we can see more detail about this order of like the items and also the product. What are the products and the price of every element of a product? So we will see all of these details in the next lecture. 121. Order Details Component: Okay, we saw previously how we create the list of orders, and we saw how we created the status badge for the order. Now in this lecture we are going to see how to make the details of the order. So what is the requirement for that? The requirements are for me are just I want to see the details of the order and change the status. They user is not going here to create orders or for example, update the whole order data. But it will be in the front end, the front end, the user or the customer going to create the data or the order in our issue. So I would suggest some design I have made already. Like for example, we can have all the detail. We can have order ID, order date, and order status, which can be updateable. And also the order total price and the order items. We can list order items here and then the order address and some information about the customer. So let's do this structure exactly how it's done here. So we go again to admin. Then I want to change here the icon to be lot edit, but it will be like a view. So we can change the icon based on icons in prime energy. We have here icon in prime end use is called Pi I, so we can use this one. So I go again to my orders list and then I am going to change the icon here from pencil to I. And then we save, we go to see that everything is working fine in our application. Okay, we have the icon here. So now we need to see the order details. So when I click here, I want to go to the orders detail. First we need a route and which we created already, and then reference to this route. So first we need to define the function which is called Show order. We will go here again and then we will define a method which is called Show Order shoulder here. And I am getting here the order ID from the front end. And we are going to use the router. And the router, as we said previously, it's a service or a class which we can use. So I'm going to have here the router itself, I would say private router. And this will be type of router. And we can import it also Angular. We make this as small letter to be usable. And then we go here and say this dot router dot navigate by URL. And then I specify the URL where I am going to go from here. So I want to go to the route where I specified in our module. So if you remember, we have here multiple routes. We said that all those will be after it is ID. Then I will go to the detail component. So we go here again and we say navigate for me, orders slash and then the ID of the order ID. So we can combine that with backticks and say orders, and then we say order ID. In this way, we navigate by URL to our component. So let's try that. We go here, okay, we have year order detail works, but as you see here, we are not going to have, for example, forums structure. We want to have something like details, you know, so you need to have like static text. We don't have a form, so we are not going to use form here. Only here when I am going to change the state, I am going to change it based on the onchange event, which is coming back from the drop-down here. So we don't need actually a form. We just need to display a data. And we can use as well this accordion. So we can go there and check prime NG for something which is called field set. So in the field set, as you see here, we can use it and display content inside those fields sets. But first, let's have the title and other things like how we have in category. We have here the title subtitle, and then we have a toolbar. We don't need toolbar here, but we just need to show like some information about that. We are in order detail. So let's do that as we did exactly in categories form. We used something like called card. And inside the card we have a toolbar. We don't need the toolbar. We just need, For example, the admin page and toast for the update. Can't copy only this part at the beginning. And then we can add our grid and inside it, the field sets. So first I'm going to cut to copy only that card and then the admin page and the host itself so we can copy them and go again to our orders detail. We'll remove this part and place it with our postcard. We close again the pKa to be everything is fine and also that. So inside the Picart we are going to place our data. So first we don't need edit mode, we have only a view orders, so we need to remove all of this part. We say that we have only a view ordered. So I would say here View order and here. We can say that you can edit order status here. So we can have only this information. So now here we can use our field set. Using field set is very simple, is just you have to copy this part and import the module. So let's import the module itself as we did previously in our app module. So we go here, we have import of this module, field set module, and then we place it here. So of course, as I told you, we have a lot of modules. You can also separate the modules as we will do later. I will show you in refactoring part. We'll, we'll do a special module only for the UX to not have very big module. But we are going here in the course step-by-step. We save this part and then we check what is the HTML required for that. So we can say that, Okay, I want the one which is doubled. It's very simple. Toggle template is this one. So we can copy this part and then we place it here. And here we will have our content and we can define our headers. For example, I want toggle header for further details and then order items and then order address. So we need here order details and another one for order items. And also we need another one for order address. So here we save and then everything here is aligning and formatting for us. Check the orders. We go here again, check it. Okay, everything is fine. But as you see here, they are sticking on each other. We have ready classes for margin and padding so we can use them as well here. But I just want to mention for 1 that here in the field set or any component which is from prime and g, we cannot use like class like this and then give it a class like an HTML. There is some special keys for that, so you need to check always in the documentation, what is a key for giving a specific class for that component? For example, here in our case, it's called styling class. So in style class, I can use it as a class. So we can define the class which we want for this toggled panel. So I want to have a class which is called P margin bottom, for example for and the same for the other. So let's save that and try it to see if it's working. Okay, As you see, we have here a space. So let's do again for the others. So I need here to style class as well, and here style class as well. So we have here three style classes and it's working fine. And I think it's also targetable. So we are going to place our content, what we are going to have. For example, here we have order ID, order date, and order status, and order total price. We get all of this from the backend. So you have to repeat behind me, what do we need to do? We need to have a service. And the service is grabbing the order detail and in the front end or in the component or the item or order detail. I'm going to use this service to grab the data. But let's do first this layout, this layout, I think it's pretty simple. We have, as you see here, agreed? And this grid is three parts, three equal parts, and here the fourth part. So as you see, we need to have a grid and column 444 and inside all of them some content of data. So we can do that simply. We go first to our order details and we will say that we need to have a grid. So I will define a div which is a class called p grid. And then inside this p grid, I will have components or items where they will define three columns. So we say div dot py call. For example, you define a column so I can't have p column for, so for example, we have to have put here first, second, third, fourth. So we will see them that they are aligned under each other in our template, exactly. So we have everything fine here. So let's feel this data. For filling this data, we need, for example, a label like a title, and then the data inside it which I am getting from the database. So I would go here for a title like with H5. And then in H5, I say Order ID, like a hard-coded text. And then a paragraph where I can put the ID itself. So we will have here some ID, and this ID will be replaced, which we have from the database. And you see this order ID look like that. What we need as well, we need order date and order status. So we have here as well another h5. So I will have here order, which will be date. And as well we will have like some date here, okay, which will come from the database as well. And also we need here another thing which is called order status. So you will have here order status, but this status, it will not be, for example, a text, it will be a dropdown. So I will use P dropped down as it's defined, isPrime NG. And this lockdown will have options and we will see later how we are going to fill it with the data. The last thing which we need as well is the order total price, as we talked previously. So I need here another F5 and that I will say order total price. I saw their user can know what is the total price of the order. And then inside it, I will have like some price. So let's save that. We go here, okay, we have that drop-down, we have the data, we have the date, so we just need to fill the data. So let's first make or grab data from the database. As you remember, we have defined a service and this service contain getting order detail. So if we go to orders library and we have here Services and order service, we have something called get older. So in our order detail component, we need to use the order service. So first I have to say private or the service. And then we'll have a type which is called order service. And this order service is automatically imported from my workspace. And then the orders at is defined as we saw previously, a method which is called this dot get the so-called, it's very simple. We just need to call this method. And then these methods will be implemented as private. And then we say get older and get order will give us the order to a variable or a class member, which is called order and has a type order as we previously defined the order model. So here we go. We lose a service. We say this dot order service, dot get order, and then get older with come with the order which is coming from the parameters which I got by the URL. So we need as well to use the service which we used previously, which is called activated route. So we have here imported activated route. And this route, I am going to observe the parameter this, the trout and then params. And then I will see subscribe, and then I will get params and then I will subscribe to them. And as you see previously that in app module we define our param as ID. So we have here ID. So when you have some pig else, you have to use it. So we need to use ID for example. And I will say here, if params dot ID, and then I'm going to call the get order service. And we will use that service, this ID, because in the params ID, as you remember, we are getting the ID of the order. So I am going to get order with that ID. And then we say that we've got the order and the order will be equal to order. So this order, which we define as a class member, which will be the same as order. So here we save everything and then we go to our front end and check if everything is working fine. So we don't get any error. We are just getting error here. They need order. So we just need to define it somehow to not have this error in the console to say order ID. And this will be your homework for doing it, the leading order as you will see in the next lectures. So we save this part. We don't have any error only like ES lint error that this method cannot be empty, no problem. And then we are going to fill the order data detail. So for example, we have defined the member class which is called order. And this order I am going to replace with order dot ID. So I am going to get this order ID between these brackets to be defined as a variable and as well here we need have to have the date order ordered, date ordered, and the dropdown we will let it fall. The next lecture and order total prize will be the same way as we did it here. So we will have order the total price. So we save and we check that, okay, everything works fine. It's better always when we are getting data to the front end, it's better to see that if this data is ready or not. Sometimes on slow servers, when you don't get order, you will get errors in the console and this will be causing a problem and there is no data will be displayed. So it's better to wait for this order to be ready, like this variable to be ready because as you see, we have many waiting times. So we need to subscribe to params and then wait for the service until this order, Garfield. So it's better to use always ng-if for this pace. So I would say on the admin page level, I will use ng-if. So, in ng-if I will say if there is order, then display the content inside. Otherwise, display empty page until the data comes. So until the data comes means that I will not get errors when I will say, for example, order dot something, because if this not defined, then I will get error in the console. It will say we cannot get date order from undefined variable. So it's better here to have ng-if in GF, it means that if there is ordered, like there is defined order, there is data inside this order. Then a grab for me the data and show the page otherwise, display empty page. Okay, Now so we have the order here. Let's do some styling or purifying for that data. For example, we have here the date is ugly, it's not formatted, and also the older price is not coming as a currency. So as we talked before, that Angular comes with something called pipes. And in those pipe you can define whatever you want to format your data. For example, I am going to use the date here, which is for using the date. And this date will be short format as we saw previously, exactly. And the prize, there is something called currency. So if you want to see all the pipes which you want, you just do this and all of them will be placed and displayed here. So you can have, for example, date, you can have number, person, and also slice. And if you want also to display JSON data, all of this pipe are available for displaying your data in the right way. So for example, here I am going to use currency. So let's save and check that ice we have here that currency is very beautiful and also the date is formatted. 122. Display Order Items with Subtotal Prices: So let's check now what we are getting from the backend to display the order items. So what I go here and open the network and the Dev Tools, then I will see that I am getting here some requests. So you have two options. One of options you can console log the order ID of after you get it. For example, when I go here to detail, and then you can do a console log and then this dot order to be sure what data are coming from the backend. Or otherwise, you can directly go to Authentic torque tab and then find the request which we have called previously for getting the order detail. So I console it, look in the console log. We will see that we have order items and this order items is array. For example, in our case here is empty. Let's try another order I have here or there with some items. Okay, we have another one. We can delete, slow this one, go here or there items. Okay, I have here two items. And as you see in every order items, I have that product and the quantity. So I have here to order items. Every one of them is to products with a quantity and to display them. If we check here our template, we have your name, brand category, subtotal, and we have here total price and how it's counting all of that. You have two options. One of the options you can create a table and display this data or otherwise you can do that manually. We can do that manually and easy by doing also the field structure or a grid, a grid inside this field. So we can say also here that inside this field set, we need to define not the content, but another grid. And this grid will have the same structure as we saw previously. I am going to fill them. So as you see here inside this field set, I defined a great ad inside this grid, there are columns of two, so until they have equal of 12, because we have 12 columns available. So we need six of those columns and all of this data and inflammation. If we go and check our order item, okay, we have got them exactly how we need. So now we need to grab the order items from here and then put the information in that table. It's very simple. We can also do another grid under it. So it will be equal exactly to this grid. But we will replace this text data with the order or the orders data. But this grid be repeated because we need multiple order items, we need multiple roles. So you can consider this is a row and every rock will be repeated based on the data which are coming by order items. So as we see here, we have MD4. Md4, I am going to put inside it every order item. So I will say let order item off, order that order items. So we will have here, or the items I think we have here a mistake in the model. It says that order item is not defined. So I think we need to go back to the model to check if everything is working fine here. We have here order and then the field is called older items must be altered items. So we go back again, we see that the error is fixed. So we don't have any issue here. And then I'm going to replace the order item with these data. So first we need order item product. So we have here first order item, and inside this order item that is a product, and inside this product there is product details. So first of all, I will say order item, forced first-order item, which I got from the LC4. So I would say he order item dot product and then give me the name of the product. So this how it should be done. So as we see here, we have all information which we got with this MD4. And then the same, it will be exactly for their brand. I will check here, go to the product, and the product will be the brand as well. We need that category. But let's see how that category is implemented. So we go here and check if that category also populated. So we need to category name. So category dot name. And also we need the price. So we need to check also this. So we have say order item dot-product. That price quantity is coming directly with the order item. So we have here the product and the quantity. So we would choose that. So we say order item dot quantity. And after that, the subtotal, we will see how we can fix that. So we have here order eyes, we have quantity three, prize computers and brand, and everything is working perfect. So we need just now the subtotal. The subtotal, we need to have it as well calculated. So we can calculated by multiplying the price with the quantity. It's very simple. So I will go here and copy this one and say price multiplied by the quantity. We have here everything multiplied. Then we check again, okay, We have also the price is coming by calculating price multiplied by 3. Then we get here 750 and the same for here. We can give it also, uh, flags here like currency and as well for the price we can give here also a flag or a pipe currency. So and then it will be displayed like this. Let's give some space between those grids. For example, we have here a little bit sticky and so we can make it with more spaces. So I can say also this grid give for me margin bottom will be five. And the same one for the grid itself. So every grid will be generated, will have margin button five. So as we see here, everything is perfect. So we can as well make those as bold is up to you. Prime NG also comes with some classes, are ready classes for making bold things. So if you go here to the Prime flakes and you will see something called text. And in this text you have some styles so you can align the text and as well give it some style. So for example, I want to give this p text poll. So we can go here and then we can define every column as a p, text bold. So we have all of them will be bold. So when we save, we go here, we have everything is bald. So now we have defined all of these items and also we have here subtotal. We need to have as well here that total, so the user can see the subtotal and then the total price of whole order. Like as we saw previously, how we calculated the total price in the back-end. To do that, we can as well defined another grid for that. So we can have another div. And this div will have a peak grid class. And this big grid with contained two columns. One is for the title or the label of total price and then the total price itself. So we will have one div with P, call two, and another one, we will have p equal to, and here I will write a total price. And here as well, I'm going to define that total prize, which I get from the order itself. So here I will say give me the order total price. So order dot total price, save that. We tried out. We will see that we got total price. Is this price the sum of subtotals. But let's give it some offset to be exactly under those lines as we see here. So we can also do that by defining something called offset. So when you use offset for this, then it will push the columns, some spaces, throw it would get the right place. So I want to push those like for example, we have these 2222, so we need to offset eight, so 1234. So then here I will have the two columns. So I will offset columns and I will give it a rest, four to two. So we can do that as well. It's very simple. You just say that the first column will have offset of eight. And when we say, we will see that it got offset under them in the eighth place. Let's make them as well bald as we saw previously. So we can give this one, for example here, bold class. So I have p text bold, and another one will have PTX bolt. And you can as well give them some styling like color. So we can give to the whole grid content to be color, for example, green. So I would say style and in since style I will say color, and then you can define a green color. So after you save that, we will see everything got the green in this grid. And this grid has a bold text, which has price and the total price. Let's give it as well some currency as we did previously, to have currency format. Okay, Nice. Now we have our order table with that currency. As I told you before, you have option to use a table, but we use table many times. I wanted to use some specific with a grid so you can get used for the grids. 123. Order Address and Customer Info: So for now we finished order details and order items. We will do the same for order address on their address is exactly the same how it's comes with a user information and also with the order detail. So I will know which user ordered it and as well, I know the address, and that's it. So we can go here and then define another field set. We can't have another grid or div, we can say a peak grid. And inside this beaker, and I am going to have a columns. So I will have a three columns and each of them will contain some specific data. So I will say H5, give me another address or customer address is up to you how you want to name it. And then inside this B, I will get the order details which are coming from the back-end. So what we want here to display all of this information to save time. I have it defined already. So we have here the order either address will be ordered that shipping address, and then I skipped a line and then ISA shipping address two, and then the zip and then the city near each other. Then BreakLine where I will have the order country. Okay, let's check those changes, how it will become in the front end. We can go again here. Okay, I got here the address, Flower street, 13, Prague, Czech Republic. Okay, we need to display as well the customer name. So in the next column, I will say here h5. And as you remember that customer info comes with a user class. And inside this user class I will have the name. So we can have as well here information about the user. So I will hear say that, give me the order that user, and then after that, it's better to have the name. So we save that. Okay. I have as well my name. You can also at that other information like e-mail or for example, phone number. So we can have here another h5, we can say contact info. Or I will define, for example, the phone. So I will say here Order and not to user, but it will be exactly coming in the order level. So we will get here or there and then form. So we save that. We go again. Okay, we have filled our order detail, so everything is working fine. Now, I have here two orders, but you can add more orders if you want. So here my order is just fine. We have everything. We have ordered date, order status, we are going to see in the next lecture, we use the currency we used, how we use the grid, and also we use the information about the grabbing data of the order and order items. 124. Update Order Status: Okay, in this lecture we are going to see how we can update the order status. As you remember, we have some specific status for the older. And now we are going to make our fill this list and then we will have all status of the order. And when we select one of these status, then it will get, for example, nitrification for us for updating the status of the order. So as a first step, let's fill this list or this drop-down. As you know here we are not using a form, so we can use NG model, which is a two-way binding for reading and inserting data to the drop-down list. So if we go to prime end, we can't see in the drop-down that we have the basic one. We are going to use this basic. So the basic one will contain, for example, it will ask for a ray of the status and then I can use the NG model as it's mentioned here. So we need to define the options and the NG model. So first of all, let's have the options. And as we see here, the options comes as array. So let's take this part and then place it in our order detail component. So we can go here where we have defined the order status. So we have here the drop-down, and then we have options. It will be order statuses, like we have multiple states inside this order or this array, and we have a selected status. So first of all, we need to fill the drop down, the dropdown. As you remember, we have defined previously in the ordered list item, some order status array. And this order status array, it will contain all the states which can come from the front end. But as we see, it's not array, array, but it's dictionary. And we are going to map this dictionary to and change it to array. But first, we can put this constant in additional file or external file so we can read from it and then we can use it in the both components. So here in ordered level, I can define a new file. We can't say older dot constants. We can call it like this. And then inside this older constant, I am going to put this order status and exported so I can use it in another places. I would say here, export const order status. And this order status will be array or the dictionary of adhere to keep. Everything is working fine. We are going to import this order status from the file of constant. So we go one level up and we get the order constant. So let's make sure that everything is working fine for now in our orders list. Okay, everything is working and the mapping is working fine. Okay, Now we are going to use this constant in order detail components. So we will go to the component and take also again import also the order status from and then also one step up and then give me the constant. Okay, but as you remember that we said that dropped down except only array. So we need to map this array or this dictionary to be as an array, then we can use it as well. So we defined here order status is, so we can use it as well. We can define that. So we can say here order statuses, which is for example, empty array for now. So we need to define that. So in Anki on init, we can say this dot status. So we need to map the order status and it's better to call it before getting the order so that dropdown will be ready and then we will get the order. So the method I defined here, and then I am going to see how we can map these older status to array of order. So what we need for the drop-down, actually, we need options, and those options are consisted as we saw previously from ID and name. So every auction will have ID and a name, name for displaying and id 4 using and sending to the database. So if you remember, we have used a function which is called object dot keys. So I can go through a dictionary for all objects inside a dictionary. So when I say here, Object.create of this object, then it will give me 0, 1, 2, 3, 4. Let's try that. So I would say object dot keys of order status. And we can make a console log for it. So to be sure that everything is working perfect, I want you to understand why I'm doing this. So first, we need to console log object dot keys of order status. So we go to one of the orders. Okay, I got 0, 1, 2, 3, 4. Okay. But we don't have any values. We don't have any name of this status. How we can do that when I create another console log. And then I will have here another console log. And I say, for example, give me the order status and then say 0. Then I go here, I will say that 0 is bending and color is primary. So when I want to reach one of the order status, I have to specify the key and I am getting this keys through object keys. And as you remember, we got an array. So through looping, through this array, I can do something with it. So let's go again here, object of status dot map. So I am going to loop or go through all these elements, generate a new array in different style which fit for my dropdown. So when I do map, I go through all the keys. So I will say key, so it will return for me key by key. Let's move this console log here and place it here. And in place of the 0, I will say give me a console for me the order status of the key which is returned from this array. So when we save, we notice that I get all the status so easily. We can map all of these elements and make them as array of ID and label or ID and name. And as you know, that map is only for changing the style of dictionary or style of array. So we can make something different. We can build our own array. So I will say here, returned for me, for every key which you are going through, this array of object gets returned for me ID. And this ID will be the key itself. And then the name will be order status and not order status itself, the key. And inside we have not only the order status, we have color and label. So I'm going to use the label because I need the name. I want to display this name in our drop-down, so I will say label, okay, we save to see the result of all of this mapping, then we need to assign it to constant. So I will say this dot order statuses is equal to object keys and all of this mapping. So we can't save that and go again to our application. We will see that GOT the drop-down of object, object. Okay, let's see what is the problem, why we got this. So we can console log I always, for example, when I don't know what's happening or when I get this object, object array, I console log the things. So if you remember, we have assigned to the drop-down this older steatosis and I am going to console log it. So I want to see what is there. So as you see here, we have, we have an array, okay, that's fine. We have ID and then name bending the problem here, that m prime energy that you need to specify which label you want to display inside of your array. So if you want to display the name, then you have to say option labeled, then name. As you see here, he defined name and code. So he can say he can display that chord or he can display the name. So we need to do as well the same. So we need to say in our drop-down, don't for example, show me the order status as object, but show me the name of it. And the option label will be the name. Okay, go back to our application. We will see that we got the name displayed exactly how we defined in our constant. Okay, What about now NG model? And you model, it will return for me that selected element and also I can assign a selected element to it. So selected status, it will be the selected element of this dropdown, so we need to define it. And we can say here also selected status, it will be any. Okay, let's see how we can get the value. For example, I want to change when I change from here to this, and this to this, I want to see the changes. I want to console log. What is a result of this changing? So it's very simple. In dropdown, you can just define a method, output method in your drop-down, which is called change. And when we change something, you can create a method, for example, on status change. And in this change, you can pass a keyword which is called event, and we save this one. We go again to our application, we define the method and we say on status change and this event we can say for example, it can be event like this. And let's console log this event so we can see what is going on here. So we can say here, console log event, it's better also to delete all console logs, which we have defined previously to have a clear console. So we have here console log of the event when I am going to change this status. So I am going to change. But I am getting nothing this because that we cannot use the change. It's exactly how I told you before about the style. You cannot use a class on this members. You have some specific keys you have to follow. So I always encourage you to read documentation of the component when you want to do something. So when I go here, I want to see when I change what will happen. So we can also find out about all of this. You see, you have a lot of methods. For example, there is onclick, onchange on filter. So there are many things. So what we need exactly is unchanged. So when I replace this change with change, then I will see that results. It's not like a standard drop-down. It's not like a standard button. So you have to read the documentation and see what you need here. So let's try again. Okay, nice. We have original event and there is value and the value is one. So the value returned as object. First field is the id, and the second is the name of the status. So for example, I have here failed, then I will have object, which is value and ID and name. So it's better somehow also we can return only the ID because we are going to use only the ID to store it in the database or load the order status based on that. So we can see also in the documentation that we have as well, not optional label but option value. So the option value will be used for this field or for this dog down, it would be the ID. So we talked previously many times about that. And I just want you to know how exactly specify the things and the inputs for the component from Prime NG. We change again, Okay, we have here, again, we have the value two, so we are getting only the value. So on status change, I am going to update the status of the order based on how we got it in the backend, how we made it in the back-end. So as you remember, I was creating a put misspelled and then post method. I am just sending the status to the specific order in the our orders API. So when I send this request, I will get the updated status and then I will get the order again. So we just need to pass the status. We don't need to pass all the data of the order as we did previously with the product and category. So for that, we need a service. This service will be update order. And as you remember, we have defined all the services which we need for updating the order. So after I update the order, I'm not going to send the order itself. I'm going to send only the status. So I will say here status. And as you remember, in the JSON, we are sending the status like this, JSON status and two, so you can as well send the status, dike that or define your own type. So I am going to have status. And the status will be a string and what I will get in order. So in order I will get the order itself after I update my order. And as well, we need to pass the order ID, which will be also string. So we need here as well, or their ID. And then I will send the order status. So here is different, but of course you can send the order again and it will automatically, the back end will get only the status as we saw in the back-end part. So here we have update order. Let's go back to our component and create or call the update service. So I would go to order details again and onChange, I will call not event, but I will say this dot Order Service, Update order. And update order. I am going to pies the status as you see here, we have status string, I will send an object will have status, and the status will be event dot value, as we saw previously in the console log. And as well, we need to send also the order ID. So we need as well here, when I get the order, I need to say this, the order ID. So here we have everything is fine. And as well as we talked previously, we said that it will not be executed until you subscribe to it. So we have here order and maybe we can, for example, console log the updated older. So let's save and go again to our front end and check so we can say shipped, okay, It's got updated and we have the new status. So we have status to, okay, let's make another failed. So we can go here and we will see the status is for, okay, so for example, this is failed. We go again to orders. We will see that the status got changed as well. So we go again, we updated delivered. We go here and the state who's got updated. So it's very nice to have like some notification for the user. As we did always, that everything is fine. So when he click here, then he will get a notification that okay, the message or the other, the order got updated for that. If you remember, we have created or called the Message Service and the method terrorists will do for me what I want. So we can copy this part and then go again to our order detail list. And we say that after this axis, okay, Show Message Service saxes, and then say order is updated. Otherwise, when there is an error, we will show the error. But first, let's call the message service. So we go here to our constructor and then we call private message service, which will be Message Service, which comes from Prime energy. And then we save, we try that again. Okay, everything is working fine. So the order got updated. And if we go again here, okay, it's working fine. So when we go again and check if there is error, then show me the error. So here after the subscription, I can say also that if there is error in general, then do for me an error message and say that the order is not updated. But of course the Estlund is complaining here that we didn't use this error, so you can delete it or you can also print it in the details. But for me now, I will just display order is not updated and as well here we need to delete the order so we are not using those. We aren't just displaying messages after subscription, fail or success, okay, as you see here, we have now everything is updated and our order status is updated. One last thing is left that when I go to orders, for example, I have here a delivered, but when I go here, I still see it as pending. This is beef caused that when we are loading the order, we are not updating the selected status in the dropdown. So simply you just go here and say these dots selected status will be ordered dot status. So that's all. You just need to do that to make sure that you are entering the right status. So as you see here, we have a delivered and it can be updated easily. 125. Create Login Page: All right, now we are going to see how we can create the login component. But first, let's take a look back to our graph about structure of our project. As you remember, that we have created a library which is called users and authentication library. And in this library, it will be shared among all the applications. Because I don't need to repeat the login component in every application. Or the login page, which will contain email and password. I am going to create those components to be also shared in the user's library. So as you see here, we will have a login component and register component. And beside that, we will have also the services which are going to help me to login and register a new user. As you read in the previous article, we need to do many things regarding the authentications. We have many lectures and many features to implement inside those lectures in this section. So first of all, I'm going to show you how to create the login component to be shared among all the applications. I would start first to be, for example, only templating. So we will have only HTML, CSS, we will have nice login page, and then we are going to see how to connect it to the application, which is admin panel application. And then later when we are going to work when the issue of obligation, we were connected there as well. Okay, as we do always, we are going to create a component which is called login. So I am using an ECS console to create a component. So here I am going to put it inside Pages folder, and then the name of the component will be a login. And also we have here where it's a project. So we are not using admin, we are using user's library and as well, I am going to skip the styling. So we have public style already and as well we need a selector. So I will put users login as a selector because I have users, I am inside user's library, so the prefix will be users and then skipping the tests. So we run this component or this comment, and we will see that the component is created inside user's library. So we have here multiple libraries, if you remember, one of them is users, and we have here pages. One of them is a login page. The login page which I am planning to do is this one. So we have here like some image and also like some welcome shop admin, username or email, password and submit. And then we have here the empty space. So let's create the layout for that. We are going to use the prime energy grid system to create all of this layout. But first, let me talk about the routes. Here we have routes. So also when we are going to have a login, we need a route to login. So how we can do that, as you remember in the admin application, in the app module, we have its own routes because those components are located inside this module as well, or inside this category as well. So we have here the components and that routes are located here. But as you remember that we created them login component inside the user's library. And for that, I am going to put the route here so the users will have its own route. It must not conflict with those routes because this module will be used also in the admin module, so we will not have any issue. So let's create first the route. As you remember, we have created constant which call it routes. This route has a type which called routes as well. And these routes will be an array of objects where I will put my routes. So first object will have a path which is called login. So when I put in my application slash login, then I will go to this component, which is login component, okay, now I have created here the route, and let's see if we are working fine. So my assume that when I put here login, then I will get login page. But as you see here, we've got error that doesn't exist because users module is not used anymore inside the application module, which is called a module. So here we have the application module. We need to call the user's module as well. So here we will have an addition of these modules. We will have something else which is called Users molecule. So we will have here users module, which comes from the library users and recheck that, that it's automatically imported. It will be here as a user's module from my workspace. So let's organize this code a little bit and put it here. Okay, Nice. Let's check again if we are going to work fine. So I will say login, okay, Still, I am getting error that this route doesn't exist. Why? Because if you remember when we created the routes here. The application module, we said something like router module, we call drought and module. And then we said for root, and then we call the route, which has parsers and component. We must do the same in the user's module. So here as well, in users module, I will call the route module. And this router module will have not fought root because the root is application. So the application will have a root. And this user's module is a child of this module. So we are calling users module inside our application module. So in this way, this module is a child and I want to use the authors of this child inside my application route. So I will say for child, and then I will specify that routes constant, which I have defined here. Let's save that and check if everything is working fine. I will go here again and I will say, Look in my login works. So now we are reaching the a component which we have created previously, which is called login component future, I am going to talk about lazy loading module. So we have here loaded the module totally, Exactly. So we will talk later about lazy loading, which is making the bundle size for lazy loading is the smaller, as we will see that later. First, let start templating the login components. So first of all, I am going to have the, this gray, the gray background. So I'm going to have a login container. So I will have, for example, div, and I'm going to use this lock-in and also in register form. So we will have login register and login register div will contain also the panel, the panel which will contain this white area. So we have here all the registration and here we have a panel. So let's create that. So I will create another div and I will give it Login Register panel. And then I'm going to play with equity. But first, you remember we have created public style. So we can use also this style or this classes in our public style. So first of all, I'm going to have here the user's library, if you remember, we have created a login register and users and users is called in the application level, but here we are not calling it, so we need to call the users as well. So here we can say clips and then import the style which I want to import, which is lips, users and user SCSS, because we have here calling all the components. But here let's delete this one because we are going to make only one, for example, for a login and registration. So we can call it login and register. So first-class of this login register will be this one. And then inside that I am going to have panel. So as you see here, we have here like some gradient, It's going from black to gray. There are many tools for creating gradient. You don't have to do it manually, you can copy them. So I'm going to do that which is called CSS generator and CSS3 generator, you can choose what you want. For example, you want a gradient and then you can specify the gradient which you want to create. And then you can copy all of the CSS and then use it there. For me, I have collected some gradient, which is exactly for our case. So I will have here the gradient from gray to black. As you see here. We have already defined that and we save everything. We still, we have error. It says the file doesn't match the style because here we have said that look in only so we need to make it login and register. And they did this one because we don't need it anymore. So let's save that. And then we will see that there are no gray background because we must define a height. So we need to say that the height of this page or this div will be 100%, or you can use VH, so we say 100 of a view height. So in this case, we will have the height exactly how we want. We have here the gradient, and then as you see here, we have a white panel. So let's create this panel. So I am going to do, I want to have a width of this panel. So it will have, for example, 650 pixels. And as well it will have a height which is 525 pixel, is how I measured it, and background color will be white. You have also the option to use in a prime NG a lot of colors, and those colors are defined like this here. So if you just inspect in any element, you will see them down here. So you can use all of those colors. For example, the white is suface a. So I would use this color is better for making all the code unified. So I will say here var, so phase a, okay, let's check that. Okay, we have here the whitespace is created, but we need to put it in the middle. So how we can make the things in the middle. So I will have here position absolute, and then I can position it like. Left to be 50 percent, like in the middle. And also on from the top will be 50 percent as well. But we need to give margins. So as you see here that it's got some margin, okay, it went down, but it's too much because as you know, when you put something in the middle, you have to have to measure minus half size of the panel. So we can say, for example, you can make it like this. You can say Calc 2 percent minus half of 650 is 325 pixel. And then it will be in the middle. And also we needed in the middle of this green from the top. So we can say as well, Calc 50% minus 525, let's say for example, it's 260 pixels. So in this way, we can say that this can be in the middle, as you see here. And when you resize the screen from the height and the width, it will stay in the center always, okay, inside this panel now we are going to have half image and half the content where I have to put my phone, it felt so we need a grade. So the grid will have column, you know, that that grid has a 12 columns. So the grid would be located inside the panel. So we will say that give me all of this as a grid and give me six columns for the image and six columns the content. So let's go and do that. Inside the panel, I will give div, which is has p grid. And inside the grid I will have also another div, which will have P minus column and six, because we have six columns for the image. And inside that, I am going to put the image itself. So I have imaged defined and I copied it in the assessed folder, but Assets folder of the application. Because here we don't have assets folder. So you need to specify the application which you would get from the image. So in the admin application, we are going to place in the assets folder our image, we have images. And then I'm going to place the login photo here. So here we have to say the image source will be exactly in the assets folder. So assets, it will automatically take the application, they're running application assets folder, images. And then we can say login. And we save that. We checked it. We see, okay, The image is placed exactly in that place. So now we do the second column which will contain our form itself. So I would say div dot again the column 6. And then inside the column 6, I'm going to have, as you see here, that we have a title and then the form itself. So we can't simply say that I want to have h3 for the title. I will say welcome. And also I want to have H2, for example, login page. And then we have to save that. And then we will see that we have here welcome and login page. And under them, as we saw that we need to create the form. So here we have to create a form. So I would define another grid. We can say like this, you can't consider the grid as a row. So here again, we can say div be called 12 or yeah, because we need them under each other. And here I will place the first component, which is like the email component. And as well, I am here, we're going to place the password. We need to place that submit button, but sled do something. Can you, for example, if you remember, in prime NG library we have components like this. We have this icon and then the user. So it would be great if we do the same to use this component as well. So we have here input group, and it has user and username, so we can copy the same for that, or we can name it as email. So we have here user, place holder will be e-mail and the same will be for input-group, but we will put password and the password icon, as I know, it's locked. So this group has a span for the icon and as well the input itself. Let's check our page. Okay, we have everything, but it's not styled because I think we didn't get the styles from Prime NC. I would tell you why. Because we are here in a new module and we are working in a component which is not in the application module. So this module cannot see the modules of prime and G which we imported in the application level, in the admin application, like those ones. Because we need to import them there as well. Later when we do refactoring, we will see how to create one module for that. And then we can call this module for all prime NG modules. So we can't be used as well everywhere. So I think this one is using input text module so we can use it as well in our users module. So we go back to our users module and then import that module as well. So we would say here, input text module, good for me. As we see here, we are importing it from Prime energy input text. We check our application again and we see that everything is working fine. So, but we have like here some, it's ticking totally to the panel. Let's have some padding. So maybe we can give for this column, that container of the right side, more padding. So we can say padding in general will be, for example five. So when we save and check that, okay, we have now a nicer p-adic. And for the grid which is containing the controls or the inputs, we can give it also a margin top like four, so we can make space between the titles and also the form itself. Can also make it bigger. We can have it as six, okay, now it's getting better. So here we have now the title, the inputs. Here we have still it as text. So we need to change the type of this input password to be password. And then we need to call a button. And here the button we have created already or we have seen it already in their prime and g library. So we have here multiple buttons. So we need as well to import the modern module, which is end-users module. So we can have it here as well. You can create your own constant for UX module, but I think in users module we are not going to use so much you next module, we will have here on the bottom module and text module. So we again go here again and use one of the buttons. For example, let's use this one, the standard one. We are not going to make it complicated. I will call it submit or login is up to you. So when we save, we go here again, we will see that we have the submit button. You can specify the classes which you want as well for the buttons, a few, remember, so we want to make this button with full-width in the content So we can make as well. As you remember, in the description or in the properties, we have something called a style class. So we can give it a class as well. So we can say here, buttons type class will be full btn for example. And then we have to use this will be the class and give it a properties, for example, in the login registration. And here we can say the full btn, we'll have a wheat which is 100%. So when we save and we'll go again to the application, we will see that we have full-width button. Okay, let's add as well some validation. If you remember, when we want to add validation, we need to use a form group and the former group, we are going to use form builder for that. So first, we need to combine this form and use something called form-group. And the former group will have a valuable or the constant which is created in the ts file, which will have the form itself exactly how we did with categories, with products, with orders. All of this, we did that already and already explained. So I will give here a name which is called login form group. But here it's complaining that there is no input for foreign regroup because we need to import as well some modules, like four modules. And as well reactive form module. And those modules are defined in angular forms as we saw previously and we talked about it too much. So going back to ts file, I did that quickly. We have here the login form group, which we have defined as a formal group. I used the form builder service to build a form. And I have method here is called any login form. And the login form will be as email and password. And email has two validators, which is required and email, as we saw previously, and the password as well is required. Let's go back to the HTML and give validation. So first, we need to give for this component for control name, as you remember. So this one controller name will be e-mail and the error message, it will be exactly under this group. So we will have as well a login form to define it. So if you remember, we have defined a login form to make short cold. So we can say get login form. And this login form will return for me that this dot form group or login form group that controls to not have all of the sentence in the HTML template. So we can use only a login form. So a login form if e-mail is invalid and the form is submitted, then choose one of two errors, as we saw previously. The email required, then show email required when the email is, for example, invalid, then show that e-mail is invalid. Let's define is submitted form as well or variable. So as submitted by default is false, The same thing also goes for the password. We need to define foreign control name and font. Font or name will have password. And then I am going to have the error message as well. So the Submit button, we do not click because we are using prime n j component, we say onclick. So if you remember that prime NG has its own implementation for the clicking of its components. So we can say here on Submit gets defined as well, the onsubmit method. So we'll go here and say again that onsubmit is submitted, is true. So let's save everything and try that. Okay, we got the error messages, okay, the AML is also invalid when I put invalid email, but now it's valid. So now we have the login form. So now we have our login page. We will see how we can redirect the user to login page when he is not logging in, whenever he is going to try to put, for example here products or for example, when he is trying to go to the admin panel in general, we are going to redirect him to login page based on the rule, if he is logged in or not. Next, we will create the login service and we are going to submit the user to take the token from the backend. 126. Login Service and Retrieve the Token: Okay, after we have created our login component and login panel and the controls, we are going to create the service, the service, which is coming when I am clicking on Submit, then I will submit a user with email and password and get back the token. That token, which I am going to use to validate the user if he is locked in all not in my application. So as you see here on Submit method, we are going to call a service. And this service, you can use either User Service itself and you can define a method. You can call it, for example, login, or you can create a new file and a new service, and you call it users or authentication service. For me, I'm going to create a new service. So I will click on NX generator and then I will search for service and then give the name for this service, like auth authentication. Or you can give the full name and the project will be users. And if you remember that we have file structure there so we can put it inside services folder and we can as well skip tests so we can check now hear that, okay, the service is created inside the services under the name of services.js. Okay, let's create this file and then we go there. We will see that it's generated and we are going to use it. First of all, as we did with the users, we need to configure the login URL or the API URL. So let's copy this one, then pasted here and define a new variable. We call, for example, API URL mouth. And it will be the same, it would be users. So we can keep the same name as well. So as you remember in the back-end, we have created API which is called users. And these users contained as well the method login. So we aren't going to use the same API. Let's import as well that environment variable because we are going to use this environment variable as well here. So first service we are going to use, which is called login. And this login will have a name login, and it will accept email, which will be a string, and as well password, which will be as well as shrink. And it will return for me observable of what of user, because we are going to get the user with a token from this observable. So we need to import as well the user model, and then we need to use the HTTP client so we can as well use it in the constructor or call it in the constructor, and then imported as well from HTTP library in Angular. And here we say return for me a this dot HTTP post. And first of all, we post the URL and the data as we saw in the postman previously, it will be email and password. So we can as well here pass email will be e-mail and the e-mail itself. So we have object, the key is email, and that email is a value which is passed here. And as well, we have a buzzword which will be as well password. If you have the same name of the keys and the object you carry move also the key definition. You can just say email and password, and it will be known automatically by the post HTTP client. And here we are still getting error because we have to put the expected return type, which will be, for example, the user. Because we defined here that we are expecting user. And here as well, we need to say that we are expecting user. And in the postman is, if you saw previously, we got as well the user, which is the e-mail and the token. Let's replace this API URL with users. And now we have the login service is ready. So let's use that and try to console log what we are getting from the back-end in the front end. So I will go again here to our login component and then I am going to ask for the house service. So in the constructor, I will say a brink for me, the OSS service. So I would say here private of and then here it will be our fourth service. And it would be shown automatically and important automatically based on what we defined here. So we have here that out. And then I will say onsubmit, do that directly. We can say this dot auth, like our, our service dog login. And then we can pass the username and the password. So we need to create here an object which is containing username and password. Let's call it, for example, login data. And this login data will have the email. Which will be this dot login form dot email because this will be looking form group that controls and then email dot value and the password will be exactly the same. So we can define another member which is called also password. So we can say also give me the password field from the form and given for me the value of it. So as we see here that we have created the login data. So we can say here, login data dot email and login data dot password. Of course you can do that directly. You can say like I want to send directly the form data like this. And like this without sending any object. So we can do that directly. So you don't need that object total. So let's make that very simple. But first, we need to check as well if the form is valid, like we don't have any validation error. If this login form group dot invalid, then we just say return. So we don't need to do anything otherwise, continue and make for me they're looking. So as we said previously, this login will return for me and observable. It will observe the data. When there is data is coming, then it will be executed. So we need to make it executable. We need to subscribe to it. Then we expect the user data. And inside this user, let's console that in our log, so we say console log user. So let's try that out. We see that if everything is working fine. So I assume that when I am trying to look in, I will get data in the front that so here is my console. And I am going to have, for example, my e-mail. And then I will have the password. I will click on Submit. I will see that I am getting here the data with a new token, exactly how we did with the back-end. But if I am going to put like long password, I will get here error, maybe the bad request, which is the buzzword, is wrong. So we need also to show that here that their password is wrong because we are not seeing anything here in the front end. So we need to show the user that there is something wrong going on. So how we can do that? As you remember, after the subscription, we can define and edit. This error can become like this. And then we say that if there is error and inside this error, we can say console log for me, the error itself. So we can do that as well. Let's try wrong username and password so we can use it like this. And I am going to put some random name. Okay, I got an error and I have the error type here. So now let's show some message to the user. For example here that there is error or the username or password wrong. So we can show that exactly here. So we can go to the login form again and we can place another column. For example, here we can define another column with k, say div, the P call and 12 as well. And inside this p equal 12, we can define a small. And this small we'll have a class which is called P error. And this be arrowed. Email or password are wrong. But as we see here that we are always seeing this error because we have defined it as a span without defining any condition on appearance. So we can put as well here ng-if. So, we can say ng-if the form is submitted. And as well, we can define another variable which is called error, like authentication error. So we can go here and define this one. And by default it will have a value falls. And then when we are going to get error here, we can say auth arrowed is true, so we save everything. Go back to our application. Okay, we don't see the error message. So when I will put my e-mail and password then mice, I didn't get any error because I got the user and the token. But when I make mistake, for example, in the password, I get error and I got email or password wrong. But what if I get, for example, an arrowed but what not authentication error. Like some, some error which comes like with the server error because the server is not connected. So we need to specify the error status. If you remember, we have defined in the backend status of the error, but if there is server error in general, then it will give me 500. So based on status of the error, I can show here different messages. So here, instead of having this message, we can define also a variable. We can call it, for example, house message. And this message will be replaced with the sentence which we have created previously. So we will have here, for example, our message. And this message by default is e-mail or password wrong. But here we can change it based on the error. So I can check here that the error status. So we can't say HTTP error response. So we have here HTTP error response comes with a type or status. So when I go here and check the error, if you remember, we have here error response that type, and then we have here, okay, false, and then state 2s is 400. So in any way we are going to show the error if there is some error happened. And then I will say if error status equal to 400 or not equal to 400, then this dot OK message will be error in the server. So we can't say that to the user that he know that there is a problem in the authentication in our server. So we can say error in the cerebral. Please try again. Later. In that case, we surrounded all the errors or odd possible errors to the user. So it will not be any trouble for us when we are showing the arrows for the user. And in the same way, we need to say that this dot of the arrow, when everything is fine, then we have to hide it. So we say oath error is not seen, is false. So we can go here again and we can reload our application and try that again. So I will say, for example, found in your gmail.com, and then I will make, for example, a mistake. Okay, I got the error and then I will go into make it right, so we can do this. So okay, the error disappeared. So now I am going to make error in the server. Error not about username or password are wrong, but adult in their server when the user will know that there is error in the server and see this message. So we can go here to the user service and maybe we can or the authentication service, and we can make some mistake here, for example. So we go again to our application and try to login again. And then I'm going to click submit. Nice because I got different error, which is not 400. I got 404. And this gave me this message. So now we surrounded the user with all possibilities of the arrows. In the next lecture, we are going to see what to do with this user and the token. And we can store it and make some decisions on our application based on that token. 127. Create Local Storage Service and Store Token: Okay, maybe we are asking now why we are doing their login or why we need the authentication. The authentication normally goes when you want to prevent the user to go to some specific pages or do some requests to the server. For example, if someone comes to my application and then he said navigate directly to products, then he will see their products, but I want to prevent the user to do that. So he will be redirected directly to the login page and then I will let him login. And of course, when we are going to navigate when the user is navigating, we need always to it verify that he is allowed to navigate through my application or not. For that, it's not fair to make a new token or generate the token every time I want to navigate to some place. So every time I will ask the user if he has the token or not, and then ask you the backend validated and then send it back to the front and then I allow him to navigate to somewhere else. It's not fair and it's very exhausting for the server. So for that, we are going to store the token which we got when we locked in in the local storage. If our application, any website and any application has hear something called a local storage or storage. And in the local storage, you can use it to store a data of your application, which you need always to use to verify the user, for example, or if you want to store their cart as we see here, or if you want to set the current locale of the application, for example, some user has it in English and he set it, for example to French. And then when he went back to the website, he would not see again English, but he will see the French, the French which he started. So those values are always stored here. And based on that, then they user when he visited the website again, all when he navigate somewhere else, it will use all of this information which is used in the local storage. So the local storage, you open DevTools and then you go to application and you will see the localStorage. There is also the cookies that is as well the session storage. But we are going to use in this course, the local storage. So what I am going to do now first, I am going to save that token in my local storage. So when I log in and I have a successful login, then I will store that token in my local storage. So let's remove all of this data information. You can remove all website data easily when you go to a storage tab here in Google Chrome, and then you say clear side data. So when you clear everything, then you will see that your local storage is empty. Now, we are going, when we log in, we put the token in the local storage. For that, I would say also that I can make another service which is called here a local storage service. So let's generate that as well. So I will go here, generate, and then I will say service as we did previously. And the service would be repeated in services. And the name of it will be local storage and the project name will be users. And as well, we are going to skip that tests. We run it. We create the service as we see here, and we are going to make the local storage service. So how we can work with local storage engine and all that which I showed you. We can do it very easily, do with standard JavaScript and Luke and storage if you Google for it in the browser and you go here to MD and web docs, you will see that we have something called a local storage. And these local storage, it has some methods like set item and get item and remove item and clear in general. So let's have an example. I'm going to create a service method. We can call it, for example, here, after the constructor, we can say set item. And set item will ask for me for a data. And then I can't say exactly directly local storage dot set item. And then I can specify the key. So for example, I can say token and then I will give the data as a value. So then we can use this local storage service anywhere. So let's use it after we have a logged in or success locked in. So for example, after I make a login, then I will go here and I will call their local storage service from here. So we can say here, private local storage service. And then it will have a type local storage service. And then we can use this local storage service here. So we will say that after that, this local storage service put set item. And I am going to specify the data. For example, I will store the user dot token, okay, we save, and then let's try to log in and check our storage. So we go here and I am going to have my email and password. So after I click Submit where I am going to lock in and call logging service, then I must he here the set key of the token. To be with a value of the token. So when I click Submit, as I see that I have successful network and then I have write name and password, and then I retrieved that token. So from now on, we are going to use this token to verify the navigation of the user without asking for login data again and again, every time the user is navigating somewhere, I want to see if he is allowed ordinal than I will ask for a new token. Now, we can ask always the local storage token. And as you remember, this token has expiration time. So when it's expired, then the user will not be able to navigate again in the application only when he logged in again and ask for a new token. So what we actually need here, we need a set item and as well get item, like we need to get the token back. So we can say the return value will be a string and then it will return for us local storage dot get item, and it will be what? The token, and we can do also add remove item. So remove item, we are going to use it or we remove the token when the user logs out to as well. Here I will say local storage dot remove item, and here it's not return is just normal method where it will remove for me the item. It's better than to rename those not set item but setosa because we are using only one key which is token, and specifically for the authentication. So I'm going here to say that set token and as well here and get token. And here, remove token. So it's better like that. So we can use this service outside and anywhere in our application. And it's always nice to define a constant for repeated strings. So for example, I will say here const, for example, will be token. And this token will have a name JWT token. And here, which would be always, the constants will be a capital letters. And we can replace this token here. So to not repeat the same string, we can say always a constant and we can use this constant and rename it. Or do we want whenever we want to rename this key? So let's save that and try again. We have still the token. And if I have to put my e-mail again, I will see that I got error because here we need to call not set item, but we will say set token. And then we save the e-mail again, we submit, and then we will have here that JWT token. So we need also to delete this one. So let's make a start clear so we can clear the data again. And then we will not have anything in our local storage. So let's try again to submit. Okay, nice, we have JWT token and in this way we are going to use this token for guarding and protecting the URLs. And that equates to the backend. 128. Create Admin Panel Route Guard: Okay, in this lecture we are going to see how to guard the admin panel. Like we have to protect the admin panel from users who are not authorized or authenticated to log in. But first of all, normally after we put the username and the password and then we click on submit, we are getting redirected to the admin panel if everything is fine and our username and password, right? So we can't do that after Submit button or click on Submit, then we can redirect the user to the application or to the admin panel application. So how we can do that, we can go here to the login component. And we see that we have previously created the login authentication. And after the user is getting at open. So we can call the router, the router, which is letting v to navigate to a new page or to the homepage of our application. So we can't call here the private router. And this router will have a router and it will be imported from Angular. And then we are going here where we have a successful login. Then we say this, the router, and then I can say navigate, and then I specify the URL in the array. So we need, for example, the homepage. We don't need to go to any sub-pages. So we go to the homepage when we are logging into the application. So let's try that and then go here. We can say, for example, email, I will put my e-mail and the password, and then I will click Submit. So we click Submit and then we see that we are redirected to the application or to the admin panel. We have here whitespace because of the routes. We are going to organize our routes later for making it to go directly to the dashboard. So as you see here, we are able now to navigate through the application. We have problem here. I'm going to delete the token from the local storage, so we will be considered as not locked in. So when I navigate, I am still able to navigate through the application. Even I don't have a token. Or for example, let me reload the application, go again to the login page. And then as you see here, we are in the login page. So if I go to U R, L and I say orders, then I will go to the owners page. So this is wrong. We need to login first and see that the user is really locked in. Then we allow him to go to orders or two products or to other pages. So for that, we need to create something is called guard. And guard actually is a service. You can pass it to the routers or to the routes which you created. And then you can say protect this route until the user has approved something or has the user did something. So we can do that very easily. So when we go to application module here, so as you remember, we have here the routes. So I can't say that route, route, I say can activate. And then I specify something called guard. And the guard is actually a service and the service which is observing always the routers and see if it's allowed to enter this route or stay in place without moving to a new route. So let's keep this as empty and we go to create our guard. So first of all, I will go to create the guards in the services in the user library. So here we are going to create a new service. So I go to the NX module and then I say generate for me a new service. And this service will be located in services folder and it will be called mouth guard. So we call this service as our mouth guard. And then I specify that project will be users because we are putting it inside user's library and that's it. So we can also skip that tests. So when I click on Run, I will see that the service is created here as old guard service. You can remove this suffix. For example, you can say only like off guard without Asgard service, you can say only off guard. And these are the guard will implement something from Angular, which is called can activate. And this is from Angular router. So this can activate is a method which is always observing for me the router and return true, then we allow that we are going to a new route, or it's false, two 4-bit going to that route. To understand it more from me, I am going to create this can activate. So for example here it's saying the error that the class are off guard is implementing can activate, what can activate method is missing. So let's create this method because when you want to implement some class or extend something from class, you need also to do the same methods which are. Created in that class. So when I go here to can't activate, I press Control. I see that it has interface and this interface has a method which is called can activate, and this method will accept route which will be activated snapshot and also state. And it will return for me observable of Boolean or a promise or Boolean itself, which is clear. So we can also copy this method. We can take it here and go to our mouth guard, and then paste it here and open the implementation for this method. So we need to import some stuff. For example, activated wrote snapshot, that's important. We control dot or contour space in Windows, and then we would see that it's imported here automatically. And another one we need also to import it. Okay, it's giving me an error because this method is returning a Boolean or observable of Boolean or a promise of Boolean. So we can return like simply like false. And then we need to export this method so we can use it in the application level. So we go here and we say that export from Lip services. And then the guard which I have created, we save and I am going now to our application module. And then I would say, use the mouth guard which I created. So here we have the Asgard and it would be imported automatically from users library. So let's scroll down and we will see that we have protected this path, like the route add its children so we cannot access any child because this off guard is always returning false. Let's see that. So as you see here, we have a white page because I am not able to access anything but for example, login, okay, I can't access login. But if I put, for example, something which is children of this route, because here we have categories, orders, products, et cetera. So I'm going to put one of them because we have here products. And then I will get wide page because I'm not allowed now to enter because can activate is for bidding me to enter because it's returning a force. So when I send it back to true and then save and try again, we will see that we are able to log in and see the admin panel. But when I set it to false, I will not be allowed to enter there and I will get a white page. So we are very close. So now we are allowed to go to the login page because we didn't include it in the guard. Because if you remember that the login page is located in users module here. So we have the login route outside of gardening, so we don't need to guard it or protected. So I want somehow to not be directed to a white page or to some page which is not defined. So I want to be redirected to their logged in when I am not allowed to enter that route. So when I put here something like product or the user is trying to access directly through URL. I want to send him to the login page back. So exactly the same. We use this guard exactly to do what we want. So when the user is trying to do something with their links, we are managing. What is the result of that. So we can do that very easily. So we can say that also, we need to redirect the user using the router to the login page. What I am going to do here that I am going to import again a private router. And this router is coming by angular again as we did directly in the login. And as well, I am going to say that navigate for me to login. So when I say this one and then go again and I try to enter, for example, two orders. Then I will get three directed to login page because I am not allowed to enter to that wage. Okay. When I am allowed to enter, I am allowed to enter when I have a token with a valid expiration time, and then I can allow the user to enter to that page. In this case, I want to get the token here somehow and then I will return false or true that can activate based on the token data. So if you remember, we have stored the token in the local storage. So we can use again here our local storage service. So I say private local storage token, bringing for me again that local storage service. And here I am going before everything. I want to get the token. So I will say const token and then this dot local storage service and then get the token. So here we have the token. So I am going to check if there is token in their local storage, like it's not empty, then allow for me, the user to access that page and send it through two can activate method. So I will say here, return true, else router dot navigate to login page and return false. So let's try to save that and try again. So we are here, I am going, I have here that token. So when I try to go to products, I must be able to see the products. Because we have token here. I will say here products. And then, okay, perfect, We have the axis. Okay, let's try to delete the token and go again to our login page. And then I deleted the token. So when I read the token, I will have nothing. Then it will rename the direct me and return false. So I will say here products. Okay, I came back to Logan. So this is how we are protecting the route. So the route itself is protected in the app module application, as you remember, we have here with the mouth guard. So all of those routes are protected based on can activate what it will return for me, true or false. So when I go here, I check if there is token, and then I say, okay, login. But now in this case that if someone come here, I feel like some DVT token, exactly like the key and I put anything, then I will be able to go to the products page. Because I said if there is token, I didn't see the value of that token if I am allowed or not, if I am admin or not. And this what we will see in the next lecture, we need to read this token and analyze it. And based on that, we allow the user to enter to that page or we read direct him to the login page. 129. Read Token Data isAdmin and Expiration: Okay, in this lecture we are going to see how we can verify if the user is admin or not. As I told you here previously, that we are not doing here a user security, we are not doing application security. The security itself is going when we are intercepting the HTTP requests, like get product or get orders or post product or post orders only with a token. So normally any client can access my API without token. We will talk about this later. But now what we are doing is just a user experience. So I am just leading the user if he is logged in or not. And if he is locked in, he can see the admin panel. If not, he will be redirected to the login page. So let's analyze that token which we got from here. So if you remember, we created this JWT token and in the back-end, we embedded some data like the user ID and also if he is admin or not. So when we go to JWT dot io and then we put our token here, we will see that we get here the user ID and if he is admin and also expiration time. So we need somehow to decode this token in the front end. And then we find out if they user logged in is admin odd lot. So let's try that now. So first of all, I am going to use a method which is called AT or B. This is like for decoding the strings of data which has been encoded based on base-64 encoding. So let's see what we can get here. So first of all, I want to decode this token. So if there is a token, then make for me a constant, call it token decode. And then we are going to use that method is Javascript method, so we can use it directly without calling any library. So I will say here token, and then we will see what we get as a result. So let's console log as well, this token decode to see what we have in the console and what that, or what decoded token will return for me. So we save and go to our application and check our console. So if you remember, we have already logged in here so I can go directly to orders for example. And then I will get here something we will see that we are getting error is called invalid character error. This because that the token is consists of three parts. First part is called the headers, which is specifying what type of the token and also what the algorithm is written or generated this token. And the second part will contain the data, as you see here, the color is matching. So we have here also the data which is coming inside the token. And the third part is for verifying the encrypted token or signature of the token. We are interested about the second part. So we need to split this token based on the dot. So after we split it, we get the second part. So first of all, we need to split. We say token dot split. And then based on the dot. And as you remember, the split will return for me array of three items. So first part and second part, which is containing our data. So we are going to count from 0 to two. So we want the second part. So here we have now splitted the array and we are going to take the part and decoded and read that token in that way. So after the coding and go back to the application, we will see that we are getting also object user ID is admin and also initialization time and expiration time of the token. So exactly how we got here. So first part is for the headers, and second part is for the data of the token. And the third part is for signature and verifying the signature. So we got actually those data, which we are interested in. So now we are ready. We are reading the token as a JSON. So we can take also this part, all of it as a JSON. So we can say JSON dot parse. And then I can read all of this as a JSON object. Then I will be able to read the content of this token. So we can't say if token decode dot is admin, like the user is admin exactly how we send it from the back-end and then we return a true. So in this case, if the user is admin really, then he can access the admin panel. If not, he will not be able to access it. So let's remove this part and check if everything is working fine for us. So I will go and try our token after I save. So I will go here to the login. And then, okay, we have here everything. And I am going to log out by removing this token minorly, and I am going to log in again. So I will say my e-mail. And as you see, I put here my email and password and I'm going to click Submit. Okay, We are really directed because I am admin. I will try another user. So we will have one user which is not admin. So I will go again to the login page. So I will go directly to the database and then I will change myself to not be admin, but I will be like False of admin. And then I will click on update this row. So after that I got updated, I will try again to login. Let's see what we will have. So I will put my email and password and then I would click Submit. We see that, okay, I got that token, but I am not able to login as you see here, because I am not admin, because is admin is not coming with that token. So to be sure, I want to show you so we can copy this token and put it here. And we will see that is admin is false. So in this case, I am not able to log in anymore. So let's put it back as a true To be able always to log in. So in this case, I distinguish between the customers and not customer people. Maybe someone will come and tell me, okay, I can create a user ID and is admin. And as I create a token like this, exactly. And I pasted in my local storage and I try to go through the link, I will tell you, yes, of course you can do that, but you will not be able to send requests. You cannot take product, you will, you will go to the admin panel, of course, but you will not be able to see any data. You will not be able to send any requests to the server. Because as we will see later, we are going to intercept those and protect APIs with a token. So as you remember in Postman, how we were always loading the token in the body of the request to be able to send that request to the backend. So as you see here, we are always loading a token with every request which I was doing. So in this case, we are protecting the backend. What we are doing here actually is just user experience. So the user will not be able to see easily the back end or the admin panel if he is not admin. So I set my myself as admin again and I am able to lock in and fetched data so we can as well use the expiration time. So a user is able to log in anytime to our application, anytime during the day. So if you remember, we have one day of exploration, we set it in the backend. Of course, you can set the token in the back-end as much as you want as we saw previously. So here I am going to check as well the token if it's expired or not. So we will say here admin. And also I am going to have a method which will check for me the token expiration time, a private method, it will be token expired. So here I will know that if the token is expired or no, so, and then we will say send the token decode and EXP, because if you remember, expiration comes in the x field. So I am going to create this method. I will show you quickly. So we have here to the method which is called token expired, and it will have expiration time. It will return for me Boolean. So to check the expiration time of something, you know that the time is coming for us as a print or as a timestamp. And this timestamp, we can analyze it by doing this method. So I can check if floor then get time. So all of this, like I am getting the time now, if it's bigger than this exploration, then the token is valid. If not, then the expiration of token has ended, so that token is expired. So in this way you can check the token if it's expired or not. Of course, there are also another ways like you can Google them. You can find them like using woman JS or for example, using another library which is taking, checking the token and send you back all the information which you want. Here. We did it with vanilla JavaScript. So let's try that now we save and we have now the token. Of course I cannot make it expire now because I am not like I created the token now, but now we set everything and we are able to use that token and we are valid users as admin, to look into the admin panel. As I told you, this is the simplest way of the coding that token, there are more complicated ways. In the next lecture, as I told you, we will make more security and so we will not be able to see any data if we don't have a valid token. 130. Enable Back Backend Authentication For API's: If you remember at the beginning of working with the admin panel, we have disabled in the back end the authentication for our APIs. So how we did that, if you remember that we commented out all the authentication and we said that we allow everything. So in JWT file, in the Acme, in the back-end, I disabled everything and I said, Okay, a low for me. All you are to be unless we talked about that previously. So let's set it back. How all of APIs are secured except those. So we need as well to secure all the APIs. So we will not be able to post a product. We will not be able to post user or we are not able to get the users. So after activation, Let's try, for example, go in our admin panel to the users because here users is not included. So let's check that. I will go here again and check users. I will see that I got empty and I got error in the console that I am unauthorized. So we need to do something exactly like how we did with postman. If you remember, we were loading a token in the request and then we send that request. In this case, we get what we want, everything smoothly. So here we are going also to load this token, which we got after we logged in to this request. So the backend will authorize me to get the data from the database. So here what we are going to do in the next lecture. 131. Intercept HTTP requests with Token: Okay, As I told you previously, that we need to load that token over their request. If you remember, we were loading the token over their request in Postman, and we were passing that token in the headers of the request. That was very easy as postmen, we were just going here and select authorization. And then we say barrier token, and then we were wasting our token here. So the same way we are going to do here, but with Angular. In Angular, that concept of this is called interceptors. The interceptor is something which is observing all the requests which are going out from the front end and then checking if this request is going to the backend is API, then I load a token over it. Because as you see previously that the back-end now is done, allow us to send any requests without that token because we are not authorized anymore. So how we can do that easily? As you remember, we were using always NX tools. I am going here to generate a new module and there is something called interceptor. And the interceptor is something that will be loaded over the HTTP service and then it will load the token over it. So the way to do that, we go and we give a name, for example, GW t. And then we can pass it also in the services folder, which is located in the project users because we are going to use that in the application. And then let's skip this for now. So we can click on skip this, then we run this, and then we go to our application and we will see that we have JWT interceptor. Okay, let's see what is interceptor. Interceptor is implementing a class or interface which is called http interceptor. And inside this http interceptor, there is a method which is called intercept. And this intercept receiving a request and then next for handling, and then it will return the HTTP event. So for now, it's like this. So we need to load over the HTTP request headers as postmen doing to the HTTP request with the token. Because always we put extra data inside the headers. Every request going in your application is going over headers. So authentication token will be loaded over the headers of the request, as you see here, we have here for example, the headers request and I have authorization bearer and then the token. This is exactly what the postman is doing. So let's do the same exactly with our applications. So we will be able to see the users because now we are not allowed to see the users or orders because we are not authorized. So first of all, I will go here inside this method and then I will receive that token and also the URL. So the token, as you remember, is stored in the local storage. So first of all, I will define a constant. I will call it token, and I will use the local storage service. So the local storage service we used previously, which is also located in the same repository, all in the same folder of this user's service. So I will say here private local storage token. And then this local storage token will be come from local storage service. And then I am going to use it. So I will say here this dot localStorage darken and then getToken. So that's all. Then we have that token which we stored in the local storage here inside this constant. The next step is the request. That request is every request going from the front end HTTP request. Because if you remember, in our services we are using HTTP requests. So always we are using HTTP post HTTP, GET HTTP report, etc. So as you see here, we are using HTTP protocol for sending our requests to the backend, so we want to intercept them. So the u r l will be inside this request. So when I say give me the user data, then I will go and put the request. And inside this request there is URL, and this URL will be our API URL. Here we can say const is API URL. And then I will say that give me that request, which is passed here. And then you are L and then starts with, so if the URL start with my API, if you remember that we stored the API inside our environment variables, which is located in the environment file. So we can as well here we say that give me the environment. It will be imported from environments, environment. And then I will set the API URL. So if my API URL start with this URL. Then I will intercept it. So it means that it's a back-end URL. Okay, As I told you previously, we need to put that in the headers, how we can do that. So when we have a token, so I say when, if token and also when I have is API URL, then I am going to add the headers to that request. So I will say request will be the same request, but clone it like clone the current request and adjust the following. So we need to adjust this request to have set headers. As you remember, I told you that we need to put the token in the headers of the request. And then I would say authorization. And then if you remember that we are using beer authorization, so here I am going to have stream called bitter and then space. You remember you have to put space. And then I will put the token after it. So in that way, I am going to pass the token with a bitter authorization in the headers of any request. And we keep this next dot handle request. So okay, we save that and we check our console if everything is working fine, okay, everything is working fine. But now we need to export this interceptor as any service we did before, so we can use it outside of our library, of our users library. So we go here to index and I am going to say Export, and then from lib services and then JWT interceptor. So after that we save and then we need to use this interceptor where we are using the interceptor. You have a choice. You can use it here in users module because we are using as well the user as module in app module. Or you can use it directly in application module. So how we can use that? I will go as well here and I will check the providers which I am having, NG module declaration or import. And there is something called providers. So improvisers, I am providing service. I am providing some token. I am providing some variable to a service so I can use it. The way to use that is we say that we put a comma here and then we open an object and we say provide. And then HTTP interceptors. And as you see here, http interceptors comes from HTTP in Angular. So we use this one. And then we are going to say use class like as a default. We are going to use the class which one is JWT interceptor, which I created in the user's library. So when I go here, I will see that it's automatically imported as you see here. For example, if we go up, we will see that JWT interceptor is imported from users library. We say Multi is true. So after we save and then we go to our front end, we will see that we are able to see their users. So also, I can see the orders because here I have a token and then I am loading the request with the token. So as you see here, if we go to one of those requests, you know that we have here in the network. Okay, I have this one. I will check the headers I have here, get, and I will see that, okay, authorization bearer is my token, okay, maybe someone will tell me. Aha, okay, I can then generate any token and then I can send it with the headers of my requests and tendons through Postman and then I can destroy their website. No, this is not possible because if you remember, in the back-end, we had a secret. If you remember, I made a secret file which is called, for example, secret. You add it to the token, and then based on that, you have a signature of JWT token, and then it will generate for you that token based on that secret. So in that way, you will see that you are also sending this token and it will be analyzed based on that secret string which you created. If you remember, I put, I love my dog, for example, as a secret in the back-end. So now if this will be analyzed by Birkbeck and accepted by this secret key, then diabetic and your response with me with a data. Otherwise, if I send any token, it will not be accepted because it will not have the same secret which I created when I was signing that token in the back-end and send it to the front end. So be careful you have to keep this secret, really secret so you cannot use it anywhere else or give it to anyone because it's securing your application totally. So if you remember, we were using the secret, if you remember, and this secret is in environment file and I was using it as my dog is nice or I love my dog is depend. So you can put here any string. And based on that, all your requests in the back-end, we'll use that secret and then analyze. Every request comes with that secret, then over the token, and then it will respond for you if it's right or not. Okay, Now we have, everything is fine. We have loaded our token over the HTTP request. We are receiving and securing our admin application totally without any issues. So now I have the recap. If you remember, we made a security and we put that token in the application, in the local storage. And we are using this token to send that request and also redirect the user to login page if they are not locked in. In the next lecture, we are going to make the logout, which is only removing this JWT token. And then we will be logged out. 132. Logout User: Okay, great. Now we are going to see how we can log out a user. So if I click on this button, I'm going to log out the user. When we want to look at the user, we just simply delete this token from the local storage and then redirect the user to the login page. So on the click on this button, we are going to call a service called lockout. So we can do that very simply. We just go to Users library where we were creating our service or authentication services. We have login here. We are going to have as well the logout. So I will go here and say, give me a logout function. It will not have any parameters. We'll just look out the user. So for that we are going to use also the local storage service. So we need as well here to call the local storage service. So I will go here and say private. We can say token or token service, and then we can call local storage service. And this local storage service, I am going to use it here. And then this dot token and then remove token. So that's all. And then we are going in the front end to look out the user or you can looking him out here. So in that case, we need also a router. So I would call here private and then router. And then I recall the router again. And then I've, after I delete the token, I will say these dots, router, dot, navigate. And then I will select the login page. So I will say here login and then we save. And then we need to call the service whenever I click the button on the sidebar. So if you remember, we have that in their shared in Admin application. I have in the sidebar as well the button which is called lockout. And I will go here and say click. Like when I click on this button on this link, I'm going to look out the user. And what do we say here? Look out user. And then we implement this method. So we go to the sidebar also here in the component. And then I need to call the authentication service because it's used in the, OR it's created in the user's library. So I will say here, private auth service and then call for me out of service from the user's library. And we will see that it's imported here automatically. But sometimes you will be in mistake with the Auto Import that you will see that it's returning the full path. It's not making it like with the shortcut as we talked previously. So sometimes like it should be like, like these users. But as you see here, we have a problem. We have an error because I think that is all service is not exported. So to check that, we go again to our users library and check if we have exported the authentication service. We will see it's not exported. So we need to do as well here, Export. And then from. And then I will select the library and then services, and then our service. So here we will be able to see that in our sidebar component. So its better always for linting to have this shortcut path. So we have now the authentication service. I am going to create another method, which is we created here. So it's called lockout user. And this logout user will be located in the TS. Fine. I will define this method here and then I will say this dot AVS service. Then look out. It's that simple. And then the lookout, if I go to it, it will remove that token for me and then it would navigate me to the login page. Let's save everything and then we will try that out. So as you see here, my token is expired. So that's why I recorded this video after one day. So as you see here, when it's expired, I have the token II was already read directed to the login page. So let's look in again. So I will go here and put my e-mail and password. Now I am going to login. Okay, I logged in, I am here, I see everything. I see the orders users, that token is valid. Now I am going to click on the Logout. So when you click on the logo out here, you will be redirected to the homepage or to the login page. And you will see that the local storage doesn't have the token anymore. So this is how we are logging out the user. Everything is working fine. You can login again and then go to your admin panel application. In that way, we finished everything regarding the authentication. So now we are going to see how we can organize our code more. We are going to do some refactoring and this what we will see in the next section. 133. Dashboard Styling: Okay, after we finished the authentication, we are going to decorate our dashboard. If you remember, we have the dashboard page here. We are going to do something like this. So we will see that total orders and how many customers we have, and how many products and the total sales. If you remember in the back end, we implemented all of those APIs. So I can take them also from the database. So let's do that. First of all, I'm going to my original application where we have a progress there. So I'm going to lock in. Then we would go to the bathwater dashboard has dashboard works. We didn't do there anything yet. So we go again to our pages in our admin application, and then we go to the dashboard. The dashboard, if you remember, we have created component like this, so we need to refactor it. We first delete the styling. We don't need the styling because we are going to use the public styles, which are folder of our styles here. So first of all, we are going to template this dashboard. So as every admin page, we are going to do the same. So first of all, I will have a div and it will have admin page. And this admin page class is implemented already. So we are going to have as well here our card as we did previously. So we can have here a dashboard as a title and a sub-header. We can have like latest updates. So let's remove like this, like to not make it as input. We can make it only appeared string and pure input. So we have here the dashboard. So I'm going to have agreed, if you remember, we have here four rectangles. So we need exactly a grid. So let's go and do there. And we say div dot py grid. And inside I will have the UV dot py call and then three. So we need four of this. And again, I am going to use that card inside. So we will have as well here another card. And inside this guard, we are putting our item. So the item which will have exactly the same, which will have icon, and some title and some number. So let's do the same. So I'm going also to define a div. And this div like a name, we can call it the item, like dashboard item. And then inside this item, I will have another div. I will put first the icon. So for example, let's have icon of the shopping cart, like four orders. And again, a span where we are going to put the name. So we have here the span which is called orders. And then we will have as well another span which will contain number. So we can say like hard-code a number which is like 25 for example. So let's see if we are doing well. Okay, we have now this card, we have the icon, we have the text and the number. So let's tie them. First of all, I'm going to have a background I'm using some website is called a gradient dot io. And it will give you a lot of very great gradients. You can use them and you can just copy the CSS of the gradient which you want, and then you can use it in your application. So first of all, I'm going to make a gradient, this one. So let's go here and go to style our application. So first of all, we need to have a style file for the dashboard. So if we go, if you remember, we have every, all the styles here. So the styles app, and this is dashboard, which is used only in the admin panel. So we can put it inside the admin application. So we can't say here the dashboard dot SCSS. And then we need also to import this dashboard in the admin because we are using this file. And this file contains all the files which we are used here, and we are using it in the application. So if you remember, we have here also Styles folder in the application level. So I will going and using the admin SCSS file. So we need somehow to import as well the dashboard file. Remember we have the shell. Now let's import as well the dashboard. So simply we replace this with dashboard. Okay, Let's go now to our dashboard. Let's make clause others. So we don't have anything here. We can have only the CSS and the dashboard file, so we need only those two files. We will work with that. So first of all, I want to style the dashboard item. So the dashboard item, we'll be in my opinion like a flex so we can align the things inside this Flexbox. And also that we need to align every text to be centered. So it will be all text inside this will be centered. Okay, let's give all saw a gradient. So we can, for example, copy this gradient here. And I go to my CSS and I just paste and I would get exactly the CSS style which is assigned here. So we load our application and we see that it's only styling inside the div, but I want the whole card. If you remember, the cart always comes with something called class style or style class. So the card itself need to have some style. So we can hear have style class. And this time class will be different from card to card, as you see here, because we have them different. So we need a gradient for every card. So we can give it like a name. So we can say the orders. For example, I am going to have a special class for this, which is called the orders. So here I go back to the CSS and then I create this class, and then I give it a name, and then I move these ingredients here. So I will put it here and then save. And we will see that the whole card is colored. And this is exactly what we want. So now we want everything inside the car to be white. So on the item I will say color. And if you remember, we were using vars. And if you remember that we have a variable which is called surveys, or you can use simply the white color. So I'm using the vars, which I talked about them many times previously. So we have here the surface color will be white. And as well, we need to have that justify the content between those items inside that the item or dashboard item to have space between them. So as you see here that we have different sizes or fonts, or we have this big, for example, this size and this size. So let's give them everyone in class. So I, we gave, our eye will use a class of this and I will give for this like for example, a name. And I will give for this class we can call it in general number. So here we are going to style those. So first of all, I want to style the icon inside that the item I will give the PI and then I will say font size, well before EM. And then we give it like a margin-bottom just to push the content under eight, like 15 pixel. And as well, I'm going to give a size for the name. So font size of their name will be, for example, 1.4 AM. And the number will be big a little bit. So I will give it like for example, font size will be 3M. For example, we can give it a 3M. And as well we are going to make it float, right? So we can put the text on the right, but okay, let's not do it now. I will show you later. So we save this one. We check that everything is like resized, okay, but as we see here that we don't have the color, I don't know why we have color, suit, face. I forgot one liter. So then we will have the white color, hopefully. Okay, we have now the white color. But as you see here that we didn't get any effect. So maybe I can group these two items like the icon and the name in one div. So this will be like for example, in one div, I can remove this one and put it and make this span alone. So we will see that the flux will be divided between this span and this div. So it will be divided between them. So as you see here, that the flex gave me the ability to have here the orders and here the number. To simplify the code mode like to not have this div and this div and put them inside a div to be in new lines, we can just use a simple HTML like weekend, say a BR here. Like we can put a brake line here. So I'm just doing it very simple. Of course you can do it in a way you want. I just want to show you how we can style quickly. We see as well then this number is like a little bit high. We can put it down like a little bit. So we can give margin top to this number. So we can say here, that number give it a margin top about 50 pixel. So we will see now that we have our first item. So we just need to duplicate those items to have four other, like the user products and total sales. And then we give them different gradients. So we do that quickly. So first of all, I will duplicate this column because we have here column three and another one, another one and another one. So we need to have four. So first one, it will be products, okay? It has a number. And also the products will be, for example, a brief case. And if you remember, we want to give a different gradient. So we need to put here as well a product. So the card will have a different class from the other one. So as well here we do the same for users and we do the same as well. Like we give the icon will be users. And also here the dashboard item users. And as well, we need to have here total sales. And we can give here, like we can say the icon is dollar. I am getting the icons from Prime NG as we saw previously. So we put here total sales. And as well, we need here have a number but in dollar, so we can use as well the pipes which we talked previously about. So I will have here a string like 120, and then I will use the currency pipe. So we save everything. And we go again to our application. We will see that we have the cards, but we don't have enough or the gradient. So let's copy the same gradients which I created here. So to do that quickly, I also selected some gradient, as I told you previously, from the website. So we can save that and go again to our application. And we will see that we have here the colors as we assigned here. As I see here, that the font is a little bit big, so we can make it smaller. So for the number, so we can make this number to have, for example, 2.5. It would be better, I guess. Okay, now we have everything is fine. We have decorated our first page in our dashboard. So we need as well to replace these numbers with the real data which comes from the back-end. And this what we will see in the next lecture. 134. Dashboard Statistics Services: Okay, As you see here, I grabbed all the data from the database based on our services. So how I did that, but the solution, I attached it, the code with this homework and I am going to explain it quickly. So first of all, if we go to the dashboard component, I have called multiple services, one for getting the orders count, the products count, and the users count, and the total sales. And then I didn't say like separately, like okay, this dot subscribe and give me the order count and then product dot subscribe and give me the product count, like how we did previously with many places here in the forums or with the categories list, for example, as you see here that I was subscribing to this output of this getCategories. And then I am assigning two categories to display them in the template. Know here it's a little bit different. I used a function in R x js which is called combine latest. And these combined latest, It's so great way to combine multiple observables. So when all of them ready, like it's, these are observables. When they are ready, then I subscribe to them and I will get array of the values exactly the same order of this array. So here I will get on the first member of this value, I will get the order count. And in the second product count, user count and total sales. And if you switch that, like for example, if you move this up, then the values will be different. So as you see here, the values, it will be an array. As we see here. It will be order count, product count, user count, and total sales. Okay? And then I assign these values. Class member, which is called statistics, which is an array. And this array, I used it in the template. I went here and I say, Okay, statistics, give me the first one, because as you remember, we have here, first one is order count. So give me the first one. And then dot order count. I will talk about this dot-product countered user count later. So now we have exactly how we get the values from the back-end. So statistics first will be product count, exactly the same order as here. And as well for all that cool user and also the total sales. Just one thing, like remember to have here, ng-if that if static sticks is full or I mean it have length, then display the component itself of all the dashboard page because otherwise you will get error when those values are not ready yet. Okay, let's go to the surfaces. So their services, as you see here, that they are called from different libraries. So I used here user service, product, service, order service. It depend where every function related to, for example, the order service. I went to the order services here in the order library. Then I said, give me the order count and it will return for me observable. And the type of it will be order count number. Why I have this? Exactly this because our API, if you remember, it will return for me an object, and it will be in that way, it will not return for me the number directly. It will be returned in an object. So I must match exactly the same income which come from the backend and I put it in the front end. So I will expect order count field with a value which will be the number. So the return observable will have this shape and also that get will be expecting this shape. So the same thing I did as well for all the other services. So we have here dashboard and we have as well the product count. The product count, as you see, it will come as well the same way because I am getting from the back end this way. You can also adjust that I will show you later and as well for the users and the total sales, the total sales is in the orders. So we have it also in the ordered library. So as you see here, we get also the total sales as a number. That's why in the dashboard, in the template, I said, Okay, give me statistics. The first value. And then the value will be object because here the statistics will have multiple values which are coming from those observables. And every observable is returning for me object. So I want to use value or statistics member of the static array. And then I will say give me the order count of it. If you don't want that way. Like if you want to do it in that way, only. I am explaining that just to show you how to make all of these changes easily in your code. So let's say that we are expecting the values. Directly, like I will get here, not objects, but the value directly. So how we can do that? First of all, I go to the get order count for example, and I would expect not ordered count, but I would expect only number. And as well, I would expect here only number. But as you know, the API will return for me the object, object itself. So this is wrong for me. So I will not get a number, I will get object. So I can map their return, which is coming from the API. I can change it to be a number only. So I can make this as a number only. So how will I can do that? I can get this and put pipe after all, all of these get. And then I say map. And I am going to import this map from our x js operators. And this is a spatial mapping, not like the map of array. It's mapping of our XJ AS operator which is coming from our x js library. So it will return for me that mapping and I can map the value as I want. So I will expect here to the object, which is coming like this way. So here or the count will come as object. And I want to map it a way to be only a number. So how I can do that, I will say that I have here object value for example. And then I will not return the object value. I will return object value dot. And then I will choose this one, the order count. So I say that, that this object value will be order count. So in that way, I need to say that this object value can be any order. You can specify the type directly how we specify it before. So as a recap, I used the map from our x j as operators. And then I expected object which will come from the API. And then I said, don't give me the object itself, but give me field of this object, which will be ordered count. The same thing we are going to do for the other parts. So for example, we are going to make for the users, Let's go here. And we would accept, expect that we will have not user count, but we will have number. And as well here not user count, but we will have also number. And then I will say dot pipe. And then object value will be not the object itself, but user account. Like because as you remember, the API will return for me the user count in object. So this is mapping of their return value, which comes from the observable. So in that way, I will guarantee that I will get the number because the backend shape object is like that. Let's import also this map here from our x j s. So we have here observable and as well the map from RX j as operators. Remember, this map is not mapping of array, it's mapping from our x js. So you have to put it inside a pipe off observable. So the same thing we are going to do also for the total sales. So we don't expect total sales like this, but we can expect map and this map were returned for me like this, exactly the same way. We are not making any change except this field as it come from the backend. So I will say here total. So we save everything. And then we try also to do that for products. I am going to do it quickly. So we will have here number and as well here we will have a number. And then I would use and import that map from our x js. So we can have here map and then I'm going to use it here imported. So for every service, we have to do the same way and place here the pipe and object value. And it will be not order count, but it would be product God. So we save everything and we check that everything is working fine. All of these steps, which I did now is just because I don't want to see here like dot and then order the count and then product count. Now we can just have the statistics and flood values which are coming from the back end. So we can here try and go back to the browser. And we will check that we are getting the values in the right way. As we see that we are not getting the total sales. Let's check the API. Let's see how the total says a returning. So maybe we have some typos, so we can have here total sales. Okay, let's check our API. We go again to order service. So where is the order service? It's here. And then I will say get total sales are, it's still order counts. So we can put total sales like this. And then we have also the API. Everything is working fine. We reload and go to the browser and check if it's working again. Nice, it's working again. So as you see that we have mapped the values which are coming from the back end to a single value after reading that object. So you have full control on the front end. Just match yourself with a back end and everything will work fine for you. The most important part of this lecture that, or this solution of the homework is using this combined latest. So you don't have to subscribe to one by one. We have very short code. We subscribe to everything and we put the values in statistics and we use them in the front end or in the template. 135. Routes Refactoring: Okay, in this lecture we are going to do some refactoring to our code. So first of all, let's do some refactoring for the route. So the route, as you remember, we have created them in the application level. So as you see here that we have in the app module, we have all our routes are located here. First of all, what we are going to do, we are going to create a special module for the routes and then make the dashboard works well. And also the other pages. Because for example, when I go here to the route and go to the homepage, I will see that I am getting empty page. So what I expect that I must have the dashboard directly. So I don't want to have a route which is called dashboard here. To do that is very simple. We just need to say that, okay, I have the parent is rude and I have the shell which is containing the content and the sidebar always. And then I want to have the dashboard not in separated URL, but it will be exactly the same as apparent route. So we can just remove this path from here and then we say Save. And then we will see that our application is loaded directly to the dashboard page. So whenever I go to the Dashboard, I will see that the dashboard will be in the homepage. So as you see that we have previously configured on the sidebar that the dashboard will have slash dashboard. So we need to remove that as well. So we go here to the shared and then to the sidebar. And in the sidebar, I would say the router link will be the homepage only. So we don't have to specify the page in that way. So I go here to products, go back to dashboard, everything is working fine. Okay, the second step, I am going to refactor the app module and put the routes in separated route module. Because as we see here that we have very big file for app module. So we can normally put the routes in separate module. So let's do that. As you know, that we can have multiple module in Angular application and those molecules can hold multiple components itself as well. Module doesn't have to hold multiple components. It can be used for importing some libraries such as UX module as well. It can be holding the routes itself. So we can do that with an X. You can generate a module or you can just use angular snippets. I just want to show you they're any different way for generating components and modules in Angular. So first of all, you can use Generate and then you can find module. And you will find here schematics, Angular module. And here you specify the properties of your module as we saw previously. But there is another way I can install also extension, which is called angular snippets. And this angular snippets, it's always following angular version, so it's always following the current version which you are in. So here we have angular snippets. You can install it and it will give you ability to generate components directly live in the code, as you see here. For example, we need a module. So after installing this extension, we can use it. So first of all, I am going to create a new file in the app level, so near the app module and call it up routing module dot ts. And inside this app routing, I am going to use the snippets. So I just have to put a minus. And then it will list for me some options from the snippets. So I will say Here module, as you see here. And then I collect Enter or I press Enter. And when I press enter, it will generate for me all of these items. And it will generate for me the naming and specified so I can give a name directly. So I would say app routing module. And it's by default importing some component which I don't need. So we can remove this component import, we don't need that anymore. And we have now the app routing module. So we can copy all of the routes here which we have. So we can copy all of them or cut them and then paste them in NG module behind AND module because it's a constant and I am going to use it. And in the same way, we need to import all of those components. So to import them quickly, you just need to press control space or control dot and then you will get all of them. So I'm going to do that quickly. As we see that we automatically imported everything and we need as well the, our mouth guard, which we have specified from users Library. And as well, we need to import the routes type which is coming from Angular. So now we have the routes imported. I am going to do exactly the same how we did in the module. So we need to copy this line as well or cut the slide. So we go here and take it. And then we go to the app module and we go to the import, because it's in the import, I'm going to import router module. And then we are going to use this routing module in application module. We need also to import our protein module in our application module. So in that case, we will have the routes automatically inside our application. Again, control space to automatically imported. And then we will have all of these libraries are not needed anymore. So when you save, we will see that we are grayed out. So that mean that they are not used anywhere. So we can also remove the unused import. If you get such an error in the console that okay, router outlet is not defined. This is because that app module doesn't have anymore the router module. Because of that, you can also make an export of the router module in the ARP routing module. So you just need to have in exports router module again. So it will then knows that application module is using the router module, which is used in AP routing module. And we can check again our navigation. We see that everything is working smoothly. And as well, we need to specify if the user, for example, went to undefined page, something like this. So what is going to happen? I don't want him to see a wide debate. I wanted, for example, to be redirected to the homepage. So how we can make this redirection to the homepage, It's very simple as well as you see here that we have multiple partners and the root path, but we are not going to use this route paths. We are going to create another pass. And it's very important to be at the end this path. So this path will be like two stars. And then we can say redirect to the page which you want. In our case, we want to be direct to homepage. And then you need, after having everything like Directory direct to, you need to have bath match and then full like I want to match exactly this path that out. So we can have here exactly that out. So we have everything, everything which is not defined here, then redirected to homepage. You have to be sure always that this is coming at the end. Otherwise, if you put it before, then everything will be redirected to the homepage. So let's try again and make some issue here. And for example, we will see that we got three directed to the homepage. So in that way, we have re-factored our routing module to have more stable application module and more clean. And as well, we are going to do another refactorings which are related to performance, as we will see later. 136. End Subscriptions for Performance: One of the important stories that the user or the developer is always falling in that memory leak. The memory leak is very headache for the application, especially in Angular. You'll need to have and be sure that you don't have memory leaks in your application. So what is the meaning of memory leak? A memory leak is like something you are creating, for example, an object. And this object is getting created again and again and again every time you visit, for example, some specific page. So for example, I go here two categories. I open new object, and this object is staying in their memory. I go and again back, I open a new object, and the old object is staying in memory. This is I am talking about object. But in our case here, the only memory leak that we have is the subscriptions. If you remember, we were using subscriptions for grabbing the data from the services, from the backend. And those services are always providing observables. And those observables, we were using them by you saying like We want to subscribe to something. For example, I have categories list. And if you want in the categories list component, you can see how we are opening a subscription. And if you remember that subscription is meaning that I am observing the values wouldn't when they are ready from this observable, which is GET method, HTTP method. And then I am subscribing to it to get the data from it. So every time I am visiting this component, I am opening a new subscription. And those subscriptions must be closed. There are multiple ways to do like subscription or end the subscription. One of them is doing like dot, unsubscribe, like immediately after you subscribe to it. So I get the data and then I unsubscribed to it. Otherwise, you can have, another way would use KMS and more efficient from our XJ as we do is called take until. And here you can specify a Bible. And inside this pipe is like we are filtering the data which are coming from that observable. I say take until and take until always from operators from our x js. Pick until is waiting for something which is called subject. And this subject, when you use it or completed, then the subscription will be ended. To explain more, like I am saying, big data, big data until something happens. So what this something, something which is called RX JS, called subject. So you can define and use objects very easily. Let's say that we can give a name to this subject. So we can say, and subs N subscriptions. And always a subscriptions they are giving like suffix with a dollar sign. And this dollar sign in that way, it will mean that I have here subject or observable. And this n subs will have a type of subject. And the subject as well from our x js. And always, when you create a subject, you need to say a new subject. And I'll always, this subject need to specify a type, as you see here, a generic type. So you need to expect something inside that type. So we can say for now any. So in this case we have n subs. So n subs will start executing whenever I visit this component, which is for example, categories list. So I open now and you subject pools, it's called ends ups. So I want to take this subscription of data until n subs finish. So when ends up scanned finish or how I can finish ends ups and subsequent be finished in this way. So you can't say this ends ups and then you can say complete. So in this case, I say that ends up finished. So take until ends ups like n subscription, which is happening here. So when we save, let's try that. We will see that we are, okay, we are getting the data. So after we got the categories, we finished the ends ups and we are getting here the, for example, the data. But as you see that we have finished their subscription on n, on n it, which is not so much good practice because on NDI, on Edit, if there is some delay from the backend, then this will be executed before this. And then we get the categories, and then there will be delay and the subscription will be ended before it gets started. So for you, for that, we are using onDestroy. So when the component is destroyed, what I mean, so when I got out from any component in Angular, for example, when I go out of categories list and I go to products, I will get NG onDestroy of categories component, which means that I am destroying the component directly. I don't need it anymore, only when I visit it again. So I execute the NG on it. Again. This is the lifecycle of components in Angular. So I want to add subscription when component got destroyed. So you understand me? I think. So here we need to use on destroy as well. So this component will implement on init and on destroy. So for that, we need to create a method which is called NG onDestroy. And this energy on destroy will do for me the work which I want. So I say here, n subs complete. So to be sure we can console log something here to see that how it's executed or printing something that categories destroyed. So if you want, you can save that. And then we go to Categories and navigate out from it. So here my application is getting reloaded again. I go out now from categories. I will see that categories is destroyed, so it's removed from memory. We don't have any thing there. So for that, when energy and is destroyed is completed and I don't have take until here. The subscriptions will stay open. And every time I visit the categories page, I will open you subscribe, subscribe, subscribe, which will cause for me a memory leak. So it's better to say take until and destroy this subscription when n subs is completed, which is actually happening when Nk of the constant won't get destroyed. So as you see here, that after destroying this component, we are finishing the subscriptions to have it more efficient. Sometimes people they say do that also, like take the next value, be sure that you have next. And then do, for example, that end of subscription or complete of their subscription. So in that case, you need to do that for all subscriptions which you are opening in your application to avoid all memory leaks which you have. For that, we need to do all of this for our, our components, which we did. And from now on, we are going always to use this ends ups to complete always the subject and finish the subscriptions. In this video, I am going to do the same for all components which we have created or for all subscriptions which we have opened to not make it slow video for you. And at the end you will see the section code, which is at that with everything with NG onDestroy and as well with Subscribe take until. 137. Architecture of the Components in the Repository: Great. Now we are going to start with our ND shop. Now shop where their customers will enter and C products and order some products. So if you remember, we have created the project repository in that way that we have one shop and for example, one internal blog application and the admin panel application. We have finished the admin panel application and we are going to start with the e-shop application, but I am not going to use that concept that I have one single e-shop, am going to assume that I have multiple customers as I am developing company, for example, am software company. And I want to provide my E-sharp to multiple customers. So to not repeat that code again and again, I can get the benefit of using the libraries. So for example, I want, for example, to use the login component and registration component again in another customer or in another shop. Of course, I can change the style of the login and then I will not repeat the same code every time I have a new customer. So I'm going to use this approach. So as you see here that we have NGI shop one and energy shock too. And I moved all the components from the end G-sharp one to be provided by the libraries like products and orders. For example, we will have the categories list, banner and product detail component and product list component that will be all in the product library. So in that case, when I create and you shop to, I can use the same components which are located in that library. So I don't want to repeat the coding again in every NG shop. And this will be all under one repository, which is called Blue Bits repository. And we would get the benefit of sharing the code among our organization. Let me explain it more. So for example, Google has the same login for all of its services, like Google Drive, Google AdSense, Google Analytics, you will see always the same login component is used. And this what I am going to do here, I'm going to use the same components or the same library with different services. I am providing for that. Back to our design. We will see that we are using that categories, for example, leased and featured product list. And those will be located exactly in the products Library. And as well, the login will be the same login which we used for the admin panel previously. So in that way, we are reusing components. Every E-sharp we are creating. 138. Preparing Structure and Styles: Okay, welcome back. We are going now to run the application which we need for any shop. If you remember, we have two applications. One is the admin, and the second is initially, you have two ways to run any application. You can only type in x serve, and then you can type the name of the application. For example, I have any shop or you can use also the NX console, how we did previously, like a serve. And then you can specify the shop which you want. So for me, I'm going to use a comment line and start our application. Here. Instead of having the admin panel application, we will have the front end or the end you shop application. Okay, their application is running successfully. Let's go here and refresh our page and we will see that we have what we did previously when I was explaining to you about the prime energy. So first of all, we need to configure the sum stylings. We need to prepare our front end. So if we go back to the design, as you see here in the photo, you will see that the website itself is in a container. So that container has a specific width. And we are going to put the whole application inside that container. So the application will not be a full-width application. So to do that, let's go here to our end you shop application. And as well we have here application. And here in the app component, we are not going to have directly the header and the footer, but we will contain them in some container. So we can create a div, give it a class, we can call it container. And inside this container, we are going to put all of those components which we are calling for our application. And this container, we can configure it so we can go to the styles of our application. If you remember, we have public styles and we have here and you shop at NDI shop is using some other styles. So for example, we can use some class that we can place it here. So here you don't have to import only, but you can also write classes. So for example, you can say container will have widths. For example, 1, 0, 0, 0, 0, 0 to 100 pixel. And as well we can give it a padding, like for example, 15 pixel. So from up and down. So it will have some specific width and some padding. So if we go here, we will see that the content is moved a little bit based on the configuration which we gave. So as you see here that the div container has this width and as well, it has some padding. Let's put it in the middle. So we can say that this container will have margin 0 out all. So in this way, we can put the content in the middle, as you see here. Of course, it depends on the width which you got from the designer. You can ask him audio can open the XD file and check the width which is provided there. The XD file for the design is attached with this lecture so you can use it as well. And as you remember in the design, as you see here, that we have a gray background, that gray background of the content. We can use the same gray background again. So we can use one of those colors, which are provided by prime NG because we have imported it already. So we can have one of those gray, for example, let's pick up this gray. So I will say give me here as well. A background color will be valuable and this variable will be surface 100. So I will put that and I would get this gray background. But as you see here that we don't have the, for example, the DV is not sticking exactly on the page browser because we have not normalize it. If you remember, in the admin application, we have used a library which is called normalize. So let's use it as well here. So we can put it on the top of our application. And then we can have like a great sizing of the container and initialized paddings for the configuration of the application. If you remember, we have configuration file. We have specified the font and the font size and also some initializing on that links. I prefer to put this as well under importing the libraries because prime N G is overriding some staff, it's overriding the font. It's overriding some configuration which we have made. So we can start here clear. After we imported everything, then we can initialize our application with specific font, and then we can initialize or start styling based on those configuration here. So we save that. And we will see that we have now better fonts. We have the default font size will be 14. And based on that, we are going to build our application. So let's clean up a little bit. So we have here header and we have here the content. So we can as well though here. And we have the router at in the pages, we have the homepage component. So in the homepage component, we don't need that anymore, so we can just remove it and save it. So in the next lecture, we are going to start to style the header. So as you see here, we have the header and we are going to style it exactly how we have it in their design. 139. Styling the Header: Okay, in this lecture we are going to style the header, the header which will contain logo, cert, and some links. So first of all, let's do some clean up. We are not using the components diet because we have the file which we are locating in the public styles. So we have here in the shop something called header. So we are going to use that one so far that we need to delete the one which we created previously. So now we can start with the header. So if we go back to the design, as you see here, that we can have the logo here and the search here, and also the navigation and some icons for cars and the user account. But how this located, how we can locate those things. If you remember that we were using a grid in prime end. And you can agree with a designer to provide you with a grid guided design. So how we can do that? If you want, you can just go to View and then you can say surely out grid in XD or Adobe XD. And then you will see those grid. We will have a 12 columns and all of those columns will be used exactly how we have them in prime end. So if you keep more eyes, you can see that the search is using four columns. And also there is here space one column, and then navigation has three columns, and this one has only one column. The banner is using the whole space. For example, categories. Every item is using two columns. And here as well, the same thing for their product item. We will see that we have three columns for every item. So in that way, you can have a good designer and the designer will give you the gridded system design, which will make for you the sizing easy. So I guess we need one grid line which will have three columns and four columns, and one space column which will have offset of this one. So we will have three column with offset 11 column at the end for those icons. So let's do exactly the same. I will go here first and I will open a tag. Normally the header comes with a tag called header, which is HTML tag. And then I will have a div and I will give it a class P grid. And this B grade will have multiple columns, as we talked previously. So first of all, we will have a div with a three columns, so p called three. And we will see how we will talk about responsiveness at the end of this course. So this one will have, for example, col md like medium sizes for three, but we will use now the general one, which will be a three columns only. And as well, we need another div, which will have for the search bar, which will have P call, and four columns, and another three columns with offset one to push it. So for the menu, we will have div P call three. And then we will have as well a class which is offset one. So we will say p offset and we specify how much. So we can offset only one. So we can have offset and then one. So in that case we will have one pushed line. So let's put like some words here. For example, here I put logo, and here I will put, for example, search. And here I will put, for example, the menu. And at the end we have one column for the icons, which will have P call and one. And here we will put icons. Let's save that and check our application. Again, we will see that we cannot resolve header component SCSS, yes, because we deleted it. We go to the ts file of the component and delete this line because we are not using it anymore. So we go back again to our application. We will see that we have logo, search, menu, and icons. So exactly how we specify those spaces. Now, let's fill those spaces. First of all, I am going to fill the logo. So the logo, I have already used it in the admin application. So if you remember that every application has its own assets. So we need to use the logo as well, which is located in the assets folder and put it in the application of Andy shop. So I will go here, copy the file or the folder all and say ND shop. And then I will go to the Assets folder and then paste the images here. So I will have a logo and the login photo which we need as well for the login page. So here we have the logo and I am going to use it in the header. So the logo simply we can put it inside, for example, a div. We can give it a class, we can call it logo. And inside the logo I'm going to place the image. So I will have here image and then it will have like some source, which will be the Assets folder. And then images, and then logo. And I forgot the name. It will be logo dot. Png. So we will have here logo dot PNG and the alternation will be local. And then we can save that. And we will see that we have the logo here, but we must have some specific sizes. So to style that, we can go to our application styling. For example, it can glow this one and we don't need the component. We can go here and specify that we have the header. And the header will contain what logo. So we can put here logo and inside the logo we will have image. And this image will have like some specific size. So based on the design, we can give a widths, for example, 160 pixel for the logo. So we can go here and check it. We will see that we have the size of the logo like that. So in that way, we have prepared our logo and then we are going to make this search bar. The search bar will be located inside this item or this column. So we will have here an input. And you can also make a separate IT component for that. For example, you can call it a product search. But I am going to keep it like this for now because we are going to replace it with a component as we will see later. So now we can keep it like this. So let's go and do the menu. We can also the menu, not locate all menu items here to not have big header. But we can also create a component. We can call it an EV. The name can be N, G sharp, NADPH. And this NG shop nav will be a component where it hold my navigation items. So let's create this component. For creating the component we can use also the NX console. So I will go here to generate a new component, and I will search for component. And this component will have a name nav. And the projects will be end you shop. And the style. Okay, I ignore the style and as well, we need to a lifestyle. And as well, the selector will be N G sharp nav. And we need to skip tests. And where it would be located. It will not be located on the root of the application, but it will be, it will be located in a shared and then nav near the header and the footer. So we can save that and check our application. We will see that we have created the nav component here, and it's automatically import in the app module. So now we can use this component. So let's save and check if the component is really rocking fine, okay, it has Navisworks so we can create or template the navigation now, which are normally their navigation comes in unsorted list. And this unsorted list, we can give it a class which is called nav. And then we can have LI and we will need three list items. And inside of the list item we will have a link. So when you click Tab, you will have it like this. So first we will have H ref. We don't need them because we are going to replace them with the router link, as we saw in the admin application. And here we can have, for example, home and we will have here products, and we will have contact. So as well, we are going to create a styling. You can use the header as well here, or you can create a separated file for the styling. So in that way, I'm going to create another file which is called nav ul dot SCSS. And this nav CSS will be imported in my application. So I will go here to MD shop. And then after the header and the footer, I'm going to call the NAV file. So after that we save and we go to the enough fight to style our navigation. So I will have here nav. And as you remember, inside the love, we will have LI. The list-style of that LI will be none to not have these dot near every list item and the display will be inline-block, so they can be near each other, not under each other like a list. And then I will give margin write about 15 pixel to push the items away from each other. So let's save and check our application. We will see that we will have all of those navigation items. So now we can style the links so that a link will have color and the color will be like a dark gray. So I'm going to use a variable which is called surface. 500. And then on whoever, I am going to use different color. So when I put the mouse on the link, I am going to use a different color. So for example, we can have here over on the a, and the a will have a color, which will be the primary color. If you remember, we have defined a primary color in the configuration and this color we can use it here. So the primary color we are going to use it always in our application when you want to change the theming or the coloring or the base color of the application. So the color is located here. So if I save, we go here, we will see that, okay, we have the navigation like this. We still have one problem that we need. Like somehow when we put the mouse, it doesn't look like it has a text. What we want to have it as a link. So you can change the mouse behavior here. You can say coarser will be a pointer, so you can make it like that. And then the mouse would be like a pointer. And for the router links, we need to add them so we can go again to the navigation here. And then we can say on this, we are going to the router link, which will be homepage. So it will be nothing. And for products we are going to use the router link, which is called products. And for contact we are going to use the router link, which is called contact. We save that. And then we can't check that we have the product list and the homepage. Finally, as we saw in the design, we have two icons here though. Let's replace them with the icons from the navigation. So here we can have the header and inside we have the icons. I am going to use a prime NGO icons. I have two icons. One is user, one is a shopping cart. But as well, those components or those icons will be replaced with the components. For example, the shopping cart. I want to show how many items in the shopping cart. So we need to replace it somehow with their component, as we will see later when we are going to work with their cart. But for now, let's style it like that. So as well, we need to have the stylings or all of them should be like a line somehow, because you see here they are not aligned together. So we can give a class for every item. So for example, we have here our logo, and here we can give a glass called surge. And here we can give a class like for example, navigation. And here we can give a glass, we can call it Tools or actions. So we can give it like tools. And then we can put like some margin top, some margin paddings. So to align all of them together, for me, the navigation is okay like that if I check it. So okay, it's fine for me like that. So we can just move that tools like giving edited with some padding top so we can have it aligned with the item. So we can say that this div will have padding, padding top, we can say would be 15 pixel or more until they are aligned together. So we can have this as 22 pixel. So we'd go to the header style. So we go to our header SCSS, and then we can go here and open a new tag. We can call it tools. And these tools will have, the banding top will be 22 pixel. And as you see here, it's aligned. Let's put some space away from each other of those icons. So as you see here that we have created the icons near each other. So I can access this class From the tools. So everything BI Insight Tools give it margin, right? Like for example, five pixel or 10 pixels. So we can say here dot py and then margin, right? For example, 10 pixel. So we can do it like that. And we will see that they are far now from each other. That's very great. So now the header for us is ready except the search. We are going to create a component, especially for the surge, and we are going to use it and put it in the products library. So from the products library, we are going to use the set component to search in their products. 140. Product Search Component: Okay, we are going in this lecture to make the search input. So the person that can search for a product when he put some text inside this input. But a different thing here that we are going to put it inside the header, but we are going to provide this component in their products library. Of course, you can keep it as well in the header component and you can use it normally. But I am going to do it here as a separated component which can be located and reusable somewhere else. So first of all, we are going to our code. First, we are going to replace this with something like a component which will be located in their products library. Something like we have any sharp but any shop nav is located inside the application itself, near the header and the footer. But this component will be located in the products library. So how we can do that? First of all, let's create the component. So first I go to the NX generate, and then I will use that generator, search for component. And then I am going to create in the components folder and a component which is called Products search. And this project will be products. And then we are going to skip the styling and skip tests. Everything like are we how we are doing always with every component and we can give their selector as products. Search. That is also an option which is called Export. I am not going to put it now, but I am going to show you the difference minimally. So let's create this component and then run this application or this common line. And this command will be executed in their products library. As you see here that we have created components folder. And inside this components folder, there is a component called search or product search. Simply, I am going to say to my application that use this component somehow. And I will go here to the header, and then I will replace this with the component which I have created. So we are calling the component in that way. But as you see here, that it's still undefined because it says that product cert is not known element. Okay? For that, we are going to use the product module or the products library. So here the products library has a module and it's holding components. To let the header or the application see those components, we need to import the products module. Okay, We go here and then to our application, as you see here, we have at module in the application level and we have here importing the modules. But the problem here that we have the product module is imported and even that we are not able to see the product search component. This is because we didn't check the something which is called export. So you need to export the component in NGO module. So how we do that? We go again to our products module. So I will search for products module, which is located in products library. And then as you see here, we have a declaration. And inside the declaration we are placing the component. But as well, we need to say that this component is exportable, so it can be used in another components outside of this module. So when we save everything and we go back to our header, we will see that, great, the product search is defined. So when we go to the browser and we check that we see product search work. So remember, always when you are creating a gun component outside of the application, like for example, in products library, you need to export this component, not only declare it. And to make that when you are generating a component, just check this one in NX console. So you would just say to export as well in the module, this component. Okay, So let's style this component. I will go to their component and place here. Instead of having product search work, we are going to create a div. And this div will have a class products search. And then as a design we have icon and near it a textbox. So first we need to have defined the icon and the icon as we saw previously, it will be defined like PI. And then I specify the icon PI, which will be searched. Okay, we have the icon and now we need to have input. And input will have a type of text, and then with the name can be search. And the ID will be as well search. We will see how we will use this search later. A place holder for that we can use find products. And we can give it a class which can be, for example, product search, like the same patent. And then we can say input. So in that way we can access that input easily in our styles. So for that, we are going to style this component. Let's call everything others. Like we don't need all of them. We just need this component and we are going to public styles again. But we're not in the shop, but in their lips because we have created the component in the library. So as a rule to myself, I am going to create the product search components dialing will be inside the products library. I will create a new file and I will say product search dot SCSS. And then I'm going to place that glass here and save. So we go to our application to see if everything is working fine. Great. We have here the icon and the text input. So first of all, we need to put the border, as we saw in the design previously, that we have here, like some gray area and inside it there is icon and then the text input. So the user will think that all of this is a text input. So to do that is very simple. It's just a playing with the SESS. So first of all, I like always to use the flex. So display flex. We let the items like the icon and the input to be near each other. And I am going to give it a background color, which is from the valuables from Prime NG. And it will be soon phase. And for example, 200 darker than the background of the container. And it has a border-radius like about 10 pixels. And we can give it a width like initially we can say 275 pixel as a design and we can give it a height to say, for example, 35 pixel. You can give it more. We save, we check again everything. We see that we are not seeing the changes. Why? Because we didn't use this styling file. So first of all, we need to import the style file. So I have to say Import, and then I will say the product search. So in that case, products is imported in anti shop as you see here. And then I will be able to see this diet as you see here, we have the gray box. So now we need to have an orange icon. So I will go again here to my product search. We'll access the icon, as always we do with PI because it has a class called PI. And I will give it a width which will be 25 pixel. And for example, we can, font size can be a bigger, a little bit bigger icon. So we can give it 1.3 AM. And then we can give it a color, which will be our primary color. So we save, we check that, okay, we have the icon colored, but we need to give it some margin and padding like to be more in the space. So we can give for examined margin, top 10 pixel, and margin right or left, then pixel. And we save. We tried out again. Okay, It's located in that place. Of course, you can always use the dev tools to manage or measure how much you have here. Spaces like for example, you can use with okay, what you like. You can place it in your style. Okay, now we are going to style this input. So this input has like background and border. Let's remove them. So I will say here as I named it. So I have here the Product Search minus input. I will say here minus input. So I am inside the product search with SAS. It gives me the ability with this ampersand, I can give minus input and then I will give it height will be exactly the same height which we gave for the container. And background color will be transparent. Like we don't have a background color and color of the text itself. It will be var, variable, which is surface and 600, like it would be darker a little bit like font color and border, for example, we can remove it totally. We don't need a border, so I will give border 0. And then we save, try it out. And we would say, Great, we have here everything. But as you see here that when I put the mouse on it, I see some border. Let's also remove this border. How we can do that inside the input, I can say ampersand focus. And also I'm percent active for that. In that case or in that situation when I am focusing on the input, you can put the border is none or 0 and outline is none. So in that case, we guarantee that we do not have anything when we focus, as you see here. Now we have it style totally. We have all the component is created. What we are going to do in the future that when I put some text here, I am going to find some list of suggested products where it found in the database. But now let's push it from the top a little bit. So if you remember, we have in the header, so when I go to the NG, show up to the header, we have given a class which is called search. So I will go to the CSS file and say this header will have on the top you remember we have tools and we have as well search. And it will have padding top. We can say 25 pixel for example. So in that case we need to align also everything. So we can have here as well, this navigation can have like more, more space on the top. So we can then navigation give it padding top as well. And we can measure it like 25 pixel so it can be aligned. And as well, we need to give the tools more space on the top, so we can also give it like that. So for navigation we need 23 pixel, about 23 pixel, and the tools we need about 38 pixel. So for the tools we need 38 pixel. And the navigation padding top will be 25 pixel. So we save everything. We save all the styling. We see that we have the header is ready. 141. Banner Components: Okay, so now we have finished the header, the header which contains the logo and some search bar. And as well, we have some icons and the menu. Now we are moving to the homepage. Let's go back to our design. As you remember, in our design we have a banner and then categories list, and then we have list of featured products. So let's create component by component. So in my opinion, I'm going to make one component for the homepage. So in our code, we have created previously a homepage in the application and you shop. We moved here and we said homepage. And we said then homepage component will contain something a and B. This when I was teaching you about the grid. So for me, I will imagine that the homepage will contain the following. First, something like called UI banner. And this will be a component. And then maybe I will have categories list or categories Banner as well. We can call it categories Banner, no problem. And as well we have featured product. So in this way, we will have three components under each other and they will show up in my homepage. But where is the location of those components? So first of all, UI banner, I guess it can be in UI library, which we created previously in the lips. And we have orders, products, UI and users. We have the UI. So I guess here we are going to create the component of the UI banner. To do that, I want to show you first how to delete a library. For example, if I want to delete this library because it was generated somehow wrong with us. I made this mistake by purpose when we are creating this library in the command line, if you remember. So I want to delete now this library. How we can delete a library. First of all, you just go here and say that I want to delete this folder totally. But that's not enough. You want as well to remove it from the index.js JSON, which is located on the root of the project. So you need also to remove the UI here as well. You need to remove it from ts config base, if you remember, we were defining the path is here, so you need to remove that as well. Don't forget to remove the library as well from the Angular JSON because in Angular Jason, I am defining my projects. If you remember, we have defined the UI, it games as generated here automatically. So we need to remove this part as well. So from four places. First the config NX and then angular JSON, and then the folder which is containing the library. And then you can generate a new library easily using an ECS console. So let's save everything now. See if our project is still working fine. Okay, we have the project still working fine. We don't have any issue here. And now we are going to create a new library. So let's close all of these tabs. We don't need them anymore. We just need to create a generate. And then we can say library, which is here. And then we can define the name of the library. I will say UI, the library called UI. I'm going to locate my UI components such as a gallery, banners, et cetera. And then you just press on the run those options. You can take a look at them. We talked mostly about them in the first lectures when we were creating the library. So first we click on run. And then we will see that the library got generated again. Let's go here to lips. And then we will see, okay, great, we have the library again here defined and everything is fine. Now let's generate a component which will be the UI component, the UI banner. If you remember, I said I'm going to put it in the UI library. So we open again the same type of generate. So we need to close this because we were generating a library. We have to generate a new thing which is called component. So, so I will go here, click on Generate component, and this component will have a name. First, we will put it inside folder to be more organized inside the library. So I recall this folder components as always. And then I will give it the name, which is banner. And then the project will appear with is UI. And then we will do the rest of the things which we have previously done. So most important is export. Remember, we talked about that previously, so we can use it in other places. And then we don't have anything else in a lifestyle. A lector which is very important, we have to call it UI banner. And then we have to say skip that if you are not interested to create unit tests now. So let's click on Run and then call to our files and check if the component has been generated. Let's check. Okay, we will CUI source lips components and we have the banner component and it has its ts file with the right elector. And as well, it's already imported in the module and as well exported. So I just need to do one thing, at least. So here in module, I need to use that component. So in their, in their homepage, as you see, it's still giving me error that you, I banner is not element or known element. So what we have to do is just go to the app module again, and then we will import the UI module. So I will go to the import and say UI module. So if you sometimes, it doesn't know that it's created, especially when you create this library recently. So you have to say UI module type it like this. And then you click Control Space or control dot on Mac to just to see if his autos completing that or not. So we see that it's not auto completing. We go and we import it manually. So I will go here and say Import. And then you ICT module from, and then I will say add blue bits, UI, the organization name, and then the UI. Because if you remember, the ts config already defined for me a bath, which is referring to the UI library. So and then we save, and we see that UI banner doesn't have the error anymore. Let's comment out those. So we comment out this part and we save, and then we go to the application. We will see great that the banner works. So now let's style it. Okay to style the manner, I would like to take a look to the design. So first of all, we go to the design. We will see that we have divided, for example, that banner to two columns like I can imagine. So if you go on, you can also enable the layout grid so you can see how the layout is going on here. So first of all, I would like to have, for example, five columns here and then Offset one column. So I have a 1, 2, 3, 4, 5 for this title and the button, and another column for the image, which will be six columns. So first of all, we need to create a div which will contain the banner and we give it this color of the background. And as well, we will make a grid which is inside it, these two columns. So I will go here and I will give div, and I will call this div banner in general. And then I will create a div and give it like peak grid. And then inside this peak read, I will have two columns. First one will be P call, and then five, as we saw in the design. And the second one will have but six. Here we'll have six, but this one will have b offset and then one. So we can push that content one column to the right. So as we see inside the design that we have two parts, like two texts, the best products in every category. So we need to have two texts. So I would put, for example, the first texts in H1, and I will say the best products. And as well another edge, for example, it will be H2 and it would be in every category. So here we have two texts and then we will have a button. So the button, we can grab it from Prime energy. As you know that we have a button library, but how we can use this button. So let's go here and go to their prime NG library. We can't check it out. So we can have here, we have the icons. Let's go to the buttons. So here we have the buttons. I want a button which will contain text and then icon. So we need to use the one which is in sources. I think we need to use this one because it has eye composition is on the right. We can copy this part. And then we go to our code and place this button here. But as you see, we have a problem that the button is not defined because we need to import the button module, but do each module we have to import it to you or to the application level, I would say to the UI because in the UI it has these components. And those components doesn't see any other components which are outside of this module or outside of this library. So we need to import the button module again here. So I will go here and say Import. Button, module from and then I will say prime end g slash button. So as you see, it's already defined here. And then we put it in the import of the module and we will see that our button has been defined. So the label of this button will be see more. And the icon will be, as we saw, we have ter, children, right? And then we save. We check if we have everything is working nice, we have everything working fine, but the button not showing because module is not saved. We go again to our application. Again not showing up. You can save their component again. Okay, it's showing. So sometimes you need to save multiple times to make things work or appear in their front end. So now we need to style that. First of all, we need to create a style file for the banner. So if you remember, we have public styles and we created leaps. And inside this loops we have folder for every library. So I'm going to create a UI library or do you I folder. And inside this UI folder, we will have that banner dot SCSS. And then we are going to style it here. So first of all, I will go quickly to style it. So we have hide it will be as a design to a 180 pixel. And as well we have a width, it will be 100%. And a background color, which will be like this, like slightly blue color. So as we see here in the design, we have a slide, a blue color. So if I go here and then we can hide the layout, we will see this light blue. You can copy the color which is the same as here. You can copy it, or you can use something from the surface. The defined order, the defined colors which are in prime engine, but I would follow the designer exactly. So here I will have like this banner background color. And then we need a border radius because it has some curvy borders. So we need to have border radius and it would be 15 pixel. Let's check if we are on the right path. Now we don't see anything of the styling because we are not importing banner SCSS to our application. So we need to import Banner CSS to our application. But as we do always, we put a file which is importing everything, all the components, and then we import this file in our application. So in this case, we will save less lines. So I'm going here to create another file. I will call it BWI dot SCSS. And inside this UI SCSS, I will have import to be like this. And then this import will import for me that banner or CSS. And in my shop I'm going here and I will say import for me all Library, which is containing like this leap. And then we have the UI and then their banner or sorry, the UI scss. So in this case, I imported YOU IS CSS which contained the banner. So let's save everything. Go again to our application. Okay, we have that color, we have everything fine. So let's push a little bit the banner from the top. So we can do either margin bottom of the header or margin top of the banner, I would say for example, margin top of the header. You can as well put margin top or top of the banner. So we go here and where is our header styles? We have apps. And then sharp shared header. I will give it, for example, margin button to the header, push everything under the header, about 25 pixel, let's say all you can measure it with a design. So we have it like that now. And now we are going to do some styling. First of all, let's style those titles. I'm going through their banner again. And then I will say, Maybe I can give a class for all of these groups so I can give it like a text. We cancel a banner texts. So I go here and make defined here something like banner. And then text. And all of these texts can be styled. So first of all, it will have a color. I have that color already, which will be variable, suit phase. And then 700. And then margin top. We can give it like to push the text from the top about 50 pixel. And then we start to style the titles so that title first one, H1, it will have like for example, margin top 0 or margin in general 0 to not have this spaces around, we can initialize it. And then formed size will be three AM and a font-weight. We can give it like some heavyweight, something like 400. And as well H2. And then we can also give it a margin 0. And then we can also give a font size and font-weight. So we can say here font size will be 20 AM and the font-weight 300. I'm fast in styling because our course is not about styling, is about showing the angular structure and how we are going to structure our application. So that's why I'm so fast in explaining the CSS. So let's save check. Okay, we are very close to our design. Now we have the button here. We need to push their code or push the button a little bit. You can do that through styling. If you remember, we give style, not class directly, but style class. And then you can use the predefined margins and paddings, which are in prime NG. So I would say margin top, and then I will give it, for example, three or four. So we can put that and we will see that it's pushed automatically. Okay, nice. We need also now a place for our image. I have, for example, the image already defined. I already have it in my assets folder. It's called banner image. So it's SVG. You can collect any image you want and you place it in the assets folder of the application level. So we have here the app assets, and then we put images as we saw previously with the logo. And then inside this column, I will say image. And the image source will be Assets folder and after assets, images. And after images, banner, image, dot SVG. So we can also import SVG, okay, we have our image here. We need to push it a little bit to the left or to the right. But I want to show you something which is animation. I'm using some library which is called Any made SCSS animate or CSS animate. I will show you how we can, for example, when the user open this page or this website, this will come like from left to right to like sliding. This cart is sliding from left to the right. I will show you that in the next lecture. 142. Animate Banner: Okay, Before we start with the lecture about animating the manner I want to mention about the font issue. So we have previously talked at the beginning of the course about fonts, the fonts which we have installed previously, but they don't take effect only when you configure something in primed NG class, which is called peak component. So just be sure that you have configured this and be sure that in your calling of your libraries and other components, that you put the configuration after Prime NG calls. So after that, we have that configuration file. The configuration file is called here and it has a peak component for the font. Now we are going to see how we can animate the banner. The banner. I think the best case here that we can slide this image from right or from left to right. For that, I am using a library which is called animate CSS. If you go to their website, which is called Animate dot style, then you will find this library. This library is very great for animation. It has a lot of animations like you can use for your divs, for your images, for example, texts. You can do whatever you want, css and very slight and very light for the browser without using JavaScript and this complicated things. So they're CSS animation is very light and also browser friendly. So what we need actually here that we want to slide the image from left to the right. So we can use this animation. But first let's see how we can install this library. First of all, we need to execute this command npm install any main.css minus minus save. So I am going to open a new terminal and then I will install this library. So the installation of this library can take some time. I'm going to skip it. So here I have the library got installed, added one package, as you see here. Now we are going to add it to our style. So if you remember, we were using here in ND shop, SCSS, not in admin in any shop. This is specialized for their shop that we are adding libraries here. So we want to add the animate CSS here. So how we can do that? First of all, I told you with this sign, you can reach all libraries which are in npm module or in node modules folder. Here we have the node modules folder. What we want actually we have installed already is animate CSS. So NMAC as S is located here and we want to include the file animate dot CSS. So that's it. So first of all, I am going to do import. And then I will use this sign. And then I would say any made dot css and then slash because if you see that the folder name has animate CSS. And then we will enter the glass or the file which is called again animate the CSS. So in this case, we have imported the library. So now it's important to our application. We are going to use one of those animations, so how we can use it. So first of all, you need to say that I am saying that this H1 or this div or this image is animated. How we can do that by saying any mate animated. So we can copy this class. And then we go to our banner. So we have created the banner in the library, which is called UI library, and then we have the banner here. So what I want to animate actually is not only the image, we can animate all the div. So I can put here on the div container of the image. So that container of this image here, I can put it inside a div and then we can animate it. So we have Any made animated. So now it's, we are saying that this thing is animated, but what is the animation? So the animation will be slide in left. So here we can copy it. You have button here to copy it. And then we go here again to our class and we put space that we have another class, which is called slime in left. So we save, go to our application and we refresh. And we will see that sliding in that way. It's very great way for doing that. So what I am going to do now just to put this image at the end here, like something like the design, because design is showing that this is mostly going to the right. So let's do that. So first we can give the div container of the image, something like banner image. So we have here that banner image. So after that we have banner text and now banner image. So we go to the styling of the banner. So we have it already in the styles, public style lips. And then I go here to the banner, and then I will choose here, not text, but I will open a new tag, which will be image. So here it will be image. And this image we can give it, for example, text align center, like the things inside this image will be centered. Let's go back to the browser. We will see that it's still there because I didn't save this part here. So if we go back again, we will see that it's more to the right, so it's centered. But when you put, for example, the image itself, text align more to the right, then it will be pushed totally to the right as you see here. But we need here again some padding so we can give to this image like we have to push it a little bit from the top and from the right. So we can give to the container itself some padding. So we can't say padding will be from that top about 15 pixel. And then from right it will be like again 15 pixel. And from bottom will be 0, and from left it will be 0. So after that, we will see that we got exactly what we want. So we have here the animation, and we checked that in the console. So maybe we need more paddings like from the left so we can give it like more pushing to the left, something like 50 pixel. I think I wasn't enough with that. So I have to put here 50 pixel. So we save. We go again. We see that the animation is going very nice. Of course, if you don't use bagging, you can just say padding top. And then you can, for example, put all of these values to 0. And then you can just say text align center. So it will be in the center of the div, which we have specified year. I prefer always center. So this is how we are animating things with CSS. Using this great library which is called animate CSS. Of course you can use also the animation of CSS or angular animate. But I prefer always to use simple things which can affect performance of my application. So I am using mostly more CSS and HTML friendly without using some extra complicated libraries or JavaScript libraries. 143. Overriding PrimeNG Button Style: In this lecture, I am going to show you how to override the button from Prime NG to a specific style which you want. If you remember, we have imported the button from Prime energy and it came as a standard styling, which is blue. But we wanted like in the design, how we have it here. So we can do that easily by overriding the styling of prime NG. So let's do that now. So first of all, I will go again to the banner component which I have created previously. And then in the style class, I can add a new class. We can give it button or banner button. And here the banner button will have a style in Banner, CSS. So let's go here and create another tag, which will be again prefixed with banner and then button. So if you want to override this button, we have specified class for it. So let's give it, for example, some properties. So what I want first is a background to be white. So I will put background color will be var, and then suit phase 0. And then we can have a white background, and then that color will be a primary color, which I have defined previously for our application. And we talked about that before. And as well border or let's try now without styling more to see if we are going to progress. Well, okay, As you see here, we have now the border is still blue. And on Hoover we still having it as blue. So let's go first, remove the border. I'm going to remove the border like bordered 0. At now we save. Okay, Let's now remove the hover. So how we can do that? First? If you want to hover or remove the hover, It's very simple. Like as you see here in CSS, the hovering will be in their way like I am inside the button class. And then I say this and over. So ampersand hover. So it means like the button. And then I have this attribute which is called hover, and then I can remove the background as well. So I can also do the same properties here. So we can save and we will notice that it will not get any effect. So prime end, It's styling some buttons in different way. So if you want to override some styles from Prime NG, not only button, the only way to do it right, is to inspect. So you can open the development tools. You can right-click on the button and then inspect. And then you will see the, for example, the styling here. So I don't want the styling of the span of the text inside it. I want the button itself. And not only the button, I want the B button, like this tile, how I, where here the banner button styling. So as you see here that we have all the information coming here. But we have still issue that we don't see our classes which we have specified. They are in the button and here are our properties. As you see, that banner button, the class which we defined is here and also on the button itself. So prime ND is doing everything for you is to through style class. So what I am going to do now to check the whole reason why it's not working. So to enable the hover styling, you can click on this over this toggle. And then you can select what activity can do like instead of you, like you don't have to do the mouse activity by yourself. You can just say, I want over. So, okay, now it's in Harvard state the button. So as you see that we don't have over directly, it has enabled and then hover. So we need to do the same because look, it's overriding our changes because this come more important than our changes. So in that case, I must do it exactly the same how I am doing it done here. So we can take this enable Hover and then we go again to our code. So I will go here and say, not only hover, but enable as well, enabled. And then we will see that we have here the changes going mostly. So let's try or restart the page. And we go here. And we will see that it has normally the hover effect. So we don't have that issue anymore. So in that way, you can override not only the button, but everything in prime NG. Sometimes you need that. You need to override some style from component like accordion or some textbooks or for example, some toggle button. So you need to do that for every part of Prime NG based on your design. So it's the easiest way to override. And this is the goal of having the public styles. Because without having public styles, you will not see the changes in your component. Because if I have this dial in the component, then the prime end where render as well based on component. In that case, I will not be able to access the style of the, for example, this button only with something called host and, or for example, host deep. And this is used in Angular to access inside some components or child components which are defined inside the main or the parent component. So in that case, we guarantee in the way with public styles that everything is public and opened for us. We can just go through and then we style as we want based on what we inspect here. So that's why I use the public styles always. I'm not using the components styles. Of course it's up to you. You can use as well, the components styling. So let's check the design again, we will see that we have here like more border radius. So we can say like it's 13. So let's put the same border-radius as a design. So let's go again back to our code. And then we will say here that the button has border-radius will be 13 pixels. Let's save, check it again in our browser. And we will see that we have it in that way as well. We notice that the button has more height. So you can also give it a height which you want like here, it has 48 or maybe let's make it, for example, 50 to have like some constant number. So here we go again and we say, okay, the height of the button will be 50. So he go here, Pixel, 50 pixel. So again, we go to the browser, we check that, okay, we have the button with 50 pixel. So this is a way how we implement the things and how we override this dies from Prime NG. 144. Categories Banner: Okay, back to our design, we are going to do now the categories component or categories banner. So these categories will have a title and the categories list. And every category item will have the icon which we have specified in the back-end and the name of the category. And when I click on one category, I would go to the products list page and I will show the products which are under that category. So let's do that quickly and we are going to implement it the same way how we implemented that banner. So first of all, I need to go here. We can now close everything. So we don't need to do anything else here. So we are just going to create a new component which is called categories batter. And where this could be good IS banner will be created. I suggest for me now I can create it in products library. So we have lips products, and here we can define components which we had made with product search. We can add as well the categories banner. So we can go here and generate, and then we give a new component. And this component schematics. And I will give it here components. And it wouldn't be the goal is planar. And then the project name will be the products. And then I am going here in the list as we do always, I give it export because I am going to use it in the homepage and the path and of goals. We need to give a selector, the selector, as we said, we define that, that we give the product the name of the library like as a rule. And then we define what we want. So we can say products, categories, banner. And here we have that selector. Skip texts and we need to specify no need for styling so we can put in line style. So in that case, we will have the categories banner generated in that way. So let's click on Run. And then we go again to our files. We will see that we have categories banner. So as every category or as every component we need div and we can give this div quality categories banner. And this categories banner will contain a title, as we saw in the design. It would be called here categories. So I give H3, you can give any age you want for me, I give the H3 because it's the third level of the page. So here we have now categories and then we define, agreed, so p grid, because if you remember in the design that those categories are under metric, agreed. So at every grid will have two columns because we have six categories in there at all. So we give this div and then call and two. So in that case, we will have the categories located here. So what we want first we need a div which will contain the category itself or category item. And then inside this category item, we will have a background and then the icon and the name. So I will give here div. And then I would say, for example here div, a category icon or it will be, yeah, okay, They're category icon because I need here the icon first. So we have here category icon and another div where I am going to put the category name so we can say div dot category, dash name. And here we are going to put an icon. The icon which we read using it was from prime and g, If you remember, we were using the tag which is called I and then P icon, and then I give the icon which I want, for example, PI check. So here we have the icon and the name will be, for example, the category name will be, for example, garden. So we are going to replace later all of this component or this solid texts or hard-coded text with the category which is coming from the back-end. So now we are structured our page. Let's go again to the homepage. So we have everything is working fine, but we don't have that banner because we didn't call it in the homepage. So first of all, I need to go to the application and you shop, as you remember, we have the pages and here the homepage. And the second component which we are working on is that categories component or categories banner. So here we called it as products. Okay, I think or IS banner and also we have to close it as well, so we don't have here any issue. So in this case, I will have like the categories banner will be called from products library. So if you remember, we have already imported the products module. So the products module, inside the product module, I have already the categories banner, which in ECS console made it in the export and put this component, which in the libraries product or the products library. So here we have everything. Let's try that. We will see, great. We have categories. And the icon and garden. So what we need, actually we need first to style this banner. So we go as well to our public styles. We have lips. If, if you remember, we have defined same structure. So I'm going to create a new file inside Products library and give it as categories banner. And this categories banner will have, will be a CSS. And then we are going to style it here. But first we need to import it as well in our products, which is imported in our application style. So we have here as well, we don't have the products, we have categories, banner. So in that case, I can see the styles in my application. So as we see in the design, we have like some space here. So either you can give banner or for example, here, margin bottom, or here you give margin top for me, I will give margin top for the categories. So maybe we can go here two categories, banner and first of all, we need to call this class. So we have here the class of categories, banner in categories mammal fine, CSS file. So I will give here Ferraris like margin but dope or yeah, dope, we can't say 75 pixel. And also we are going to style the H3, which is inside. So we can give it, for example, margin button. So we can push the category icon under it, about 20 pixel. So we can save this to check if we are really importing this time. Okay, We see that we have, the style is imported. Okay, Nice. And we are going to color this the same as the color which is defined here. It's not totally black, but it's like light in gray. So we can use the grays which are in the surface and defined in the, in the prime energy. So as you see here, we have a lot of variables for colors, so we can stick on those. So we can take, for example, this darkest one. So we can take this slide. We can take for example, surveys 500 for example. So we go here, we give it a color to this H1 or H2, H3. And we say far, so phase 500. So now we have specified the color of the title. We go again and we will see that it got that color. Maybe you can use darker, so you just increase the number which is specified here. So I will give it, for example, 700. So we go here, we give it 700. Or based on the design, you can define your own colors, our own variables. And then you can use them in your application based on the design which is provided by the designer. So here we have style, the H3, what we need also to style that category itself. So inside categories banner, we defined a div which is called category or category item. We can call it what, I'm calling it here, category. And inside that category I'm going to have some like values. Like for example, we have minimum height for it, like it has some height, we can give it 100 pixel. I am copy those or I know this information from the design, so we can copy as well. The border-radius two will be five pixel. And then we have text align. We give it a center. So everything inside it would be in the center. And this will be displayed as a flex. I will tell you why, Because we want also to justify their content to be in the center. So first we can give it like that. I just want to give a background color, random background color, just to see how my changes are going because everything is transparent now. So we can also be, for example, randomly this color. Of course, we are going to replace it with their categories color, which we have defined as well in the back-end. So we have this garden here, we have this banner. So I want to justify their content. So if you remember, we define this as flux. So you can't say simply justify content and then you will say center and then align items. You can give it, for example, also center. So it will be exactly on the center of this div. So two things, justify content and align items. So let's give it here. So as we see justify content, we say center and align items. It will be as well, Center. So everything will be centered inside it. But as you see, they are near each other, like the icon and as well the name, they are near each other because we said display flex. So to put them under each other there is nice I think in flex you can say flex direction. It will be not on, they're all like not a horizontal, but it will be column and also column reverse. You have multiple options here. You can switch between all of those stuff. So you see, doing things is really important to learn. As you see, you cannot do the things only when you are learning something practical. So that's why I am doing those types of courses. Courses who are coming with practical experience. Not only I am leading some document and then okay, you can apply it. No, you see it in front of you. You see how we really need, for example, flex direction. Maybe you saw flex direction. Okay. You don't know what is it? You have never experienced why we are using it, but now you can see how it's used. So this is a great value of doing things practically. So here we have now that category. So what we need based on the design to give the icon like some bigger size and also the text to be a little bit bigger. So let's do that in the code. Go, I go here. So I will say that if you remember, we have specified icon, category, icon. So I will go here and I will say I'm percent category or icon because I'm percent will give me dot category. And then I put dash icon. It will make for me in that category icon. So here we will have the class, and inside this class we are using the icon. So we can use this class as well. So here I can say PI, it will be font size. We can give it like for example, 40 pixel. All you can use the EM units, you can say to EM. So we can have it as a big text. So back to the browser, we will see, okay, we have it like this. I, I ignore the changes because we didn't save that. So we need to put again, flex direction will be column. Okay, we have now everything is fine, so it's reloaded. And we have it like this. Also maybe that text, we can give it a little bit bigger. So I will align also another class which is called text or name. No, what we call the glass here. We have it as a name. So I will go here name, and then the name font size will be like a little bit bigger. We can give it 1.2 AM. So this 1.2 E m, what it mean, like, I will multiply 1.2 by 14 pixel and then it will give you the size in pixel. So this is how it's calculated because we have the body specified previously in their configuration, that we have. The body size of the font will be 14 pixels. So after that, we can save and go again. And we will see that we have a bigger font a little bit here. Let's give as well a little space here under the icon. So we can go here to the icon itself. And we can go again here and say, for example, to the eye itself or the PI, we can give margin-bottom like 10 pixel. So we can use as well this class here. And we say like, I want a margin bottom will be 10 pixels. So to push the text a little bit away from the icon. So we save, reload, Okay, everything now is fine. So let's check at least the border-radius. I think it's bigger. It has 14. So we can give also a bigger border radius. So we can give here 14 pixel. And then we go again to our design. And we will see that we have a specific category. So now what we are going to do is just repeat those categories which are in the database, which we get from Postman and we solve that previously in the admin panel application and place them here. So first of all, we need to call that category service. So as you see here, we have styled everything. First, we need to have like array of categories. So we can define here in the ts file categories why it will be as array. And this array will be type of category model. If you remember, we have defined this model as well. So it will be initially empty because we are going to get it from the back-end. And what, how or how I can use or get the categories. We can get them through the service if you remember, which we created in the category service. And we have all of this list so we can get categories. So I will go here to my TypeScript file in the categories banner, and I will call that category service. I will say private categories service. It will be categories service as you see here. So if you want, you can use this one. And then on NGO on Edit, we can call again that category service. And then we can feel these categories. So let's do that. We can say this dot category service, then getCategories. And if you remember, we have to subscribe, we have to wait for a value which is coming from the back end and then we push it to the array. So we have here dot subscribe because it's HTTP request. And then I will get their categories in the return of the subscription. So here we have categories. And then I will say these categories, like the variable which I defined here, will be the categories which come back, or the response categories which came back from the backend. And if you remember, we need as well to do unsubscribe, we need to. For example, take until if you remember, we have made that is just for performance to not make issues. So this subscribe will not stay open. So we have to do as well. And subs, if you remember, and we have defined that and we talked about that in the admin panel refactoring. So n subs will be a variable which will be as well-defined here. So we can call this n subs, sorry. So n subs also with dollar. So it will have a type which is called subject. And the subject comes from our x js and the type of it will be any. And then we as initialization, when I visit this component, I say new subject. So this ends ups, well, it will end, like I am saying here, take until, Okay, I am taking until this subs. And so when it will end, We'll end when I destroy this component. When I destroy this component, when I navigate away from the homepage, when I don't see this component anymore. So that's why we need also to call something on destroy. So this onDestroy is part of Angular lifecycle of components. And then we can use it, so it will be executed when the component get destroyed. So here we implement onDestroy and then I say NG onDestroy, and then I will specify what it's going to do. So I want this end subs to be completed. So as I said bit, obviously we need to do it this way. We say Next, like go next step and then completed. So when this component got completed, the subscription will be ended and we will not have any memory leak. So we save. And we have now the category That's for example here, make a console log to be sure that we are getting the categories from the back-end. Of course, you have to be sure that you are running the back-end. So we save again and we go to the console. And we will see that maybe there is an error. That is an error here. It says are three injector error. Category service is using HTTP client and there is no provider for HTTP client. So we need to do or call as well. If you remember, we did that in the admin panel, we need to call as well in the end you shop application, the HTTP client module. So I record here again, HTTP client module as we did previously in the admin obligation. So here we have now called, okay, I get five categories as you see here. But in the front end, we don't anything yet because we didn't add that to the template. So we go back again to our categories banner here. So we have used array. Of course you would remove their console log always because it's affecting the performance of the application. Don't do many console logs and keep them in production. So it's better to remove them. So here, as you see, we have category and we have column two. So we need to loop over these two columns or two every category. And then it will generate for me that categories, which is provided from the categories array. So I would say here in column two, G4. And then in end you for, I will say let category will be off categories, categories. We define that already and it's full. So now we have the category here. I will say replace for me the category name. So we can do it in that way. I say category dot name and then widths check that to see if everything is working fine. Nice, we have all of them like this. So let's replace the background color. To do that is very simple. If you remember, we have the color over the category, so we have it in the CSS here. So we have here the background color on categories class or category component. So here category div. So here we go and we say that we have an input for devs or the any HTML element which is coming from Angular, we just called NG style. And in any style we have specify that in brackets. So it's an input. So we need to do inside this input some angular code. And inside we open an object, and this object will contain the property of styling, the background, property of styling, we define it like this. Background. Color. So it will have like this background color. And then I will say category, the category which I got from the MD4, and then color. So here, this div will have this background color, which will be category dot color. So we save. And then we go to the application. We will see that we got the color which we have defined in the admin panel before, if you remember. So in that way we have that color. Energy style is doing the job for you. So you can as well use another properties, such as, for example, color. So you see here that the color also will change based on that. So it's very simple. You can that inside the NG four and as well the icon, if you remember, we have here specified icon for their category, so we can use it as well. You have two options. One of them is just doing this and then you say category dot icon. Because if you remember, we were specifying the icon only the icon name, which is from Prime NG. So we need to connect it to be pi and then minus, and then specify the name of the icon. And then we can get it here. It's exactly how we did with the admin panel. That's why I'm going quick here. So as you see, we have everything is defined. I think the text font is a little bit big. Let's make it smaller. I will go here again to the categories banner and then I will make the name to be. We keep it like one. So we don't have to do anything or any change here. So we can just keep it like that. And we will see, okay, we have the text and the icons are very beautiful. We have five categories only because we have defined five categories in the back-end, you can add another category. I'm going to add it for the next lecture. You can use the admin panel application to add category, and it will be added here with the right icon. Of course, the last thing I want to mention is when I click on one of these categories, I want to go to products list and then the category of that product. So I want to see the products of that category, of the category which I clicked. So to do that, we need to do on the banner itself. Here, the category. We can't say router link if you remember. So I can't say that here. It can be a router link. So the router link, what it will be, it will be a products. So we can put here in double quotation because I define this input. So here I am writing a TypeScript or JavaScript code, let's say, or angular code. So here I am specifying the boss. It will be products. And then I am creating, for example, the same component I am calling it, but it would be like under category. So I am going to a specific category and then I pass that category ID because I am going to use in this router or in this link, I'm going to use a component which is reading their category ID. And then it will return for me that category which I want. So here I can say plus, of course we put this in single quotation because it's string. And I'm going to combine with it category dot ID. So I will read the ID, then it will be with this router link. But we are still getting here error. Why? Because we didn't use the router module in products module, you need to use this router module inside the product module. So let's use that. Of course, we will return to this router module more in detail when we will define the products are out. So we need just to call router module like that. And then we have a specified our category, how it will behave, exactly what we want. So if I click now on them, maybe I will get errors because I cannot go to that category because we don't have route for that. So if you want to make it work, we need to create a component. And then we will create the product list based on filtered, based on those categories, as we will see later in the next lectures. So as you see here, I am clicking, I'm getting error because I cannot access or go to this component. So for me, I will be here enough. I just want to mention that we can make some great behavior or more free and friendly behavior. That when I put the mouse, it will be like a pointer. So we can do that on category style. So if I click Control, if you see I click Control, then click on the class and it will take me to the specified class. So I can say here cursor pointer. And then we save. And we go again to our application in the front end, you will see that we have now all category is clickable. So we can, if I click here, okay, I get error in the console because they're out is not defined yet. So in the next lecture, we will see how to make this application bigger. We will go to product list and we will filter by category. As you will see later, step-by-step. 145. Product Item: Okay, we are now still in the homepage. We are going to create the featured products. The featured products will have some products item. How we did it exactly in the backend, if you remember, we have galling that featured products API. So we can have only the featured products here. If you remember, we were flagging every product with flag which is called is featured and we set it to true or false. And based on that, we are getting the featured product to the front end. But first of all, I would like to style the work item or the product item. This product item we are going to use as well in their product list and also in another places like suggested products or for example, in the homepage again, or somewhere else in the product page itself. So in that case here we need two types of components. First, the container of all these products item, which is called featured products and the product item itself. So you can as well make featured products and put product item. But in this case, the product item will not be reusable in somewhere else. So first of all, let's create two components. First component will be located in the library of products, as we did with categories, banner, and product search, we are going to locate that featured products and the product item so we can use as well the console. I'm going to do that quickly. So as you see here now we have two components. First, it called featured products, and also the product item. I made mistake here that I put the, for example, I kept when I was generating the item, I was using the same generation tool. So I did mistake that. I put I still have the products or the selector stayed products product item. So we need to do that as well. So we need to fix that. So how we can fix it? If you do some mistake, you can just go again to the component and you can edit it directly here. So we have the selector, then I want products and I will say featured products as well. So in this case, nothing will change, just this selector. So when I want to call this component, I want to use the selector. And I am using products as prefix. Because if you know that we have a rule in ES lint that we have products as attribute as prefix. So we need always to prefix our selectors with products like the name of the library. And then I put the name of the component which I want. So as well, we have here the product item which we have created previously. So now we can make the container first, we can say for example, we have div, which contain the feature products and the title. So I will create here a div and I will give it a class which is called featured products. And as well, I'm going to give a title which are really, really like H3. And this h3 will have featured products as well. And then I need to have a grid because we are going to put the items in the grid, the product item. So we need to have a grid as well, exactly how we have it in the design, in the design, if you remember, we have four columns, so we need 34 for every product item. So if we go again to the code, we can define a div or a grid. We can call it a grid. And then inside this div, we are going to define the columns. So I will say div dot P column, because here I am using the grid system from Prime NG. And then I will say three. We have 12 columns, so I need four columns. In this case, I need to divide it by three. So 4 multiplied by 3 is 12. So here we will have four columns. And inside that we are going to use the products item. So I will say here, products, product item. So we have here that component defined already. So in this case, I am going to save, save everything, and then we are going to use the feature product component in the shop application. In the homepage, as you remember. So we have in the homepage, this DAG as well. We have the banner, we have the categories, and now we are going to use the product itself or the feature products. So let's comment out this part and then we say that we have the new tag which is defined previously. So products and then featured products. So in this way, we have called the component, which is called feature product. And inside this feature products, I am calling the products item. So in this case, I must have in the front end product item works for time. So let's go here and check. Okay, We have product items, works. We have at one time because we are calling it only one time. We don't have here a for loop for every product. So for now we are going to create the product item. And in the next lecture, we are going to call the feature products and put this in loop. So you will have the all products item. So first of all, let's do the styling of products item. So in the product item, if you remember, in the design, we have on the top image, title, price, and then button, button, which is called Add to Cart. So we need to create a div, div. And then I would say Class of this div will be product item. We need to create a styling file for that, as we will see later. And inside this div, I'm going to have something product wrapper or product item wrapper. Why I need that? Because if you see in the design, we have here a gray background. So this will be the wrapper and outside of it, like I am pushing the image out. So here we will have as well the image. So I wonder Arbor to be colored like this. And then I am going to put the image and the text and the prize inside it. And inside the product item wrapper, we are going to have the image. And the image will have like a source, which will be the product image itself. And also we will have a class for this image. We call it Image, and then alternation. We can keep it empty for now, All replace the product name inside. And as well, we need a title which will have a glass also, which will be the name, the product name, and inside it will have the product name. And also we need to have a price. So we have here a price. We put it in H5 and inside or their class will be price. And inside it we will have the product price. And at the end we need a button. And this button will be exactly how we did the button of the banner. So it will be P button and style class. I will give it a class which is called Add to Cart. And the label will be add to cart, and the icon will be a shopping cart. But here we have a problem that we are not calling the products module or the button module, sorry. So we need to call as well that button module in the module or products module. Because if you remember that every module is totally separated, which is doesn't see the other components or the other modules which are called in the application or in other library. So we need to call the button module again, inside this library of products, Let's save everything again so we can have a save and then we go to the application. We still don't see anything because, okay, here it's empty. We have only like they're button and here we should have like some name, image, etc. But now we have them empty because we didn't specify that. So what it can be here, okay. If I go again to the products item or the feature products, the feature of products will come from the backend. And here in this case, I want to pass those products to product item. And then product item will be rendered based on what? So inserted inside it. So we need something called input. And this input can be defined in that way. If you remember, we were using inputs always as a properties. So we specify like some input which it can do something exactly like how we have input. For example, source of the image. So it's input, also styled class is input. So we can specify input which is called product, the product itself. And then here I will pass the product which I am having from the backend or list of products, which I have it from the back-end. So we will see that in the next lecture. But now I am going to define this item or this input. So let's do that. We can put back everything and go to the product item. So in this case, I can see every input which is coming to this component and I can render it here. So we go to the TypeScript of this component or to the class file of this component. And then we are going to add an input. Input is something you can define in Angular, and this will be injectable item, so it will be like this input. And then you can define the name of the input which you want. For example, I want a product. This what I will have as well in the product or feature products, I will pass it here. I will say input product will be the product which is coming from the back-end. So here I have a product and the type, if you want to define a dipole. So it would be easier for you to access this input. For example, I want to access their name prize easily. So we can call that modern product because I am passing a product and the input will be imported from angular core. So here we have angular or import from angular core. So in this case we have now the input. Now I am inside this component. I can use this product inside, like I have the products which I got from the backend and I can use it here or use its properties here. So first of all, I can use, for example, the image. So I will have here the source input, as you see here, it's input. So I can't say product dot image. So we will have the image of the product. And here in the Alt, you can specify as well the name. So you can as well past the product name. And as well here, you can specify the product name which will be titled in the name. So we have here product name. And as well, we can define that a price. So we have here as well, product, what price. And then you can also pass or make a pipe which is, will be a currency. So if you remember, we were putting the price in a pipe for currency to style it and put dollar sign behind it. So let's save that. We would notice that we will not see anything because this component doesn't have input yet. So we don't have any data here. So its better always to say that when there is a product, like when this is defined, there is that the inside it then display this component. I am always doing that to avoid having error. So how we can do that, you can just say ng-if inside this ng-if you just say product. So if there is product incoming to this component with our data, then this plate, if not, don't display anything, so we can save and check it again. We will see that we don't have anything because we are not passing any product to product item from future products. So what we are going to do next is doing that feature products. We are going to call them. And then we are going to pass to the product item or the products item. The product itself, which is coming from the backend from feature products. 146. Featured Products Banner: If you remember in Postman or in the back-end, we were getting the feature products based on some count. As you remember, we have created API in the back end, which it says product get and then featured. And then you specify how many products you want to show in the front end or to show, or to get do your front end. So first of all, I want to show you how I can call this API. So I put it in Postman, as you remember, we have now three products which are featured like the East featured flag is true all the way. So as we did always with every product or with every service that we can call the feature products. So we can call the feature products inside the component, which we created four featured products. So first of all, I need to create this service. So first of all, I go to product service and then we create a new function. We can call it get featured product. And then those products or this function will return for me observable. And this observable will be product array, like I would get multiple products, not only one. And then this will return for me HTTP request and then get. And then we can specify again that we want array of products. So I will have it here as well. And then we can specify what is a URL. It will be exactly the same as you are L here. So we can have all of this part and then we are going to replace what we have in the backend or how we have it in the back-end. So we have here the URL, and then we say we need to get and then featured products. And then we specify account. And this account, you can make it dynamic. You can pass it to the same function, so you can use it again in somewhere else. So I will say here count number. So I will pass the number two when I call this function. So I will say here that I have featured and then specify for me the count. So I will need here count. So in this case, we have called this function some specific account of products, like I need three products featured. And then it will call for me this API. So we save that and go again to our feature product component. And we need to call the product service. So we have to say here, private product service, or for example, prod service. You can specify the name which you want here based on your ability for reading the code. And then I would say products service, which is coming from services, product service. And then in the end you on edit, I can specify a method which will be called as well, like a private, we can say get featured products. And then I specify count, as we said previously. So you can specify the account here or you can define a directly when we are creating this method. So here I am going to create this method and I will say private and then specify the method. And then I will say this dot product service and then get featured products. And then this will return for me, for example, subscriber. But first I need to specify how many feature products I want. For example, in my case, I want four because I have four products in one line. And then we can say subscribe like when their value is ready, Give it to me inside a products. And then I will get here and I need to specify the product's variable as we do always. So I need to class member here, which is called products. You can call it as well future products, which will be a product type and then it will be array. And inside that it would be an empty array. So this products will be filled. We are going to use it in the template and then how it will be filled by, we can say in this dot, product is equal to products which is coming from subscribe. If you are confused, you can rename this, you can call it as well featured products. Let's rename it like that to not be confused. So we have future products. And then this, that feature products is a products which are coming from this API or from this call. And then we are going to use this feature products in the front end. So I need to go to the template and then I am going to say in the feature products, bring for me every column one product and pass it to a product item. So here I'm going to say MD4 and then let product, like one product of featured products, like I'm going to go through all products which are coming through this feature products. And then I will say pass for me. If you remember in the previous lecture, we created an input which is called product. And then I am going to pass this product to that input or to that component. So in this case, this component will receive this product every time, and this would be executed four times because we have four products coming from the back-end. And then it will rendered in that way. So I will go to their component. And here the template will be rendered exactly how we received the product. So actually, we will have four components are called here because we have preacher products for products. So let's save everything and check if everything is working fine. I click on Save All. And then we go to the front end and we will see, okay, great, we got all of those products, but it's not styled and we are going to style every product item in the next lecture, as we will see you later. But first of all, remember that to do always the finishing of subscapular subscription. So here we have a subscribe. And as you remember that when I leave with this component, I need to finish the subscription. Otherwise, I will have memory leak in the future. So to do that, we need to go and make exactly how we did with every subscription previously, which I talked about it many times. So I'm going to do that fast. 147. Styling Product Item: Okay, here I styled the product item. I am going to show you the style quickly, like the CSS, because I told you we are focusing here in Angular. So the styling part for us is like just secondary part. So I can explain it quickly if you have experience already with CSS. So our course here is just focusing on Angular and how we can structure our project in the right way. But of course, I can show you quickly the CSS to not make the course boarding and longer. So I can share with you the code directly of the CSS. So first of all, I have here a product item component or styling file, which I created in our public style folder, as we agreed previously, that we have the public style in the libraries. And this library is every library had its own public style for every component which is inside this library. So here we have the product item I created. And as you remember in the template of product item, if you go back to the product item again, we have here Item and then product item wrapper, and inside it I have image and then name, price, and et cetera. So I go to the style again, so I will show you that I have the wrapper. I give it a background color to give this gray background here. And also I give a border because if you notice, we have a little bit border here. And as well, I gave border-radius display flex because I want to align this items in the center under each other. So we have a flex, all of them centered, justify their content as well. Center, like to be all of them in the center, in the middle of the box. And as will flex direction is column like I don't want them near each other, but I want them from up to down columns. So as you see here, we have also minimum height to give them all of them the same height, like this box will have all same height. And then margin top, I push the code a little bit, or that component from the top, a little bit, about 85 pixels. Okay, the image itself, we have it as a width. Here. We have like 60% of their upper because it's inside the wrapper. So we will not have full width of the image, but we have 60 percent of their upper here. So it will be like this and in the middle because we have specified here justify-content center and the margin top is minus 85. Why I did that? Because I want to push it out of the wrapper. So I gave it a margin top, like the image margin top, push it out of the riper 85 subpixel. The name I gave it a little bit like margin, top and bottom. So it will be 10 pixel to be away from the image editor bit and away from the price as well. And they then the price. I gave it a primary color, which our primary color variable we defined previously, some font size and as we'll margin 0 because it comes initially this H1 or h5, initially with some margins. So I make them 0. And the end, I have the button, as you see here, I override it the button with the styling file or that the styling class we have here, style class of the button and I have Add to Cart. So we override it that. And then we went here and we gave like the styling. I went to the styling and I gave background color will be primary color. It's like I override it the color and then the border and give it 0. I don't want border and I give it more border-radius based on the design, how I have it. And then I exported or imported this file in products SCSS. And then this file product SCSS, which contain all of the styles, I imported it in and you shop, which we have imported it already in the import for lips. And then we will see that the styling will look like this. So the styling is pretty simple. We don't have to make it complicated. We are following the design as it is. And then we will make Add to Cart button when we are going to work with the cart. 148. Styling Product Item: Hello and welcome back. Now in this section we are going to create the products list component or the products page. So when the user, when he is on the homepage and he goes to the products, he will see this list of product. And as you see that we are using some components which we created previously. We used the one which we created for future products, which is called product item, and we are going to use it inside the products list. Additionally, we are going to do some filtering for the products. If you remember, we have categories and those categories we can select which category I want to display. And in this case, my products, they are going to get filtered. So let's start doing that. As you see that we have two columns, one column for the categories, and one column will be for the product list. And inside product list, there are three columns. Let's do that and start with this list. And we are going to present first all the products which we have in the shop. And we will move on after that to filtering by categories. 149. Products Page Reuse Components: Okay, so as you remember, we have created the link which is referring to products list. And this product list is located inside our application. We have here in the sources, we have some pages and those pages, our homepage and we created product list. But based on the new architecture which I suggested that we are going to build multiple jobs, then we need to move this product list to the products library. So we are not going to use it only for this and you shop, maybe I will have ND shop too. So I will use again the product list component. So in that case, I will be having the application in my code. It's better to move their product list to the products library, as we see here, that we have products library and we are locating all shared components here. So we can as well create here a colder which is called pages. And inside this Pages folder, we are going to put the products list page. So let's delete first this component. I am going to get rid of it. So we have now deleted the component and don't forget to delete it as well from the application module where we will have called this component. So we are always removing the components from the related module. So we remove it. And as well, we are going to remove this path. And we are going to use that child buffers as we did with the login page. So let's remove that as well. And we are going to remove the import because it doesn't exist anymore. So now we are clean and ready for start working. So first, let's generate a new component which will be located in their products library. So first, I'm going to search for component. And then this component will be located in a folder which is called pages. And inside this pages, I will call, for example, the products list. So I would say products List, sorry, list. And then I will put inside the project or the library which is called products. And we are going to, first of all, exported because we are going to use it in the application as well. Or and then we are going to have inline style to not have like imbedded CSS. So we have as well to skip that tests as we did always. So we have here skipping that, this and the selector is as well. We are going to use or choose the selective based on our rules in Iceland, and we call it directly products list. So in this case, we can run this command and go to our component library or to library which is products library. And we will see that the pages got created here, which is products list. Now, if you know that if I go here, I will have error in the console because I cannot this or see this route anymore. So how we can solve that? If you remember, we did the same thing exactly with the login. If you remember, we have the login component. And in the user's module, I was referring this login page and use routes for child as we did exactly with the login. So let's do the same as well with the product. So first of all, I have to be sure that I am importing product module, which will be in the application module in the engine shop. So we have to check that, okay, we don't have the products, we have it here. We have products module. Now, in products module, I am going to create routes. Okay, let's go to products module. And in the products module, we are going to create a constant, again, like how we did previously. So we call it routes. And these routes will have a type routes. And then these routes will have the value of array. And every array or every member of this array will be an object. And the first object which we will are going to have is the path which is called products. So when I'm calling this module, and then I go in my page two products, then here it will be redirected because I am calling this module in the application module. So all the routes which are added here will be defined as well in the application. So let's do that. We have here products and we are going to have the mapping as a children if you want or you can make the path is as exactly how you want here. So for example, you can say component and then you can import the products list component. So let's keep it like this for now. And I am going to use the children later when we are going to have the categories page Garth and check out, et cetera. So first of all, let's make it like this. So when I go to the products, I must see that bait or product list item which I created, but in products library. So first of all, we need as well to use this route, how we are going to use it. So if you remember, we are calling a router module, but throughout our module is used purely here, but we need to give it a property which is called for child, and this child will have accepting the routes. So in this case, I am saying that this products module is child of application module and it can uses it routes. So when I go now to my application and click on products, okay, I have product list work which is located in their products library. So in my application, I have only one route, which is, for example, the homepage. And in there my products module, I have their route for the products. So all the products list. So here we have products. We are going to this route products. And then I will see that I am really directed to product list component. So now let's dial this component and make it works. So we will have on the right, like the products list, and on the left we will have the categories list. So we need to call to services, categories and products. And those both we made them already. So let's go here and define our components. So first of all, I'm going to use that grid so we can wrap everything inside a div and give it a name. We can say products list or products page. So we can, it's up to you and we can give it like a name like this. And then we are going to have the div, which is called B grid for having like a row of grids. And then we are going to have two columns. So one will have three columns. So we have here P, call three, which will contain the categories. So we can say here categories. And as well, we are going to have another div for the products item itself. So we have here div and P call at it would be the rest. 12 minus three will be nine. So we are going to put the products here. So let's Save to be sure that everything is working. So I go here to my application perfect, I have here category and I have here the products. So let's start with the products. If you remember, we have created in our products something like a component which is called product item. And this product item, we were calling it everywhere, for example, in featured products. So I am going to use the same. So we can exactly do the same thing which we did. So we have here like product item, but first, let's divide it. So we have inside this div, we will have another grid. So div dot grid or p grid. And inside this B grade we are going to have multiple columns. So pair row, it will be three. So I will have P call for. So inside this, so we will have three columns. 12 divided by 4 will be three columns. So we are going here to use our product item. So we have here the product item. But first, we need to pass for that, the products. So we need to call again the product service, not feature product, but we are going to use the product service, all of it. And then we can be able to loop over the products and get products. And here it will be repeated multiple times and it will list my product. So let's do that. So I'm going here and call my product service. So I would say here, private product service. And here we will have product service again. And we are going to define a class member which is called products. So it will contain my old product, it will be type of product and it will be array, and at the beginning it will be empty. So here we are going to have method which is called, we can say get products and we are going to implement this method. So first, I'm going to have here as a private good products. And this gets products will use the product service. So I will say this dot product service, dot get products. We have defined this method already when we created the Admin application. So we can use it again here. So I will have here subscribe. And then after subscription, I would get the products. Themselves from the backend. And then those products, I am going to assign them to the products or to the class member which I have defined previously. So I can reach it saying this product and then use the response products so I can give a name like risk products just for you to not be confused between names. So we are going to assign that to this array. So after that, we are going to the template. And then in the template we will say MD4. It's exactly how we did things before. We were explaining it in very detail. So we say let product off products, which I have defined in my application or as a class member, and then loop over it and display for me the product item. So let's save that and go to the application. And we are going to see that we don't have anything because I think I didn't save the template or no, maybe I didn't assign the product. So I have here product input as you see. And then I need to assign their product, which I have got from the for loop. So here I have product, and then I'm going to assign that products here. So when we go again to the application and we will see that we have listed all our products and using the product item which we have created previously. To avoid sometimes error may be the products are not going to be ready. So it's better to not display them until the products are really ready. So we have to say here, ng-if products. So if there are products ready, then this grid will be created. And then we are going to loop over the products for every product item, as we see here. Now we have all our product list ready, we are going to create now the categories. So categories will be exactly the same. I am going to call the category service. So I would say here private. And then I will say category service. And then category service will be called. And here we are going to say as well, this though, getCategories. So we are not going to get only products, we are going to get categories as well. So here we are calling this method. We are going to create this method again. So we have here getCategories private and then getCategories. And the getCategories, we are going to use a gatt service and this category service. It were returned for me all the categories. And then we subscribe. And then we are going to have the response categories. For example, a response gets. And then we are going to define a variable or a class member. We are calling it categories. It will have a type category and it will be array as well initialized as an empty array. And then we are going to assign this variable categories to our response categories. So we have here response gets. So after that we are going to use it in the front end. If you remember, we have column four categories. So I am going here to have, for example, H4, and I will say here categories. So you can give it a title on the top. And then I am going to use the prime end the checkbox. As you see here, we have prime NG component, which is using as a checkbox. So we can use that as well. So let's use that basic one like this one. So first of all, we can copy this part in the sources. We can have here a div, and this will have a field, and it will have NG model input ID. And I will see how we can prepare that. So we are going to have here in the field itself. But P checkbox is not important because we need to import checkbox module to our products module, not to application module because we have that component inside the products module. So let's import that as well. At the end of their imports, I am going to say like checkbox module. And this checkbox module with come from Prime NG checkbox. So we can as well imported here, Import and say check box module from prime and g slash checkbox. So we are having now that checkbox module. And if we go to the application, we will see that we don't have the error here anymore. So now we are going to use this checkbox and we are going to loop over the categories. So again, we need to have here NG four, I will say n 24 and this MD4 lead category. So I'm going to loop over all the categories. So I would say that categories of categories which I have defined previously. So first, I will say that this checkbox will have, will be binary, like true or false. And it will, or the ID will be, we can put it as input. So we can put here category dot ID. So I will have, the input will have this ID, and then we can give like as a label not checked, but we can give category dot name for example. So in this case we will have this category dot name displayed as a checkbox. And here for, it was here for binary. So we need to change it to category ID. So in that case, we will have here NOT input id like as it was before binary. It will be the category ID. So the four, so when you click on the label, it will be checked or unchecked the checkbox. So here we have to say as well, give me the category ID. So after we save that, we go to the application and we will see if we have everything nice. We have now the categories listed as checkboxes. So in this way, we are going to create our filter, which we will see in the next lecture. 150. Filtering Products by Category: Okay, now in this lecture we are going to filter by category. So if I go to my demo which I have prepared already, I want to show you how I am going to filter, as you see here, when I click on More, while I see only mobile, but when I click as well on beauty, then I am going to have a beauty and mobile together. So in this case, we need something like combine all of these categories IDs, and send them to the back end. And the backend will reply with me with those categories IDs for those products. So going back to our application, we are going to implement first something. When I click on this checkbox, something will happen. So let's do that. So first of all, we go to the template and we will see that we have here checkbox and we have here some error. This is NG model isn't known property of peak checkbox. Why? Because we need to import as well forms Module, forums module including the, of course the NG model. So we have here forms module. And in that case the error will disappear. Okay, now we have that fine already. So what are we going to do is on change. So when this checkbox change, it states, then we are going to filter. So I am going to have here a method which is called onchange. And it is coming as a property or output property from this checkbox. So let's put this down. We don't need it anymore like this to have more space. And now I am going to say onchange, okay, category filter. So we have here category filter. And I am going to define this method. So let's go to the TypeScript file. And we will have here public or directly method, which is called category filter. And now we have to console log like something. For example, say console.log category filter, for example. To be sure that everything is working fine. So I have here category filter. I go to my application, open the console again and check if we are having perfect. So we have category filter. As you see after I added the NG model, we are seeing that all of them get checked. One, I have one check. This is because I have defined one variable for any model. So this, when this variable is true, all of them will get through, like all of these check boxes which are generated in this MD4 loop are following this variable. So we need something separated. We need to specify that for every category. So for that, I need to create for every category some field which is called checked. So if this field is checked or not. So we can do that as well when we go to the category model or when I say, for example, category dot checked. But I will get an error here because there is no field in category called checked, so we need to add that. But in this case, I see that these checked will be for every category true or false. So to explain it more, let's do that. So first of all, I am going to define this check. I will go to the models which we have defined previously. So we have here category and in that category I am going to have checked. And it will be optional with a Boolean value. So when we go here, we will not have this error anymore. And then on category footer, I'm going to show the categories. So in general, So I will say here, console log this third categories. So we have here to this load categories. So I don't want just to see that all of the categories on every click of checkbox I have here. So let's close this as well. And now when I click on check, I see that they are all checked because I didn't save. I'm always forgetting saving. So we go back again to the application, it's reloaded. So when I click on mobile, for example, I will go here to this console log and I will check more while and open it. And I will see checked through. This is very good. But here, if I go to this category which is called the beauty, I don't have that checked field totally. And now let's remove all, let's close this part or remove the console and uncheck the mobile. So when I check them want while and then go here, I will see checked is false and the others are, doesn't have anything. So in that way, I can't say that I or I can filter based on which list or which categories are checked. And then I can get their ideas and then send it to the back end to get the filtered products. So we have to translate this dog. So first of all, I need to get only the filtered or the selected categories. How I can do that. So I'll category filter. We go here, I will call again that get products, but with some filters. So with ideas of categories which I want to pass to the back-end. But before that, let's do, for example, make a list of selected categories IDs. So we can have list of categories IDs. So on category filter, I am going to have a constant. For example, I call it selected categories, for example. And in this selected categories, it will be this dot categories. So you don't notice every click when I click on Category filter, this will be executed. So selected categories, I am going to filter, filter categories. So how I will filter this is filtering array or we are going to filter the array. So in that case, it will filter and return for me only the categories which are checked, which has felt field checked through. So how we can do that? So I will say here filter and this filter, it will return for me or I can get from it category, Category one by one. And with arrow method directly, I will say return for me category, which is checked. So when they are category is checked, then return it and then put it in selected categories. So after we do that, let's console log the selected categories so to see if we are really getting only the selected categories. So we go here, console log. I like to use console log. Also I can use a debugger, but I like console log because I can't see the results live in front of me. So if you want, then you can use the debugger as well. So, but now we have here the selected categories. I'm going now to click on mobile. Okay? I have only the mobile. That's very great. So let's clean again, click on beauty and computers. I will have three items checked. But I didn't get all categories, which is so good. And if you check here, you will see all of them checked through. And every time I click on check, I have reduced again the categories. So they are now two. I have mobile and computers only checked. That's very good. So now we need not only selected categories you see here, I am returning back all category. I want to return only the ID. So in that case, we have here, the filter is returning for me array. So as you see, we are returning array here. So I can map through this array and give it again like some new shape. So I will say like again category, but not category itself or returned for me, but return for me only the category and ID. So in that case, I would get only the categories IDs in selected categories. So let's try that again. So I will go here, mobile. So I have that idea of mobile category computers, okay, I have two IDs. House, nice, I have three IDs. So in that case, we are selecting or collecting the ideas of selected categories. Now we need to pass them to the API and give back the products which are assigned with those categories. And if we go to the postman, if you remember, we were passing to the backend the categories as a query params. So when I send a request with to get their products were and when this request has categories or categories ideas, then it will filter for me based on the IDs which are passed in that request. So we can do that easily. So I can have here in man, the categories or we can have their key, which is called categories. If you remember, we have created that. And the values will be the categories separated by comma. So we can have those categories as well. So we can go here, for example, we can pick up the first one and go again to the Postman. And we can pass, for example, let's get one now. So I will have the products, not all of them. I will have only the products which have this category. So when I click, I will get, getting goodie of the phones. So I will have products or two products which are phones exactly how we have it in the front end in the demo. So if I pass another category, like for example, if I put comma and then let's get the category of another one. So we can go here again to Postman and then pass with a comma, another category. Then I will get perfect two or many products based on selected categories. So in that case, we need to adjust our product service to get also or past categories through it to the backend. So how we can do that in the front end. So after filtering or category filter, I need to get the products again. I want to call this again, and then I will update the product itself. So how we can do that? First, let's remove this console log. And then I will say here that call for me this dot product or get products, but with categories filter or selected categories. So here we have already array of selected categories, array of IDs, and we are going to pass it here. So I need to add as well to this method parameter, which will be categories, for example, selected categories, or we can call it category is filter. So we can have here categories. Filter. And this category is filter will have, for example, optional and it will be string, array of strings because we have filtered our categories and we are returning only the ID, as you remember. So now we have the categories filter. We need now to pass it to our products service. So we need to go to get products and then to this filter and then send it to the backend. So categories filter is undefined in this method. So we need to go to this method in our product service and adjusted to accept also get the goodies filter. And this categories filter will be array of strings. So we can have it as well option to not destroy that good products which we created in the admin panel application. So here we have it optional. So when you pass some categories, then, okay, it will give you the filtered products. But if you don't pass anything, then it will give you whole product. So the type of this field will be string, and it would be array of string. So now we are going to pass this HTTP request. How we can do that? First of all, we need to define, for example, variable which is called params. Here I am using lead, not const because I am going to change it in the next lines of their code. So this will be a new HTTP or HTTPS small letter params. So this is bombs coming from Angular and those you can call them from angular core library or HTTP library. So this params, we are going to pass them to their request, exactly how we did with Postman, how I am busing here, query params. And in the front end, how we can pass that, we are using HTTP params. Okay, here we have the palms are separated by comma. So we need to do the same as well. So let's check if there is categories filter. So we can say if categories filter like we have categories filter passed to not destroy as well that I told you the admin panel application. Then I will say that params will be params dot the band. Here you need to append one parameter which is called categories. Exactly how we did with a Postman. So here we have categories. And then these categories will be what? They will be categories filter, which I got from the front end or from the user, or from the check boxes. It will be containing the categories ID, but it's array. So we need to join this array to be one, like for example, like this, to be ID or ID of category comma another one, comma another one. So it's very simple. You can join an array of strings by saying this array dot join. And then you can specify what you want to join based on comma, based on dot or based on quotation. So you just have to say comma. So in that case, those categories will have the shape of this. So we save that and we save also here. So let's check if we are really doing right things. So I want, for example, to, for example, console log the params. So we can have here console dot log, and then we can pass the params. So, and now I go to the application checkbox, one category, okay, I have here update one array param, and we have one pattern. So if you go to here encounter encoder, we have the param is defined already. So again, if I click, I will get as well the HTTP patch. Are bounded inside HTTP params, which will be send over their request. I will show you how you can see the request is Br things or prompts or not. But for now, we are going on the right path. So for sure that we are passing the categories or the categories ID to get products and we are passing it to get product service. And this good products per service returned for me, the products. But now the request as you see here. So if I click on, for example, here, I click if I go to network again. So let's try again. Let's clean this network. I click here, I am sending as you remember, a request. So I'm not seeing anything. You have to be sure that you don't have only like one type. You are filtering by one type. I want to filter all so I can see all the requests. So I click on More wine, okay, I get to products as you see here. And this products request first, which is going through the backend and not loaded with any parameters. So we need to load some parameters or query patterns to this request. So here we will have a question mark categories, and then the categories would be separated by comma. Well, we can do that very simply when we go back to the GET request. And then I am going to pass object. Remember not the params directly, like you cannot say, Okay, boss for me the params know it or not, fork work for you. You need to pass object and this object, the one key of it will be called params. And then you pass the params variable, which we created here. So let's remove this console log and go back to our application, reloaded. And then we are going to, for example, the clean this console clean everything. I'm going to have more bile. Okay, I got categories. As you see in that request. I have here categories and their contiguity which I selected. And as well, if I go here, beauty, Okay, we have another request and search for it. It's products categories, okay, Nice. We have here the product categories and they are separated by comma. So in that case, now the filter is working by sending to the backend some request with query params. And the back end is sending me back the products which are under that categories. On every click, I click here, I am filtering. I'm asking the back end, send me back the products which are having this category. So in this case, we have filtered our product page. So we have filters products. And in the next lecture, I want to show you when I click on one of those categories in the homepage. And I jump here to the products page. I will show only the products which are under that category. So we are not going to have, we are not going to be redirected to the products page, but we will be okay using the product is component, but we will display only the category which we have clicked on their front page. 151. Category Page: Okay, in this lecture we are going to see what if I click on one of those categories and then what will happen. So for me, I would say maybe you, when I click on one of them, I will go to their products page as well. And then I am going to show only the products which are under that category which I clicked. And of course we can make additional thing so we can hide this sidebar and also just show their products. So we can do that easily. I am going to show you that in this lecture. So first of all, we need to specify a new route. So in products module, if you remember, we have some multiple routes and one of those routes as well will be four categories. So we can't have a new path here as well. So we can say, we can call it category. And this category will have as parameter as we saw previously, that we have category ID as well. So we will have the category ID passed with this category. So in that case, we are going as well to products list component. But in product this component, I am going to check if I am receiving my click from products which is coming from navigation on the top or from category in the home. So for that, we need to go to the product list component. And then we are going to have the activated route. So we need also to subscribe to the current route. So we need to know on which route I am, for example, on products or on category. So in this case, I am going to use another service which is called activated drought. So we can call it, call this service as route, and then call activated route from Angular. And here I am going on NDI on it. I will say, check for me, they're out. So here I am going to say this though, trout, which I have called as a service, then params, then subscribe to those params and then check what biomes I have. So we have here params and then I am going to check and handle those. Perhaps if there is in their params category ID. As we specified in the route definition, then bring for me the products using that category ID, which is passed in that URL. So we can do that easily. So I will say this dot category or good products, exactly how we did previously. So we need to cancel this one or remove it totally. Let's remove it. So I have here nothing. I'm going to get the products based on their category which is passed in the URL. But I cannot pass it like directly. I cannot say params dot category ID. Because I am passing to this method. Good product, I am passing array, array of strings. So we need to put this inside array, that simple. So you would just say array of params category ID. So it will be one category ID, which inside an array, which will be passed to get products. And this will be as category filter. And then it will grab the data of products of the category. So in that case, we are going to have only the products which are under that categories, which I clicked on. So you know, this is in line. If, so, if there is this thing or this variable, then do that. Otherwise, just get products without any filter, like get all products as we did previously. So here we say this dot, get products without any filter. So in that case, I am getting the products from the backend based on that category. Nice. So let's save that and try that out. So I am going to the homepage again so we can click Home. Click on mobile. Okay, we see that it's not working. Let's check our console. We will notice I think that we don't have that route so far that we have defined products category and then we put the category ID. So for that in the homepage, if you remember, we put or in categories banner, we said that, okay, I want to go first two products and then I will go to category. So we can define this as a child of this path. We can define the category vast as a child of products path. Or you can just adjust the categories Banner, as we saw here, to not have router link products category, we can have directly that category. So when you click Save, so I don't have products anymore. So when we click Save, go again to our application, I will click on one of those. Okay, I am still getting error because this is not defined because I didn't save, again their products module. It's always happening with me. So I need to save products module. I go again here, mobile, nice. I have here two products only and with that ID. But when I go to products page, I am getting all products. But when I click on one of those categories, I get only the categories which are under, I'm getting only the products, sorry, which are under that category. But I still have here that category sidebar, which is not nice, like otherwise you need to make it like as checked. Otherwise you can or other solution you can, for example, hide it totally. Let's make like some practical thing with hiding. Make this component dynamic as to learn more. So first of all, I am going first to not show this sidebar totally. So in that case, we have in the product list, we need also to check if I am in categories page or not. So we can define another class member. We can't say is category. For example, page ordinate. So I can't say as a Boolean, I can define that as a boolean. And then I go here to the params where I was reading the parameters from the URL. So I have parameter category ID or not. I can't do the same. So we can say ticker is barren dot ID, then set this category or each category page to true. So I am really in its category page. Otherwise set it to false. So, okay, why I am doing that? So I am going to use this variable in the template. So here in the template, when I go to the HTML template, I want first to hide their categories. So I will say here for their categories list, which is checkboxes, which is in column 3 as we define it previously. So I would say ng-if Is category page. So if it's got agouti page, then show it. But we need not is category page. We need to hide it. So it's not going to go to the page then. Okay. I did. It will be false because it will not show that. But when it's a category page, then it will hide this component. So it will hide this column here, which containing the checkboxes for their category. And here as well, if we save, let's try that. And we go here to the front end. Okay, We have here the categories. So we have here the product, sorry, so when we go to the homepage, I have here mobile. Okay. I have two items and when I go to products or I will get the sidebar with the products which I have them here. So it's exactly the same component, but it's behaving based on the route which is here. But I would like to mention as well about the case. What if we have more than three products here in the line? I want to show you what happened. It's a bug. So we need, for example, we go to, for example, two computers. Okay, we have three products. Let's go to the admin panel and go to our products again. And let's make one product to be like as a computer. So I go here to the computer, tom with this more wild and put it as a computer's category. Update that, and go again to our application in the front end. Okay, and I click on computer. And as you see that, okay, I got extra product here, but it's graphed down, like I have 123 and then it went one noodle. Because here it's empty. And this is happening when I have this column is still with nine columns. So let's inspect on that. So I want to show you that we have defined this as a nine columns. Now that category sidebar is hidden, so it's pushed their content to the left. So we have now this content grid. It has only nine column. So we need as well to make it dynamic. So we, we end, we want to make it as well as 12. So when I click here or I go here, I will have this as a 12 column, so it will be fully on the screen. So we can use the same valuable which we have defined previously for each category page. But I am going to use different class here. Instead of nine columns, I'm going to use 12 columns. So how we can do that? So you just say here NG class by this, and you define it as input for this div. And here you are going to define an object. And this object will have beat call nine when I am outside of category page. So when it's not category page, so is contiguity page is not. Otherwise, you can define any new class. We can call it. It will be called 12. And when is category page. So we save that and we see that when it's not going to go to page it will be nine. So as you see here, it's not contiguity. It's category page, sorry, and it's 12. So we have it here, 12 columns. But when I go to products, all of products, I have it as three columns. So we have it like nine columns. And here we have the sidebar column exist, so it will be as a nine. So in that case, I have also dynamic definition of classes here. So I can play in the template in the same component based on what I came from. So when I come from this page or this categories, I will have this one. And when I come from like products here in fundamental allegation, I don't have any parameters here, any category. So I am going to display this one. So but we have small issue here. So if I go to computers again, we see that they are a very wide, I want to keep them, for example, for in the line so we can use the same thing like we did with ng-class here. So we can put as well is category, is category page or not. On the, for example, this one where we are defining the width of the product item. So we can as well here remove this ng-class or this class and say when it's not category page, then make it as for example, the 3, how it was before or four. But when it's category page, then make it as a three. So we will have here four columns, because 12 divided by 3, it will be four. So let's save that and refresh for me the application automatically. And we will see that we will have four products here. And when I go, because here I am in Category project or category path. When I go to product, I will have them here as three as well. So you see you have a dynamic, dynamic area to play with your component using from where you are coming. So we used the same component, which is very nice to have to list the products based on that. So now we have more freedom for the user to move inside my application. 152. Product Details Page: Okay, in this lecture we are going to see how to build the product detail page. So we are going to create a component which we'll refer to a specific product, especially when I am clicking on one of the products. So I will go here and I will see the detail of the product in all of the details. So first of all, we need to have like some title and some description we will have as well. They're rating. It will come from stars which are going to use from Prime NG price. And we can add like some fake offer. And as well, we are going to add this quantity so you can select how much you want to buy from this product. And then we are going to have two buttons. And as well, we are going to have the description which we have created as HTML in the editor here. So it will be rendered the same exactly how we have it here in the front end as well. We will see how to render the HTML, which is written in the admin panel, and it will be in the front end as well. We are going to create a gallery, so I'm not going to use some ready component. We are going to learn how to build a gallery by our hand. And with this, which we'll see you in the next lecture. And I want to show you that building the gallery IS or building a UI component in general is also possible. So you can use it everywhere in your applications. So we can build our own components like a gallery and vol example, star rating or for example, some slider. You can build it by your own and located in your libraries in your project. So let's start building this part here. And in the next lecture we are going to build the gallery. So first of all, let's have a look here. So we need a title description, rating, and then some price and quantity. So first of all, I want to create a component which will be inside Products library, inside the pages. So we have a page especially for product detail. So I will click on Generate and then I will have a component here, and it will be located as well in pages. And then we can call it product page or product detail. So it's up to you. So I'm going to call it product page. And the product page will be located in the project products. And as well, we are going to use the same options which we are using always. So here we have prefix selector, we will have here products. And of course it will be product page. Of course we are not going to use selector because we are going to read direct, directly the router to this component. And we are going to say skip tests. And then we are going to generate this component. We are sure that it's in products library. Perfect. We go here again and we will see that these page or product page is created here. So what we are going to do, we are going, when I click on some product here in my front end, then I will be redirected to the product detail. So let's say, for example, that we click on the image. So if you remember, we have created item, product, item. This product item, it has image, and we are going to put the link over the image. So when I click on the image, then it will redirect me to the product detail. So we have here the router. So what Router? We are going to use router link. And then I am going to use the product itself. So we are going to have here some code like the product itself, product ID. But before that we can say, for example, that I want the products. Like we can put it inside a string so we can put slash product. So take me to their products page. And then after that, add for me the ID, the ID of the product. So I will have here product dot ID. So the incoming product to product item, I will get its ID and slash it with their products. So let's go and create this route in product module. So in the product module, we have created previously product category and we are going to create another path which is called products and then the product ID. So we have here product ID. So in that case, every ID will come after the product's page. It will render to a product page component, not product list, but product page component. So we have created this product page component for this goal. So let's test that. So as you see here we have here all the application. When I click on the image, I get product page works. So this is exactly what we want and we have here the ID of their product. So let's go again to our code and we are going to template this product or this product page. So let's go to here and close all other pages. We are going to stay here. And by the way, let's create a style file. So if you remember, we have the public Styles in their lives. Product we can create as well here, some file for the products page. So let's give it a name product Page, SCSS. And then in the products, I want to import it as well, exactly how we do always. So we have two product page, SCSS, then every style I will write here, here, it will be imported to my application and the application can see it. So first of all, we are going to have a grid as always. So we can wrap this grid first in a product. We can call it product page. So we have here product page. At inside this product page, I will have a grid, so div, p grid. And inside this grid, I will have two columns. First one will be six and the other will be also six. So we have equal columns. So we have here P called seeks, and we are going to have another one which is as well be called six. So we have now the grid here. We are going to locate like some UI gallery component and we are going to locate that later. So I will comment this out. And we are putting here that details of the product. So first of all, I am going to have, for example, we can put here a class. We can give it, call it product. And this product we are going to put its detail. So first of all, I want the title of the product, which will be come from a product name. So we will see later how we are going to get their product. So for that, we need to have a valuable in TypeScript file to get the product detail, if you remember. So we created that service and we are going to grab it again and use it here. So we have here the product dot name, and then we are going to have the product description. So I will put it inside paragraph and give it a class, for example, product. And it will be description, for example, disk. And then we are going to put the product description. So here we are going to call all the information about the product. So and well, we have to go to go for a rating and other components. But let's first import the product so we can bring the product from the back end and then we can use it here. So first of all, I am going to that product page. I am going to call that product service. So we have here proud service again. So we have product service, which will be here. And we are going as well to use a router because we are going to get the ID from the URL. So we have here as well, private and route. And I am going to have activated route, which I grabbed from, from the URL. I am going to grab the data from the URL. So we will say here, this dot route, and then give me the params, which are coming from the back end or through the URL. And this params we are going to subscribe to them because every time we change the ID, we need to subscribe and catch what the ID is changing to see the right product. So we can say here params, we got the bottoms as well in the subscription. And then we are going to use this params to use it in product service. So we will have here this dot. Or let's do like if first params dot product ID. Like if we have a parameter which is called a product ID, then we are going to use this dot-product service. All we can say in separated function, get the product in general like to organize just our code to be more nice and we can pass the product ID here. So after that, we go to another line and we open a new method. We call it as well get product. So as you see here, we get product and this product will receive the product ID. So we can say ID, it will be a string. And then we are going to use this dot-product service and then get to product. And get product, if you remember it's asking for product ID. So I will give the product ID and then I will subscribe to it, and then I will get a response product. For example, here we can give it this name and this response product. I am going to use it to assign it to a class member, which will be called product and has a type. Product. So we are going to define a class member. We call it product. And this will have class which is type product. And we go again here and we say this dot product. It will be the response product. So that's it. So in this case, we are getting the product from the backend. We saw previously how we created this in the admin panel application. So remember always to end the subscription. So if you remember, I am always telling you to say these take until, and we are going to say these end subs, like two ends and subscription and n subs will be a subject. So we can define it here as well. And it will be subject and type any. And the subject will equal to a new subject, which is coming as well from our x js. And then we need to call onDestroy. So we have here in the class, we need to implement as well on this Troy. And we need, then it will give us error that we are not implementing the method NG on destroy. So you need as well to call this method. So when this component is destroyed, these dot n subs, sorry, this dot. And sorry, I need to put here the brackets and then this dot n subs, then next. And then this ends ups the complete. So in that case, when this ends helps complete, when the component is destroyed, this subscription will be finished and we will not have memory leak. Perfect, Now we have that a product. Here. We have everything we are going to check. Like if we have a product, then display for me the product detail so to not have any issues. So here we are going to have ng-if product. So if I have product, then display the product information for me. So let's save that and go to that front end. We will see that we got the product which we clicked. So if I go to another product, I would see that I got this product as well. So we are going to continue and style the things exactly how we did it in their demo. So I am going here, as you see, I am going to add now the rating, the rating, I like to use something which is coming from Prime energy. So you can search for it. It's called rate component. And as you see it has many usages. For me, I'm going to use the disabled one. So first of all, we need to import the module as we do always with every UI or every prime z component. So I want the rating module and then I will import it to my modules. So we can't put here modules, rating module, and then we are going to find out which one is good for us. So let's fall example, get the one which is called NO cancel this one and then we can disable it. So if we go to source here, you can see all of those examples. So let's pick up this one. For example, we can say rating, model and this thing. So we go again to our product page, and then after that we open a div and we can give it a name we call like product rating. And then we place this component here. So the rating which is coming from the backend will be product dot rating. So we can have here product dot rating, and then we are going to use it. So first, we don't need this cancel. We need to have the disabled. So if you remember, we have disabled and then we put it to true how I know that there is this disabled because I checked the documentation. So if you go here, you will see that disabled and non-disabled example. He did like something like disabled. He set it to true so we can do the same. So the default stars number will be five. So r naught issue here, we are able to continue. So let's take that in our application. So we go again to our page or product. Nice, we have here. They're eating. Let's remove this one. Let's see how we can remove it. So we have here cancel false. So we can give cancel falls. We put it back. So I have put here Council forms and check again the application. Perfect. We have it like this. And now we are going to add another things, which is the price of the product. So let's add the price. So I will have here as well live, which is called product price. And this product price will contain the following. First, we are going to have the product and which will be like with a currency. So we are going to have here product. Dot price. And we are going to have this pipe, which is called currency. So we are going to display the product in like a money. So in currency way. And then we will have another span to make like some offer. So we can have class and we can say price before. We can call it the price before. And this we can, for example, make it figured. For example, we can say product of price plus 18 and it will be as well currency. So every product will come with a price like this, original price and plus 18, which will be dropped off like this. And we can, after that, we are going to style it so we can make this big and we can make this like a line through so it can be dropped like this is a price before. And now we are going to have the quantity. So the quantity, as you remember, we have it here. So we have a number input in prime end. I am going to use this input number. And as you see, we have it here. So it's also a nice way to use it as well. We need to import that number module. I will go to product module, import that number module, and then use this input number module in my modules. And then we can check this component how it looked like. So this one which is called MAX mean boundaries, we go and check it. And we have this one, which will be like with a button so we can copy all of this line. And then we go here to the product page and we can say div dot product. We can give it like a quantity. We can give this class. And then we are placing these input number here. And also here we are going to not have something number. We are going to have quantity variable. And this quantity variable, we must define it as class member to read the value from it. And then we are going to use it to add the product to the cart with a specific quantity which is added here. So here it will be this UML sure, buttons. We can give here name, quantity and max Min. And we are going to have here as well quantity, capital letter. And then we are placing this to be a quantity. So when I click on the label, I will be focused automatically on this one. So when I click here, I will be focused on the import as well. So here it works fine. Of course we need more styling as we will see later. So the last thing which we are going to add is the buttons. And we are going to have here another div. So we have here div, and we call it like products. Actions. And these actions, we will have two button. First button will be four by now, and the second button will be four To Cart and Add to Cart, I am going to call method which is called ad product to cart. So we need to implement as well the method here. So we have another method at product to cart and we have it empty for now. We are not going to implement it. Now. We are going to implement it when we have a cart. So here we have used the button, which is coming also from prime end. So I used the button module, which we called previously for other purposes. So we have now here the button label and all are used as well, the rounded one. So if you go here to the buttons, We have here multiple buttons. So we have here as well, rounded. So you don't need to style it and make some rounding. You can use that directly. So if you go to source, you will see this rounded button here. So I used exactly this one. So as well, I put here the button for Add to Cart. So let's check that in the application, okay, we have two buttons. Everything is working fine and I push this button and it dealt with from its brother because you remember we are using those glasses to push things from each other, like Bim NG, margin, right? Two, then it will push it from the right. Now we are going to style this. So we have created a styling file. So I am going to style it quickly. We have, first of all, we need to have the product page class or the product class. So we have here that product, as you see in our product page. If we open it again, we have here the product. So we need to have product name, product description. So I forgot to give class here. So we can hear give a name as well. So we are going to our product name description, ratings, prize quantity, et cetera. So we are going to style all of this. So first let's start with the name. So that name will be like We can't give it font size will be like two EM like we can make it double size, it will be big. And then we are going to have the description. Description will be as well like font size will be like 1.4 EM. And as well, we are having their rating. So they're rating will be in the way they, we push it from up and down. So we can say margin 15 pixel 0. So from up and down, give it mod 15 pixel from up and down. And then we are going to have the price. So first, the price will be like this. So we have product price, we have the class already, font size. We give it, for example, 1, tool EM as well, and font-weight, we can make it bold. So we can give it like 600 font-weight border button for the whole container of the price. So we can have a line under it to separate from the action buttons, so on and the quantity. So we can have Border button, we give it one pixel and solid. And then we can give a variable. And this variable will have a sewer phase, which the colors which I am picking from Prime NG 300, which it will be a gray. And then bagging, we are going to be give some padding 25 pixel from up and down to push the content away from it. So let's save and let's see what's happening and what's going on here. So I go to the page, Okay, I have here the title, the description, I have here, the rating. And we are going to style this part. So here we have, if you remember, defined a class and this class, which was here for price before. So I'm going to style that one as well. So inside the price, we are going to have the class price before. It will be font size. We give it like one EM, like it would be smaller a little bit. And then margin-left, for example, to push the content a little bit from the left, we can give it 10 pixel to not be stuck to each other. And we can give a font-weight will be like a 100 to make it lighter. And we can give it like a lighter color. We can say var, like Sure, phase. It will be like gray, grayed out. So soon phase 500 is good. And then for example, text decoration like to have how to say line through. So we can give line through of this like the previous price. Then we can check that if it's working fine. You see, we have now a line through and we have the price of the product. I would say let's make it a little bit bigger. For example, here we can have, the price can be 1.4 and we can check it again. We will see, okay, we have weaker price and then we have the font size for this is not taking any effect IF I know why, because here we have 1 for EM, okay, When I put here also E M 1 M, then this mean that it will be the size of the parent. So here I can say that Patents are, or the size or font size of this class will be one EM, like exactly the same of this size. So when I put it like 0 or 0, for example seven, then it will get smaller. So because EM is like a how to say it's related, It's related to their parent. So when I say related, then it will be the same size if I put it one EM, the same size of their patent. So in that case, we are going to make it smaller and we put it 0.7. So if I make this one bigger, like if I put it to, for example, this as well, we get bigger but with percentage which is smaller than the parent, because I have it here as well, 0.7. So this is the EM units, how they are working. So now we have everything. Now we are going to style this quantity. So first of all, it's pushed a little bit to the right and left because we have here with their class, if you remember, we have something like a P call 12 PM D3. So we can give to this class, and this class is, are coming by default with padding. We can give it as well, bedding 0. So let's initialize this to be padding 0 and then it would be pushed exactly. So now we are going to have the quantity as well. So I'm going to have this class. So we have here after the price, we open a new tag and say that quantity, we give it again, like margin top or margin right and down. So we can have margin 25 pixel and 0. And then we can give the label which is inside this bigger font, bigger font size. So we can say here to the label will have something solid label is wrong. The label would have font size, which will be for exam 1.2 M. So we can't say as well here 1 to EM. So we will see that it got bigger exactly how we wanted. But as you see, I want this orange, like my buttons, I have everywhere buttons with orange. So we can have as well that, so we can override the buttons here, which are coming from Prime NG. So if you inspect to this button, you will see it's a normal button. And this normal button has a class which is called PI button. So let's scroll until we detect the color. So if we go more down, we will see the button and it has this color, so we can change this background. So let's catch this class. This is the benefit of having public styles. Otherwise we will not be able to change it easily inside the component. Because if this gloss component, then we are not be able to change that. So we say, like the background color of this button will be primary color, which I have defined my primary color. And then border will be 0 to not have this blue borders. And now it will be, I guess, orange as you see here. So it's very nice. Now we are going to style also those buttons is very simple. We are just having here, not quantity, but we have defined a class which is called actions. So I can go here and I define actions. And inside this actions we have as well PI button. We can copy the same thing here. So we can have as well the background color to be orange of this button. So I'm not sure if I have the right name of the class. So we can have here quantity. And here are sort of action is not actions. So I have to put S. And now it will be, I think orange as you see here. Nice. So all we have now everything I just missed one thing, which is the description of the product. So we are going to have a new grid. So a new grid in the same level. So because it's getting the whole space under the product gallery and the product page. So our total lack detail. So we have here another peak grid and then we are going to give a div be called and then 12, like it will be fooled. And inside this div, I'm going to grab the data of the HTML data which are coming for the product. If you remember, we have here in the admin define this one and it's coming or saved in the database as HTML. So how we can grab that? So because if I go here and I say, okay, print for me product that reach description because we stored it in reach description as you remember. So here I will see that I will get HTML code, which is horrible. So we need to do something for that. So the easiest way to do that is to define a div. And this div, you can use some DAG, which is coming with Angular called inner HTML. And inside this inner HTML, the input, you can say give me product dot reach description in that way. So all of the content of this div will be rendered as HTML as you see here. So we need like some more styling because it's overrided by the styles of prime NG or of my application. So we can give, for example here, I also like something like product and reach description for example. So, and we are going to use this class as well so we can hear their actions. And we are going to have outside here because it's not inside the product. So we are going to have it outside here. I will have product and then reach description. And then I am going to have line-height, for example, will be 1.6. So in that case, I am going to have like some spaces between all of these items. So let's Save as well the HTML because I didn't save it. So we will see that we got like some more beautiful line-height here. So in that way, we have the description of the detailed description of the product. Now what we are missing is a gallery. I'm going in the next lecture, create a component for the gallery. And then we are going to grab the data here and put them or the images and put them inside that gallery. But before we leave, I see that we have error in the console. So if you see that read description of undefined, so I want to mention that That's why I told you you have to put the ng-if product. So if there is a product, then we are going to display that product. So I prefer to move this one to the top, like to their container div Like all of it will be contained here. So if there is a product, then display it. If not, then don't do anything. So in that case, you are not getting that error here. So this is all about the product. As I told you, we are going to create the gallery in the next lecture. 153. Product Gallery Image Component: Okay, Now we are going to continue with our product page and we are going to implement the gallery, the gallery images of the product. So if you remember that we have previously coming with the bullet Act request with all images, which is called images field. And we have the main image where we are displaying the product itself as you see here. And also that gallery image where the or the images, where the images of their gallery are stored. So if you want to work on this component, we are going to not to use something from Prime NG. Of course prime NG also providing some gunnery, like for example here, this one, if you check it, It's called gonorrhea and it has a very nice like documentation and you can add images and remove them dynamically. But I am going to use in this lecture my own component because I want to show you how to create UI component as well and use them inside your application. So first of all, we are going to create that gallery component in your eye library. If you remember, if we go to ellipse, we have a UI library where we placed our banner components. So we are going to create a new component, which is called gallery. We are going to call it UI gallery. So first, I'm going to generate a new component user using this NX console. And then we are going to call it inside the components folder. I'm going to give it a name which is called gallery. So it will be like gallery images. The project will be UI. And the same thing for all the other options which we wear using here. So that's why I told you at the beginning of the course, just be patient. You will know everything, why it's happening, why we are checking those checkboxes. So now you know them all. So the selector will be Gallery, like, like this way. And because it's starting with the name of the library, as we said, they're all in the ES linked. So now let's create this component and run it. Okay, their component got created. Let's check it. We will see that we have gallery here and also it's placed in your module and as well, It's using that. It's exported as well. Okay, now let's move on. As you see in my demo which I have prepared already, I have the main image and then two images, and I am clicking over them and this image is switching. So we need something like div, main, div where I am displaying the main image and here like some list where I am going to display multiple images. So let's go there, do the gallery work, and then we are going to implement that. But first, let's call it in our component. So if you remember, we have empty space here. So we are going to call this gallery inside our products. So let's go to that product and pages, product page. And if you remember, I commented out here, the UI gallery. So here you, i gallery, we are going to call it. And we see that it's still giving error because we are not using the UI module here. So let's use the UI module here. Module where I am going to exported or imported. It will be imported from UI library. So we are going to have import. And then your eye module from. And then I will put the organization name, then say you, i. And in this case, I will see that my product here or UI Gallery, the error this app yet. So let's save all and check if our component is placed there. So let's go here. Okay, gallery works. So we are going to fill this area. So let's go to the gallery component. As I remembered or as I told you previously, you press Control P and then you can jump to any component you want by typing the name of the component. So I have here gallery component, nice, I am here. So it's better like to not search here. So now we have galleries work. So let's now create the template. Okay, for that, I am going to create a div and give it a name gallery. And this gallery will contain featured image, for example, or main image of the like we have on the top. So that dv will be inside it, an image, and this image will have a source which will be the selected image which I am clicking on. And also the other images will be under it, like we can have here div. And we can call it images. And those images, as I told you, a tool B lists so I can use. The UL and LI. So in that case, I can say UL and LI and inside that after pressing tab, if you see that we are using Emmet, so it's auto completing my HTML code. And here I am not going to use to put image like in that way, like here, image something. I want to show you a different way to put image as a background. So we can put a style background of the image and then it will be displayed as the image this LI. But now let's put like something just to be sure that everything is working. We can say image. And here we have a source and we can, for example, call, we call it selected image. And this will be a variable. So we are going to have this as input. So we need to define the variable or this class member selected image inside the ts file. So I can go here and define a class member and call it selected image, and it will be a string. So here we are going to use that. Let's save everything to see if we are doing well, like so we have now that we are not doing any mistakes, So we don't have problems in their code. And we must see here, Okay image, but I don't have main image. So let's make a static image. So I will go here through the ts file again and give this like some images. Image. For example, I go to the Assets folder of my application and then I will call an image. Of course, you can call any image on Google. So for example, I am going to put URL of some image here. For example, I am searching for imagery is called product. I am going to go to this image for example, and I will say copy image address. So if I go here and then I put the image, okay, I have the image address here. So let's go there and place it in our selected image valuable. So here we have selected image, and then we are going to have the selected image, I think, in our application. So after we save that, we go to our application, we will see that this image is placed here. So if you know that we source input when you are using as input, then you will have sudden source as input, which is coming from variable, which is defined in the ts file. Otherwise, it will be only a string and it will not give you any input here. So its better always or not better. You have to put it as in this bracket to say that this is input and I am going to use valuable, which is defined in gallery component ts file here. So after we save that, we are sure that we are getting the image. Now we are going to receive the images, list of the images, how I can receive list of images. So if you remember, we worked with the inputs. So this gallery, I think we'll have an input that's removed. This part here. We say here, nothing, just really make it empty. And if you remember, I talked about the inputs. So input is something where I am going to define input for this component. So this component will accept that input and use it to render itself in the template. So we can say images. We can say it's array of string. We can have an array of partners, like we will not have one path only. We will have multiple images, multiple parties. Why? Because I want to display this part here, list of the images. So we are going to use these images here. So after that, we are going in this LI, I told you we are going to use different way. So here I will say, I will give it like MD4. So we have here NG four. Then let image like one image of images, the images which one is the input which I have defined already. So now after that, we are going to say that we can give the image as edgy style. As I told you, this is different way of giving the image. So I will tell you why I'm doing this. It's just for sizing. So I want to keep fixed sizes for all images to be the same. So I am putting them as a background color or a background image. So here we can have background image. So you can define like that back ground image. And then this background image will have URL like this. Because you know, in CSS, I am saying the image, background image as URL. So in that case we have here URL. And then I will put another double quotation and plus, plus. And in the middle of this class, I would put the image which I got from images. So for every loop, I am going to have one image and place it here so the URL will be replaced or placed here inside this background image URL. So in that case, we will have our image. But of course. We still need styling. So let's style that first so we can see or what's going on. So first, as you see here, we don't have anything. So we can have here also saved to not have error. So we save everything. Again, we have nothing. So now we are going to use this component, this one u i gallery to put it where in the product page, in the product page and give this gallery input, which is called images. And these images will be the product images. But first, let's do that. So I want to show you that this request, how it's come from the back end. So I want here network, I will go to DevTools and open networks. And let's refresh the page and search for request, which is ending with this ID because I, the request is ending always with our product ID. So as you see here, I have this one. So if I go to Preview, when I click on it, I will see that I have brand or everything about the product. Now we are going to have the images. If you see we have image which is main image and then images, multiple images are here, which are coming from the back-end. So we are going to use those images in our gallery. So we need just to say product, like the input which we defined already. We say images will be product, like that product which I am using images. So as you see, we have now input the, our gallery inside, like this product page. And we are passing the images to that input. And the input or the component, we're render it in this way here. So let's go here and glow that we will see. Okay, we have some stuff you heard about. They are totally unstyled. We are going to style it. So first of all, let's create a styling file. So in the public styles, we have library and then you, i, and let's have like gallery as well. Dot SCSS, sorry, it's CSS, so we have to put it as S, S, S, OK. And now we have to import that. So we say also import for me gallery. So we have in that way and this UI is important as well in any shop. So when you shop can't see that. So now we are going to use or style that Ghana. So you can use as well my way, I am going always in that way. So I separate here the screen so I can here see what classes I used. So I will start with gallery. And this gallery contains main image. And as you see here, and main image, for example, let's keep it like for now empty. I am going to have also the styling of the images. So we have here images. And those images, as you remember, we have defined them as U L. So this UL will be a flex. So we have to make a display flex so it will be aligned near each other, those elements or those allies. And we initialize it with margin 0 and bedding 0 because it's coming with a default values from the browser or from the library. So now we have this flex, and let's check if we are really putting near each other, putting them near each other. So we save, okay, we still don't have anything because we need to tell the style of the LI as well. So we save and then we continue with the LI inside this UL, we have an LI and we are having, for example, background size. Remember we have the background image which is defined there, so we put it on cover. So it will cover all the area which has a width of 100 and pixel, like I'm going to give it 100 pixel width and 100 pixel height. And always LI items, we need to give them a display block because otherwise they will be displayed as a text, inline texts, they will be near each other. So when you give them display block, it will give her it or give it a behavior like so. Let's save and then check that what's happening in the front end. Okay, your dice, we have now all of them near each other. So let's have again, more to styling. We are styling the images. We didn't style it, the main image. So we have to give like something margin, right? Like to put them far from each other a little bit. Let's give 15 pixel. So we can have in them like separated. Now, it's very nice. We are going now to style the main image, how we can do that. First of all, we need to give this variable a value. So let's clause and then go here again. And I am going to give a value to this variable. So this variable should be, as you remember, some URL which is coming from the back end. So what we have here, only the images. So in that case, I can display the first images or image of the images array which is coming from the products page. So in that case, I can't say in my energy on, in it, this selected the image will be this dot images like these images, and take first member of the array. So to be more nice, you can check if there is images. And these images has length, like there is items inside this image, then you can give it the selected image to it. And as well, we need to check the gallery as we will see later if there are images or no. So now we have these selected images is placed here. You see, we have now the main image is placed. And then we have also that gallery images under it. So let's style this a little bit. We are going to use some styling on it. Let's go to the styling file so that div of the main image here will contain the image itself. So I can align everything inside it to the center so we can give text align center. I'd like to make it in the middle just to make it a little bit on the middle of the, of this page or this div. So after that, we are going to have some values for it. Like we can push the content under it, about 15 pixel. And as well, we can make a height, we give hide like 600 pixel maximum to not be very big. And then we can style the image inside it. So you remember, we have the main image in the div and inside it there is image. So I can access that directly. I can say not, Oh my God. I say EMG image will have max width will be 100%. So I don't want to put the image more than the size. Otherwise, it will be pushed inside this content. So I wanted to have maximum 100% of the parent container, which is this one. So we are having a max width 100% and we give height 100%. So to have the height of the patent like 600 pixel. So let's save that and try and check if we are doing right. Refresh, Nice. We have all the items are styled. We have this 600 pixel and we have here that gallery images. So let's now make those in the center. How we do things in the center, if you remember, we are using flex so we can say justify content of their container, which is the URL to the center. So after that, we will see that after loading, we will have those items centered. So look, we have very great gallery and the first image is selected, like this one is selected. So let's now make the clicking. So when I click on one of these images, I'm going to change this image. So it's very simple. I'm sure you are thinking the same like me. So here I'm going to make an event. We can say click. This click will have like for example, change selected image. So in this way, I can be able to switch the image so we can't pass as well the image which I am selecting here. So let's go now and check that. And we can create this method. I can simply say here in the ts file, define a new method here, which is the same we are calling, and it has image and it will be string because we are using image URL. And then we have here that these two selected the image will be the image which I got from the front end. So let's rename that to image URL. It's better like to have more because image is expressing like a data. So we can make it like that. So image URL here as well. So we can have. Image selected image URL, selected the image URL. Here we have another one. And then here we have syntactically images. And we can say also this image URL. So to not have confusing naming because we are not passing the image itself, we are only passing the cell, the URL of it. So here we are saving that, Save as well, this component here, and we are going to check that. So we dialed not going to use the constructor. I will show you that we have here arrows. We are going to fix them all. We're using an X, as you will see later. So we have a two, for example here it's complaining about that. I don't have method inside this because it's empty, so it's better to you delete it if you don't have or if you are not going to use this method. So we save and we are now clean of errors like broke grammatical errors. So when I click, as you see, I'm clicking on the image and the image is this switching. It's very nice. And as well, we are going to check if we have images input. So you need to check if there is images input. So it's better to make that very easily. So you can't say that get is its method like you can define a getter and say has images. So in this way, you can define this method as a variable which can be used as a variable or a class member and use it in the template. And I will say return for me this dot images dot length. So I want to check if it has length more than 0. Then I have images in the component. So I have images from the front end or from the product page. Otherwise, it will give me false, then I will not display anything. So it's the way how we do that. So here we have ng-if. So, if there is a gallery, so we can say here has image. So if it has image, then display all component. Otherwise, don't display anything because in that case, I'm going to break all of the staff because I am using here images, links, and multiple or other stuff here. So in that way, it's better to always use this valuable. So I will say here, if this dot has image, so, and as well, when this comes as undefined, then it will give me a problem. I will show you like that. So let's go here and I am going to save everything. So I want to show you that when we have no images in the array, in the input, just to be a bit careful with the inputs, because in that case maybe you will cause broken component and it will give console errors. So its better always to be sure that the input is really has data or not. And then, especially if it's an array and you are looping in that array and doing some stuff in the template. So it's better to be sure that you have 3D images and then display the template. Well here. Because now I am asking if there has images and then if images is undefined, I will get error. Length is undefined or you are calling lengths from something which is undefined. So in that case, we would get an error. So it's better to solve this as I will show you now. So let's go here and give empty array of images. I'm not going to give anything. So we can't say null here or undefined. So we can save. And then of course we will not get anything in the gallery. But we are going to get an error in the console. We are saying length of null, as you see here in the gallery component ts T2 and T4. So if we go to this gallery component ts 24, as you see here, I am saying, Okay, there is error here. So that's why I told you it's better to check every line of code when you are using, especially the inputs. So TypeScript is giving you the ability to check that by putting a question mark. And then if this undefined, then it will return for you some value. So let's try that again. We save when this image has null value, then it will not continue here and it will return undefined in general. So now I don't get this error anymore as you see here. And also my gallery is empty. So I guarantee that with this question mark, I said that, okay, if there is this undefined, don't continue their condition, just return undefined. And here, when this is undefined, then the whole gallery will not be displayed. So you see, always be careful about your inputs. So that's why we are doing here practical things. Otherwise, you are going to be in troubles. We have a lot of error in the console and you will not know from where they are coming. The last fix I want to add here that we have here you gallery is giving error, deselect or should be prefixed by one of the prefixes, blue bits. So because here in the ES lint file inside the library UI, I define that. Okay, I want that attribute as blue bit specific to his blue bits. So let's fix that as well. We make it as you see here. And as well, the element or the selector will be prefixed as UI. So when we save that, we go again to our gallery. Of course it will take sometimes to like sometime to be fixed or it can be fixed immediately as you see here. And as well we have here the banner, you I banner also fixed that error. So in this way, we are not having any errors here. We are clean. But anyway, we are going to fix them all at the end, as I will show you later with an excellently. So that's all above the gallery. Now, let's put back the error, which order they're mistake which I made here so we can have the product images. So now we have seen all the gallery and we finished totally the product page. So I can see any product images, for example, this one, and also any other product which you want to see. So in that case, it's very nice. We have fully implemented the product page. We are going to work next section with their cart. We are going to add to cart, we add that quantity and we will are going to work with NGO RX for saving the cart items. And we will see how it's changing here immediately. 154. Cart Service in LocalStorage: Okay, so back to our diagram structure. We need to create the checkout component, card component, and user history component, as we saw in the overview. So now what we need first to create the card component, but also the card component need a cart service. And this cart service, you can create a library for that. Or you can place as well all of the things in orders library, which you see on the right. So on the right, the oldest library will be responsible for the checkout cart and also like all users order and as well maybe we can manage the payment. So first of all, let's start with the cart. The cart, I am going to create a service which is called cart service, and it will be located in orders library. And for observed week, the cart we are going to use algae well, the observables or NDR x. So I'm going to show you both ways. I will going to start with the easy one, which is like observables. So we can observe in the header as you see here, something like we can see always live update on the cart. So for example, when I click on Add to Cart Here, Okay, it's added as well. When I again click on, for example, let's go to products page and I click to this product. I see that how you see it's updated so we can see how this card is getting updated live. So I'm going to use both ways and DRX and observables. But now let's start with easy, which is observables. So back to our project and code. Let's create a new service, which is called cart service. And it will be located in order service or order library. So we can go here and again to NX console generate and we have service, and we are going to name this service inside a folder called services inside the orders library. So we can have here Services cart. The project name will be orders, and we have to skip that test. We don't need them currently. So after that we create this guard service and we are going to feel our code there. So let's close everything goes two lips and again, low orders and then lips and services. And here we are in our cart service. So the cart service will have, first of all, like some, for example, initialization for the cart. So for the card, I am going to use the local storage. Why local storage? So when the user come back to the shop after reloading the application, I want to keep always the card which he filled previously. So I want to keep all the data of the guards which he feels P4 to not lose them. So for example, when I move especially from page to page, or for example, when I leave the application going somewhere else, I want to keep the guard data still the same here. The best way is, as you see here, that we can use the local storage. The local storage will have, for example, the cart. And remember we saved also the JWT token here. And now we are going to save that Cartier as well. So the cart will have items and every item will have Product ID and a quantity of that item. So in that case, I can save the product which is used and also the quantity of it. And as well, when I want to add something to their cart, again, I will see that this cart cut updated and we have the quantity for the same product. So I don't have to add the product again, but I just increase its quantity when the user click on Add to Cart multiple times. So in this case, we need to have something like local storage. So when I refresh my page, I go here, refresh. And I still see my cart items which are located in their cart page. And also we are having those in the local storage. Some people as well using the database, they are stalling the guard of the users in the database. But here we are not logged in yet, so we are just losing using the local storage, which is like for public, for everyone, any user, it's only saving under the domain, which is local host, or for example, my e-shop dot com. And this might each.com, we'll have local storage as you see here. And this local storage will have a cart. So whenever the user come back to the shop, again, he will see that his card is still there and he didn't lose the cart items. So here we are not forcing the user to log in, It's just public. We don't have any forcing for login. So that's why we are storing it in the local storage, not in the database. In that case, we are going to create that service based on the local storage. So first of all, as I know that everything or every local storage need initialization. We need to initialize our local storage with their cart, like empty cart items. So we can use init, local storage. We can make a method which is in its local storage. And then we say like constant, we can give initial cart, like we can call it initial cart. And this initial card will have, will be like object, which contains two things, or one thing which is called items. And those items will be the items which I want to locate as usual as we saw previously, product ID and the quantity. So for now the items or the NHL card, the beginning will be totally empty. And here we will say local storage in general, because this is JavaScript. Now we are writing, we say set item and then I set the item in that way, I say guard, or we can say like normal cart, which will be the k, The key here we have here c0. And then we put the value, and the value will be initial card. Okay, nice. We are getting an error here because is not assignable to parameter of string, because we cannot assign objects to be a string inside set item. Item would require this to be a string. So how we can do that, as you see here, that we are storing the data, okay? Array of objects and all of this data. We can change them to string by using JSON stringify. So this is like a method which is called JSON stringify. It will change for me this object to string and store it in the local storage as a string. So we can do that easily. So it's like we have a ray which is or string JSON, and we are storing the data inside it. So we can say constant, again, another constant. We can say initial card, same, but it will not be initial cart as object, it will be JSON. And this guard will have, will use this class or this library, which is internally in JavaScript. And we say JSON dot stringify. So make this object as a string and then store it in the initial guard here. So after we save that, we see that, okay, everything is fine. We don't get any error. But the question here, who is going to call this function? Like we need to call it Only the first time when I entered to my shop. Like I want here, go the customer that he is going to enter to my shop. But I need somehow to initialize a car to an empty item. So I need to initialize his card with empty items at the beginning for a new visitor who came at the beginning to my shop for first-time. So we need to call it like first time and only one time. Not only like every time I go to one page, I need to call initialize, initialize. Otherwise it will affect the performance. So it's better to call it somehow, sometime one time. So you have one of two options. So if you know that we have modules and we are going to use the order module in the application module here. So let's call the orders module in the application module of energy shop. So I will go to a shop and then app module here, which is like the root component we can say, or the route module. It's the beginning of my application, the main container. So I say here add module and then I call okay, or the module. So the order is module will be imported from organization name and order is, it's depend on the library how we specified the name there. So now the orders module, which is this one, is called in my application module. Let's save that here. And now we check. So we need to know that when this is called, then you can initialize the cart. So this will be called for one time only, only with a first time where I am going to use the ordered module. So in that case, you need to be sure that all those module is really called Only one time. In orders module, I can define a constructor. And when this is gold or this orders module is created, I can call the order or Carter service. So we can say cart service inside the module you see like you can also use the services inside the module constructor. So, and then I say cart service dot initialize card local storage. So as you see here we have here this method. And I am going to call in the constructor of our module the method which is called initialized cart local storage. So when we save, then my application will be reloaded and it will call the orders module. That is, module will be constructed like at the beginning because it's a class. So every class, when you call it internally, Angular is calling this orders module and create a new object of it. And then it will call automatically the constructor. The constructor has this method which is inside the card service. So when we go to our application and refresh, we will see that the cart is created. So let's remove this token again or like this local storage or all of it. So we go to, for example, to homepage. So now we have nothing because I deleted it because he had its proof that I am not calling the orders module multiple types. So when I reload the page, like when I am calling my application for first-time, then the cart item will be created with its value in their local storage. So here we guarantee that we are using or creating the card only one time. And it's not created multiple times when I navigate inside my application. But also sometimes maybe you would use orders module in other places like you are going to use it. For example, in your application, you have pages or for example, you have another module and you are going to use orders module because you need some components from there, as we saw previously. And in this case, it will make a problem for you that this will be called multiple times. So in that case, it's better to call it and find some place where is called or things can be called only one time. For example, I suggest for you, the header, as you remember to the header in my application is called Only one time. So we have here in the app more component, we have ND Shoppe header. And this energy Shoppe header is called Only one time. So to prove that, I will show you like I will have here console log. For example, in the header we can say. And then we will see that every time I navigate inside my application, I will see that, okay, any header is called Only one time. You see it's called Only the time where I have defined the header because it's on the root of my application in their main app component. So it would be called only one time, regardless that out or the partners which I am visiting. This is one way, another way which I showed you that you can use a constructor of Arthur's module if you aren't sure that you are not going to use order module multiple times. So here we have the initialization of their cart. Now we are going to fill this guard and see how we can set items to this cart. How we will see in the next lecture. 155. Add Products To Cart: Welcome back. We are going now to add items to the cart. So if I click on this button, Add to Cart, I'm going to add this product with its id and how many or quantity to the items array, which is defined in the local storage in their cart. So for that, we need to add a new method which is also added to the cart service. I call it set guard item and it will be accepting a cart item as we will define later. And this cart item will be a model and it will return for me the card I like always to give typings for everything which I am using, like string, number or even I create my own type. So for that I am going to create the cart and the cart item. So we go simply to the models we have here or the item or we can as well defined cart. And as you see here, we define it as a class, so we can say export class. And this class will be named as cart at the beginning, and it will have items, and those items will be type of guard item and array of Garth item. So in this case, I need to define as well this class, I will say class Garth item. And this Garth item will have first the product itself. Or we can say product ID, which will be more simpler. So we can give it this name and it will be a string. And then we can define the quantity. So the quantity of this product inside the car. So it will be a number. So for that, It's better always to give those items as optional. So when you create a new object of this class, it will not give you error where you don't pass, for example, quantity. So in the same file, I have two types, cart and Garth item. I am going to use these types here. So we just press control space and we import the cart item and also contour space or dot, it will give me the cart itself. So now when I set a cart item, I want to return the cart itself. So first of all, we need to add item to the cart in the local storage. Let's do that. So first of all, I can say I can get the current guard which is inside the local storage because I am going to use those items and add to them more items. So first of all, I need to get the current card. So what what guard I have currently in the local storage maybe because I have previously added some items, so I need to get the current guard. And then I push to the items of this guard, the new product. So we can do that easily. So first of all, we can get that guard const card, and this card will be type of guard. And then we can say local storage, dot get or get item. Exactly. And now we are defining or getting the queue which we set here. So I want to get this guard. So if you see that when you multiple times use this constant is better to define it on the top here. So you can say export, and we can call it like Guard, item or card key. We can say like this. And it's better that constant can be capital letter. We sank and say guard and key. And this cart and key will be in the way named as cart. So in that way, we are defining this constant and which we are going to use in all our class here or in all our service. So in this case it's better to have this card key and steed of this one and instead of this one. So in that case you will not have hard-coded string, which is not beautiful. So it's like I got all the cart and like this items. And inside I going to have here push like the guard item to the cart. So we can do that easily. So first all, we need to get the card as well. If you remember, we put it as a JSON or string of JSON. So we need to return it back to be as an object. So in that case, we are not enough to do that. It's not enough because this will return for me a string and this will give me an error because it's here saying card will be as a string, but it's has a card. So we are returning a string and we are defining that this card has type card, which is wrong so far that it's better to parse this JSON. So I would say JSON dot Parts. Here we are returning from string to object, so we don't have to stringify it because when we set item in that Garth, we stringify it. But when we want to get item from the local storage, we are going to have parse it as from string to JSON. So in that case I have it as an object and then I can access items or all class members inside this JSON. So here I just go and ISA card dot items that would push. So I am pushing a new item to the cart and I give it cart item. So here we have our cart item defined and pushed to their cart items. But it's giving me an error because I didn't return the card. Again. I want to return the updated guard. So we can say here, return the cart which is updated with a new item here. So first of all, we need to call this method how we can call it. As we said, that we are going to click on this button and add this item to the cart here. So how we can do that, we can go to our product item if you remember this component we have defined previously, so we can search for it and we say product item. And here it is. So we can say product item component. And if you remember inside this product item component, we have button. So we can say this button onclick. And we can say Add product to cart. So here, in that case, we can add this product to the cart. So we need to define as well this method. So we go to that TypeScript of this product item and we say that ad product to cart will be calling the cart service. So we need as well to call the cart service. I will say private guard service. And this service will be imported from cart service. But as you see here, it comes as the full path. We need something like a shortcut, like we need to say, like add. And then I put organization name and I would say which library I have created the service, but it's still giving me error because we didn't export the orders or the cart service in the ordered his library. So we go to the index file here. So I click on the index file inside or the library. And I say export for me as well, not or their service, but as well the guards service. So we can have here cart service. So in here, when I go to the product item, I will not have issue when I am importing that guard service because it will be defined. So now we've, when we use this guard service, if I go here and use that card service inside my product, I will not have any issue here. I am still getting error because it should be or there's not order. And now we go to our method, again, add product to cart. And then we say this dot product or service. And then we will have set guard item. But here we need a cart item. How we can create a cart item? We can create an object, we can say const, and then we call it Garth item. And this item will have a type of guard item, but this guard item also I think is not exported. So we need as well to go to our index file. And in order to library. And then I say export, start from not surfaces, but we need models. We need to import or export a new model, which will be the GARCH model which we have created. So in this case, product item, products library can see this cart item. So we can pass it here and delete this line. So in that case here my cart item will be defined. I need to create a new guard item. So then you've got item will be product ID. And this product ID will be this dot-product dot ID because I have here input product, if you remember, we were passing the product or tally to this product item and then I am getting it back. And so I can get all the details of the product, including the ID and then quantity. So we are in the product item, so the user, when he click one time on the product or Add to Cart button in product item, we are going to add only one to the cart. And then we pass this guard item two. Safeguard item, and we are all fine. So let's save all everything and reload the application. I hope we will not get any errors. Okay, here we go. So now I have here the product item, if you remember, we used the product item in feature products and also we used it as well in products list. So I'm going to add this to cart. So when I click here, I see that the cart here is not getting updated. Why? Because as well in the service, when you go to their cart service, you are not enough to push items here. You need as well to push them back again to the local storage. In that case, you need again to stringify everything, like you have to do this lines again. So after pushing this card, you can say like initial guard JSON or you can say guard JSON. And this will be stringify this guard after we pushing this item to it. And then we are going to push this guard JSON using this guard key to their local storage. So let's do that. Of course we are going to refactor this method. I'm just showing you the steps, how we can do that. So I go again to the application and then Add to Cart. I see the item is added here. Click again, I see that the item is added. I click at IC, I have now three items. So let's do some refactoring. So let's first put this in a new method. Like all of these like JSON bars, localStorage, get item like the cart itself. Let's put it in a method we can call it get guard. So we can say get cart like in general. And this will return for me the cart itself, like cart as object, not guard as for example, that JSON data. So first of all, we can say, give me the like and that way I would say card JSON.parse, but we can say in that way, like I want to make it more detailed, just you can understand it. So of course you can keep it like how we did it before, but I want to detail, so we can say here guard JSON data, or we can call it car JSON string because we need to stringify this one. And then I define constant, I call it again card. And this card, it will be also from type of guard. So here it will not be card, it will be string. So we get the item from the local storage. It will return for me the string which is in the local storage with that key. And then I get it. And then I will say here, JSON dot parts, and then guard JSON string. And here I will have the cart data as well. And at the end I will say return for me this guard as object. So here we don't have to bother ourselves. We just say here, just give me a constant will be Guard. And this cart will have this dot get card. So that's simple. We saved all of those lines because we are going to use as well get Garth multiple times in other methods as we will see later. So after that, push items and then guard JSON stringify again. And then I set the item inside the local storage and I return the guard again. Okay, after that, let's go again to our application and check if everything is working fine. Okay. We are adding items to their cart. Okay. But with adding, we have an issue that you if you see that when I am clicking on this Add to cart item, it's adding the product again and again and again. I will have product id and it's added multiple times. We need to just when I click on Add to Cart. And if this product already in their cart, then I need to add the quantity, increase the quantity only, not add a new product item. Otherwise, our guard will have problems that it will duplicate the product itself. So we need to check if the product ID or the product exist already in their cart. Just increase the quantity and don't do any addition to this array of items so far that we need to check if the product is inside or inside the card already. So I am getting the card, then I can create a constant, we can create, call it a guard. Item exists. We can say Garth item exists, this cart item exist. We'll iterate through the cart items and check if there is Garth item passed already in this cart. So we can say card to find or solid dot items first, dot find because we have it as an array. And I am going to check if there is product item or product ID similar to cart item which is passed here, then the cart item exists. So I will say find. And then item, you know that we can use this fine in that way. And we can specify a Boolean or like a Boolean return value, which will define for me this item exists or not. So for every item inside this array, check the ID. If it's exactly the same of guard item which I am clicking on or adding to their cart, then return it for me. In cart item exists. So here I will check if there is Garth item exists. Then increase the quantity else, push the new current item to the guard, and then return that guard again back. So this how we are going to do it. So we are going to increase the quantity for the product which we call which we found or the item which we found. So far that if I have multiple products, I need to find one. Like go through all the array, all the item, and check when I find one, then increase the quantity of it. So the best way to loop over those items is using the map. So when I go here and I say carte items again, and then dot map. And then we can say here guard item or like item, just like this. And this item, it will be checking it. So if item is equal to, sorry, item dot product, it's exactly how we found the Garth item. So I will say here, if item that product ID is equal to Garth item, which I am passing in this set here, guard item dot product ID. Then we need to have this item, that quantity increased. So we just say item.quantity equal to item that quantity which we had before like previously, plus the quantity which is passed with the Garth item. So I will say here cart item dot quantity. So after that we save and we check if we are really increasing the quantity. So here my guard is initialized again. I click OK, I add, you see, we have increasing the quantity based on their guard item if it exists or not. So when I click on another product, okay, I have here only one product. When I click on another one, it will not find that product, so it will add a new item, as you see here. When I click again, we will see that this item increase the quantity. Third product. We have here, three products. Again, it will increase its quantity. So we have only one product, but the quantity is different based on that clicks. It's better always in some cases, inside the mapping, you return the updated item. So you just say here again that return for me the item. Of course we are using the array references, but it's better as well to return the item to the map so items can be updated like in a nice way. So after we save, let's try that again. We have initialized, again our cart item. I click OK. I am increasing the quantity and I add a new product with the new quantity. I clicked here again. And I see that we have as well that quantity. Of course, as a homework for you, I will add it to the next section. When I want to add to their cards on item, I want you to show a boat up to the user that he can, that the guard item is added because when he can take sometimes and it's not good user experience like we cannot see what happened. Like, of course, the user will not see this console log, but you will just click, but he doesn't see anything if their cart item is added or not. Of course later we are going to update this chart here to show that, okay, this, there is a new cart item added here, but it's better as well to add some confirmation dialog or confirming that this cart or this item is added to the cart successfully. So this is our set guard item method. It's simple, we have defined and get Guard also. So we are going to use this get cart item. As you see here, that when we reload the application, we are initializing the local storage again. So we are not getting any benefit from the local storage because it's if, if the customer or the user leave the website and go back, he will lose his cart item. So we need to keep them in their local store it somehow. And this will be what we will see in the next lecture, step-by-step. 156. Restore Shopping Cart on Reload: Okay, so as you see here, when we are reloading the application again, we are losing the cart items. So when I add some cart two items to their cart story, then you will reload the application again and we are losing the items and the items getting initialized again. So in this case, we need somehow to get the benefit of local storage because we said that the customer is leaving the website and coming back again, we want to keep his cart full, so how we can do that? So first of all, I would like to go to my initializing of cart local storage. Then before initializing the Garth, we can check out if there are guards in the local storage or not. So we can define cone's too, which is called cart. And this costs or will be type of guard. And then we can say this dot get guard, the method which defined in the previous lecture. So here I see if I have a cart or not. So if there is a cart or if there is no card, we can then create initialization of the cart. And then we can use initial card to add it to our local storage. So we can then use all of this part of the code here. There is no card initialized previously. So actually we are just initializing the cart. Otherwise, don't do anything else because if we are having the cart already, then we are not going to initialize it. Again. We are just calling this part only. We don't have guard which is coming from the card itself, which is from the local storage. So let's save that and grids try here. And we will see that when we reload the application after adding some items to their cart, we will still have them. So here for example, I have two items, quantity 2 and 1. I'm going to reload the application. So my code is checking if there is a card in the local storage or no, if there is no local storage card, then initialize one. Otherwise, keep it. Don't do anything, don't initialize anything again. So in that way, we are getting the benefit of getting back to the website after adding some items to their cart. So the user will be able to see his cart again when he doesn't have time to buy now. So he can return to the website anytime again, and then he can't see his card is still filled. There. 157. Observe Cart Count Badge in The Header: Okay, now in this lecture we are going to observe the cart. So here, when the user is adding something to their cart, then we are going to add here some bad to show how many items in their cart we have here. So first of all, I would like to create a component for this. So we can then use how many cart items we have here. So let's do it step-by-step. First, let's go to the header of our application. As you remember, we have created this icon in the header, so we have shared header and in the header as you remember, we have placed their shopping cart icon. Instead of that, I am going to use a component which can call it like for example, orders and orders. We can give it shopping, or we can say just guard. And I can, for example, just like that. So let's define these components in order library. So we can see an egg's generate and then I want to generate a component. And this component will be placed in the project which is called orders. And here we can say that in the components, we define cart icon or cart bad. Who can say it's up to you. So we can have here the Garth icon, which will be in the header. And then we do all of the staff which we are doing always I don't want inline style, I don't want as well tests. So we can use a selector as well, which we defined previously. We can say cart and then icon. And here we can skip tests. And then we run that component. We made this comment a lot of times. So we don't have to explain it anytime anymore. So we have now here the component which is created, which is cart icon. And inside this cart icon, I am going to place my shopping cart icon, which I have defined in the header. And then we need as well to save everything and check if our component is really working fine. So because I didn't check the export, we have it all of this. I see that I am still getting the error here or there's cart item isn't unknown. Yeah. Okay. I have here typos, so let's save that. I'm sure we will have now the icon perfect. Now this is not icon, plane icon. It's a component which we called in the header of our application here. So let's use this component to observe that current card. First of all, I want to display here how long or how much guard we have here. So first of all, on initialization of this component, we can use also the card service. So I will say private and then guard service, which we have defined already in our orders module. So we can say cart service and the guards errors or in Orangi on Edit, we can say this guard service and then we can say get cart, as you see here. So we can get the current card which is loaded to our application. So first of all, we need to define a variable which is called, for example, we can say card count. And this card count maybe has a number. And this number maybe it can be initialized as 0. So we can say count will be initialized as 0. And then we can say that after getting this guard, because this cart will return as a card. So we can say this card count. I want you to show you how everything can be in one line after getting the cart, we can say that items because this will return for me guard. And then I say lengths. So this pushcart count will be length of the items which are inside this guard. So let's save that and we go to the template and display this shopping cart or this number near that icon so we can stay small, dag. And we define like we can say guard count. So without styling, just to see how we are having the card count in the header of that component. So we reload the application. So sometimes after you don't see this changes, you just need to save maybe the header again, then you will see those changes. So as you see here, we have three items because in our local storage, we added three products. Okay, that now we have the number of the icons or, or items which are in our cards. Every time I reload the application, I will have the items or how many items in their cart I have here. So first of all, we need as well to style it. So let's make it like as a badge to be some red icon here. It will show that we have here three items. So to do that, prime end also providing you with something called badge. You can also directly use the icon with this badge, or otherwise you can use only the badge and place it somehow and dilate in your way. So let's use the basic one. I will going to use these numbers. So I'm going to use this one. So if we go to their sources, we will see that this one, which is called Danger, so this will have three and then it will have current color, which is called danger. So what we need first to import the module, which is called badge module. But in this case, in the place where we created their component, or in the place where we are going to call this badge. So in our case it will be in orders module. So in orders module, I'm going to import that. So we have here import badge module. And the badge module will be in the imports array of that module. We save and we go again to our cart icon. We get the template of this red badge. So we go here, we say P badge. And instead of this small what we have defined here, we just place it and the guard count would be as d dt of this theory, the hard-coded number. So we can say Garth count will be the value of that badge. And we remove the old one which we have, and we reload the application and see if we have the batch, nice, we have it here on as well. Do you have another option to use a one which is coming also with icon? So you can use this one. So we can as well go here and see in the sources, for example, we have positioned badge and it will be the one. We can take, the middle one, for example. Okay, copy all of this part. And then we remove all of this because it's coming by default with icon. So we have here the like, it's put back or the area. So now we have their color and the count or the value of this item or cart item will be card count, which we have defined previously. And we have some font size, we have some styling. And here is teeth of the icon PI calendar. We are going to use that icon, which is called shopping cart. So after we save that, go again to our application in the front end. We will see that we have the shopping cart here. Okay, It seems big, but yeah, we can, you can style it as you want. You can give a smaller font here as you see, because he specified some font size in the style of this eye so we can make it smaller like 1.5. It will be like more clear and nicer and seen to the users all of them. Here we have the guard item which is updated with the current number of my cart items in my local storage. So maybe in that case, let's also style this icon so they can be the same, we can give it same property, so we can give the same coloring, like we have here, a class P texts secondary. So we can go to our header component again, and we can give this styling to this class, to the user icon. So to not have different styles everywhere. And as well, we need to give the style of color are size, font size of the icon. So it can be as well the same we can give here Style and go to header component. And then we say here, font size will be 1.5 gram. Of course, this also will be a component in the future when we are going to see the orders of the user, when we are clicking on this icon. So we are going to replace as this always as well with the component like how we did with the orders cart icon. So let's save everything now and check if we have that I'd styling, we don't have any issue. Nice. We have now the cart and the user icons looks the same. But now I have an issue like when I want to add item to this guard, for example, let's add this one. I see that it's not getting updated. So only when I refresh. Okay. I see that the item is added to my cart. So we need somehow to observe, like make this sum variable and this variable is observing their local storage, is watching the local storage is watching my cart items always. So when Ellie change happen in the application regarding their cart, then this will feel the change and then it will report and show it to me here. So we are going to use for that the observables. So to understand observer will more, you will see it here. So we are going to make some variable in their service which is called subject, and this subject is observable. So we can subscribe to this observable like I can, this, this variable guard count. When is we'll watch always that card like the cart is always updating. So every time I click somewhere to add to cart, remove some cards, then this will listen to that and say, okay, I am updating, I got some update. Let's do that. So step-by-step, let's do the observable. How we can do a public observable. Public observable for me, I can do it inside the card service. So we can define an observable simply by calling something called subject. If you remember, we used the subject as well in any shell or ending the subscription as you saw previously. So we can use a subject as well here. But instead of that, we were saying like that, we can define guard and this cart, as I told you, always, observables are suffix with this dollar sign. And we can't say that this card has a type or subject and the subject will have a type we previously put any, if you remember, when we were ending subscriptions. But now we are going to say that this subject will contain the cart. And this subject, we are making a new subject. We initialize it that quickly. We create object. Okay, So in that case, when I go to my component here, like for example, let's say cart icon, then I'm not going to use get Guard only. Get guard is only returning for me that current guard when I load the application. No, I want somehow to observe it. So we can say as well here, this dot card service. So we have here define their cart service and then the cart, this item or this variable which I defined. And then I say subscribe. So I am going to subscribe to this card, which will return for me the cart itself. And then the card itself. I can get the length and assign it to their cart count. So we can't say here this top card count will be the guard. This one would be cart. Good items dot length. So in that case, we will have the cart always observed. So every change happen to their cart will be observed by their cart count. Okay, Now, let's remove this line. So now if I go to the application, I am getting here 0, okay, I want to add something to their cart. It's still not observed. So a state of change, like here we are saying that the change is not felt like this item or this card local storage item is doesn't feeling the changes. And also we cannot observe that as well. So we need to say to this subject that update yourself. So everybody who is subscribing to you can feel this change. So how we can do that? If we go to the guard service. At the end of this method, I will say after I initialize everything, I, before I say return the car, I can't say this dot card, the subject which I have created. And then next. Then instead of returning the card, I can say also next, update the cart. So in that case, everybody who is adding, when I add something to their cart, everybody who is subscribing to this valuable, he will feel the change because then this updated himself and with the newest guard after I add items to it. And then everybody who subscribe to it, he will say, okay, that is an update. I'm going to get that update and show it to the user. So for that, I want to show you a console log. So you see that this console log will be executed every time I have, for example, some update on the cart which is adding items to their cart. So let's save that and go to our application. Again. It will be reloaded. Okay, now we have still the Euro because we didn't initialize that subscription or subscriber. So I'm going to add some items to their product. So for example, I'm going to add this one. When I click, I see that this has a 5 because it got updated. The cart which we have or the observable which we have defined there. And this observable. Always observing, or this item is always observing what we are doing to their cart. So glucose, I have here like the console log which I showed you. So when I click on Add to cart, the icon here on the top will feel the change and console. So here we can say, for example, click, I see you look, that is items that the guard got updated. And because of this next, which we have here, then the guard observable or guards object, will update Intel and say to everybody to who is subscribing to it, like in our case, this cart icon that okay, I am updated. Please update yourself and do the code what you were doing inside the subscription. So in that case, I am consoling log and updating the guard count, which is I defined here. And I used it in the value of this badge, so I see the number here. But now when I reload the application, I still get 0 and not getting that the current or the previous count of my guard where I have previously in my local storage because Europe that ocher storage is okay, everything is fine. We have five items, but we cannot see the update here. Because also when we initialize the full example that guard, if you remember, we were saying if there is no card, then okay, update or create a new guard in that storage. Otherwise, if there is no card, then we can say here as well, this took guard subject will be or that next updated with the current card which you've got here. So for example, I can say this one. So in that case, I can say else, if there is cart then updated for me with the current card. So when there is no card, initialize a new card and add it to the local storage. Otherwise, just update that gerunds subject, which I am observing with the guard which you found in the local storage. So let's save that and go to the application again. You will see that this is not working again. So this is because we are using subject. It's better as well to use something is similar to subject, but it's called behavior subject. You can, instead of that, you can use behavior subject. So it's doing exactly the same. But we, cause we are going, we are calling this in the instructor of the module constructor of the module, then this will be not ready. The subject is not ready yet, so it will not be executed and it will not get the next. So this is getting executed and finished before this subject is getting initialized. So it's better to use for that behavior subject. We have your subject, It's exactly the same. The difference here that you need to say behaviors object must be initialized with something like within your cart. So we can't just say simply here, this dot get cart. So I get their cart which is in the local storage, and then I create my behavior subject. And in this case, we don't need this else anymore. So after that, we have the cart initialized with the current guard, which is stored in the local storage. So in this way, I will get here five every time I reload my application. So now when I am adding a new product to my local storage, I will have, for example, this one. We can have Add to Cart and we get here, six gets increasing and observing that count. And when I reload the application, I still have six here. Okay, Let's try to remove all the cart which is in the local storage. So totally and see for the user who is coming for the first time to our shop. So I'm going to delete selected. I deleted the guard. Now I am going to homepage again and I am new customer coming to the shop. I want to open the console. I want to see if I am getting some error. So we reload the application. So I say here, reload. First, I get error. Cannot read property items of null where I get this error in cart icon component. Okay, we need to go to this component because we saw that this items is not defined because the guard is not initialized yet. So let's remove this console log. And then we say if the card has item or that guard which I got is defined, then give me the length of it. So in that case, we have this question mark. Otherwise, in TypeScript you can say to question mark when this undefined. Then guard Count, give it as 0. So it's like if else, so Guard count will be this one. But when this one is undefined because of this question mark, to avoid the error in the console as we saw previously, then return as 0. So we save that again, reload the application. We don't have anything now in their guard, so okay, we don't have the error, but to test it more, we need to remove, again, reload the application, go to their console. Nice, we don't have any error. Now I am going to add item to this Karp. I click lies, I have 123. Yeah, As you see. So when I click or another product, I see that it's not added because I'm getting only the items count. So they're repeated product will not be counted here. So we have only the different products. And we will see when we go to the guard detail, we will see how many items we got and how many times the user click on Add to Cart for you in the next lecture as a homework, I want you to add a pop up as you will see, and I explain it in the homework. So when I click on Add to cart and everything is success, I want you to show a pop up like the item is added successfully to their cart. So in this case, the user will not click many times and he doesn't know that. He, okay, it's added to the local storage everything because right. But we are not having any notification for the user, which is not nice experience. As a last question, do we need to end the subscriptions here? No, we don't need that because we are always subscribing to their cart. We don't need to have n subscription because I am not leaving first. And this component, this header is always exist. This component always created only for one time and it's not getting created multiple times. So I'm not creating multicolor of multiple subscriptions. But here we have just one time and it's all the time, all the time when I am visiting or browsing in my application, I have this item subscribed and it's observing the cart always. So in that case, as a summary, we have created in their cart service something called behavior subject, which is observable and this observable will be observed and not defy all the people or all the items or their components who are subscribing to this behavior to about its changes. So when I say card dot next, for example, in this case here we have one of them. Here we have dot next. Then I am updating this behavior subject. So cart icon will listen to this change and execute the code which it will be inside the subscription based on their guard which is returned from that behavior subject. So this is the easiest way to observe the things in my application. Otherwise, we can use NG RX, which is more complicated. And for that, I don't see it like a warmth to use MDR x or which is state management only for this simple case, which we have only four that card. I'm going, of course at the end of this section, explain how to add into RX state store using NX schematics. And as well we are going to implement that cart as in the state store, not as we have here with observables. And you have optional if you want to follow the MDR x way, or you can follow this simple and nice way here. 158. Add Product To Cart With Quantity: All right, now we are going in this lecture to add product to the cart, but with the quantity, if you remember, we were adding here only one item of this product. So now we are going to the product detail and we are going to select Quantity. And then I will click on Add to Cart. It's exactly the same how we did with product item component. We are going to do with product detail component. So first of all, I am going to have that product item here. If you remember, we were using the cart service as well. And in the cart service we were using ad product to the cart. So the main difference here, we are going to use the in the pages, product page. We have to use this quantity which we are getting from the quantity input or the input number and then place it or pass it when we are creating the product item. So in product page component, I will go to the TypeScript file and then I am going to have the product or service again. And then we are going to use this cart service when I am going to add product to the cart. So first of all, we can get that quantity. So we have defined previously the variable which is called quantity. So for like making some prefix, we can initialize this item with one and min can be one to 100, do not have 0. And also we can initialize it quantity with number one. So we can say here instead of number, you can say as well, this can be one. But of course he ESL and complain when you define the type and then the value, because the value is one. So it's known that it's a number. So automatically, TypeScript will say that this is a number. So we say that this quantity initialized and then we go and save everything. We try that out after we update our application. So we see that it's not initialized. I think I have a dipole, yeah, okay, we need to have here equal, not typing. So we can have here quantity is equal to one. And as we see that it's initialized with one and I cannot go to 0. Now when I click Add to Cart, I need to add this item to the cart. So first of all, I can fires to call the guard service exactly how we did with that item or in the product item which we had defined previously. So first of all, I will have creating of cart item. So I would say const cart item. And this Garth item will be type of cart item. And it will equal to like the item itself, which will be product ID, will be the product ID where I am now. So if you remember, we have here the product which getting, so we can't say after that we get this dot-product because we haven't defined here. And we filled our variable or class member with the product which we got from the back end here. So we can say that this dot product dot ID. So I am feeling that product ID of Garth item would be this dot product dot ID and a quantity will be this dot quantity. So as a quantity will be changed based on my changes here because I am using the NG model, which will have two-way binding. And it will reflect that always or reflect always the page or input number, which I am changing here from the user. And then it will put that in the variable which is called quantity. And I defined it here as a member class as you see here. So now we go again and we add this cart item to our cart. So I will say this though, guard service, dot, add or set cut item. And then I pass the cart item, which I want. So when we save that and we try that in our application, so I will save here, and I would choose five or six and then add to cart. And then this item will be added to my cart. So let's check if we have it like really in our local storage. So we have here two items. I see here that it's not added. So maybe this button is not working. So let's go again back to our application and check. Okay, we have here button. We don't have a PI button, so we can use only Glick, like we are not going to use the onclick which is coming only with PI button from Prime NG know we are having a button. So the, even further the button to fire that this event we can use only click, but when you use the prime energy in the documentation they said you have to use onclick. So in that case, we have only button. We are going to change it to click. So let's save and go again to our application. And then we check that. So we select four. We added, okay, card updated. We have now the item which has quantity five, like because we have it previously in the cart. 159. Cart Page: Okay, in this lecture we are going to template that guard page, that current page. It's going to have all the cart items where I am going to submit for order and then I can review my cart and ICU what I ordered. And I can always change the quantity, how much or how many items I have ordered. And of course we will list like something like my cart has three item and we have some button like to go back to the shop again and as well some information. And also we are going to implement deleting an item from the card. So first of all, we are going to do this template which I am showing you here. So first, we are going to create a component which is called guard page, and it will be in Orders page. So I will go to an ECS console and then click Generate and then component. And then I will have here the pages in the pages inside the orders library. So I will have here pages and then cart page. And then we are going to select the project which will be orders, because we need to do that in the orders library. And the same thing for other components. So we have a lifestyle. We have as well, skipping the test. So here we have all of this and also the selector can be orders and cart page. So in this case we will have a component created. We just need now to refer this component to their routes. So if you remember how we have created routes in the app module. So we have here in the app module of energy shop, we have created some routes and we have only the main route. But in products module, we are defining also the child modules. We will do the same how we did exactly with the order module or how we did that in the products. So let's do that. So first I will go to the orders library. Let's close everything and go again to the lips. And of course we have imported already the order is module in our application module, so we will not have any issue. So we close all and we move to our libraries and we have here orders. And I am going to implement the routes in orders module. So we define a constant which is called routes. And it will have a type of routes. So we have here routes and it will have type of route and the route we are importing it from Angular. And this will be array, and this array will be array objects, and the objects will be Bath. And for example, I can define the first path, which can be cart. And the component of this path will be the component which I have created, which is guard page component. So now we are ready for that and we just go to routes again or to router module. And say that for child as we did exactly with the products and then I pass the routes which I have created. So now we have to check if everything is working fine. I go to my application, I'm showing this one. If you see that it's indifferent port, I have demo, I prepared it already, so to show you what we are going to do and then we implement that easily. So first of all, I want when I click on this icon, I go to their cart page. So we have created the component for the cart icon and we just need to add something which is called router, router link. And it's router link will take me to the cart page. That simple. So we just save, go again to the application and reloaded and we click on that card. I have here a mistake, I need to remove it. And then we go back to their cart again or to the page again. And we will see that we are able to go to the cart page works. So this what we are going to template. So we go to the component which is called cart page. And in the cart page as well as every component, we define it first with cart page or the name of the component. And then we say div p grid, and we are going to use the grid here as well. And as you see, we have in the template that we have here eight columns, because here I am going to put the summary of the orders like the total price and if there are taxes and ships or something like that. So first of all, we can have the grid and it will have eight columns. So I will put div call and, or, sorry P call. And 8 first div will have like a button and we can give it like this. And this will have a PI button, so we can use the button as well. So the button, I can take it from Prime energy. So we can use exactly the same button how we did previously many times. I don't have to repeat it. So the only thing missing here is that I need to import the module again of the button. So we just need to have here button module. So we have to add button module, which is coming from Prime energy as well. Title. So in the title we will have something like my card so we can create another div. And this div will have as well H4 and H4. I will have a text which is called my cart. And then like I can put the information, for example, we can say card count. So we can put here like the count of the cart, how we are going to take it as well. We did that already with navigation, but we can do it again here to fix the information. So we have here H4 and as well we can add after that some sentence like how we have here like shipping after payment, delivery time, yeah, something like that. So we can as well add this inflammation. So I will add another div. And inside this div, I can give it a class as well. And this glass, we can give it a guard shipping, for example, info, so we can color it. And then we can put the text here. So of course, this text can be dynamic based on the shipping methods if you implement that in the back-end. So let's save and style this part. I'm sure it will not work directly. We need to do some styling. So first we need to have a bag to show button. So we just all we can remove this button or we can let it like this. So we can have another method for it here in the component script. So we can have back to shop. And then inside that we are going to have the button where it would take me back to the shop. So I need in the constructor, I need to call the router. So I would say here private router. And then we need a router. And inside this router, we are going to have ordered the back button. We will say this router dot navigate. And then we specify the navigation which will be products. So I will put or I will return to the page which is called products in that way. And we will see that we got base into our page. So if I go to click back to like shop, then I will go back to the shop as I was, who you are as I showed you with that outer and here we have my card, this number, we are going to replace it with the current card. Items count. And here, shipping we are going to style it. So we just need to add this class somehow. So first of all, I need to define a class or a file or style file, which will be based in the lips exactly in the library where we have created. So it would not give any conflicts or it will not confuse us to see where it is. So I will give this card that CSS, I create a new file and this file, I am going to import it in the orders. So here we have to say Import, not URL, but only import that link which we want to import, which is card dot SCSS. So after that we have to be sure that is also orders is important in any shop. We have to check that, okay. It's imported, so we are working fine here. So as you saw previously, we have created a class which is called guard page, like we can say cart page. And these cards page we can give it, for example, the mean height. Like to give some minimum height for the cart here. So we can have here some empty space to let us work fine. And of course I am going to implement later when we don't have any element in their cart. So we can show like your cart is empty. So we have to implement that as well. And after that we are going to have that cart item or we had we said that we need to create the Garth item. So we can say dot card. And inside this dot cards, we can have that shipping, sorry, shipping. And we can give to this shipping like color green. And we can push the context under a little bit with 15 pixel or we can give like no need for that. We can just push it using the classes which are ready in our prime end. So we can say like here, B or margin bottom, which will be like we can take five. And as well we can do that for every div we have created. So to give some spaces between all of those leaves to not be stuck to each other. And we save everything. And then we are ready with the first lines. Let's dial now the guard item, which is this one. So the cart item will be also inside a div. So we have here something like div and we can give it a name which is called cart item. And inside this guard item, we are going to have another grid because I want to have like division of the grid. So we can have here two columns for the image. Example 9 column for the inflammation and the name, and also three columns for the button here. So of course you can't, you know how, you have to know that when I am creating grid inside a here, so inside eight columns, then I have also here again a 12 columns. So it will be related to the parent. So I am inside what? I'm inside P call eight. I'm not inside the like all width of the page because here if you want to see we have b, sorry, recall. And then we can say 12 minus 8 is 4. And here we are going to put order summary, we can call it. So here in that area, in this space, I am going to put the order summary. So far, the templating of the cart item, as we said, we create a new grid. We can give a grid. And inside these be great weekend, another live for column which will contain the image. So we can say P call tool and it inside it we will have cart item image. So we can say directly image will have the source. I can't pick up any image from Google. I copied some image. I am going to post it here. But of course we are going to change that as well. So we can't say this div will have a class. We can say cart, item and image. So always it's better to prefix like this. So we can use that benefit of SESS. So we can prefix always with a parent, I say gap item and then I pass that thing which I want the style. And after that, we need as well the column, the second column which will be near it where I will have the information of their product. So we can have be called, for example, yeah, we can give it eight or seven as well. So we can have now nine columns. So we can give the name of the product. So we can give div and it will have cart item name. So we will have cart item name, which will be like hard-coded. Now we can just hard code the things we can say Just product name. We can have as well a div and which will have cart, item and then price. And we can give also some hard-coded price and use the currency flag. So we can give currency like the pipe which we have created previously, all which we know or talk about it previously. And after them we are going to have the Delete button. So if you see that I want to delete as well the button of or delete the product from the cart. Of course, the button in prime end. There are a lot of them. One of them is only with icon, so you can have a button on me with icon. So you can use that as well. So we can create a div as well. We can give it class, which is called guard Item remove. So we have removed guard item and it will be a PI button as well, and it has some onclick on it. So we have P button and this B button will have icon trash, exactly how we got it from Private NGOs and then delete guard item. So I need to jump to the file and create the method which is called CreateCars item. We can let it empty for now. So after that we have created the first side. So let's check if we have everything is fine. So after loading the application, we see that nothing is styled. We need to style that. So let's jump now to the styling file. I'm going to have here, the styling again. So we need to style all of the items which we have created. So I hide this panel. We can also close everything which we have previously so we can be able to see what we are going to start. So first of all, we need to have the item, as you see here. We have some a white background and was border and border radius. So I will have here in the card. First, I will jump inside and say that I want item. This item will have a background color of like a wide and as well some border, which will be like a lighter gray. And we can give it as well some padding so we can push the content inside 15 pixel and we can give as well that border-radius, which I told you that we have some radios on the border. And then we can say that the image which we have defined here, so we can, that we have IR, Garth item image and inside it some image we can as well call it and give it inside this item that we have here as well, image. So the image inside it there is image tag and it will have high to 120 and max width 100%. So when the website is going to be responsive, it's better to give it like max width, which is 100. So the content of the image will not go out of the main container or their parent container to not have an issue in the styling. So we save and go to the application, okay, Now we have the items in that way. So now we need to do some styling for their name and also the price and this button, which is already here, we just need to change the color as I will show you later. So first of all, we need to style the name I will give here. Styling or a class which is called name. So as I told you, this is a benefit of having Garth and then item and then name and this what we are doing like we can give this prefix and then name as you see here. So we can get benefit of SCSS here. So font-weight of this text will be 600 and font size can be 1 to EM. So we can give it a little bit bigger size. And we can push that content under it about 15 pixel because as you see, it's sticking to each other. And for the price, we are going to give the same properties which are here, except that we are going to color it with orange or our primary color. So here the color will be the primary color, which I have defined in my SAS files. And we will see that we have the styling fine here. I will show you later how to color all the buttons with our orange color with a primary color. But first let's move on and we are going to implement, which I said before that we need to implement the, the counting or what is called quantity. And as well the subtotal, if you remember, we did that already in that card product page and we have here the product detail page that we have this quantity item, so we can use it the same how we used it from prime end. So we can copy it. And first, but you have to create another column because we have finished two columns for the image and seven columns for their content and delete button. Now we need to create another column, which are the rest. So we can say p call, and then it will have four or sorted3. So we have 12 columns in total. And inside those 12 columns in total, we are going to have that P number or the input number which we have defined in our products page. So if we go to product detail page, so you can go quickly, jumped to it. We can say product. And page, as you see here, I jumped directly to this component. And we have in this component that we call the quantity button, which is this one. So we can copy all of this. It will be exactly the same. So we need to go back to our component which is here. So we define the one which is as well here. So we don't need, for example, all of this info. We just need to have guard, for example, item and we give it quantity. So in that case we can style it and give it some class. And we have the don't need label as we see in the design so we can remove it. And p input number is not important. We need to import also. We check how we have it in brine energy. So we can have here inputs, multiple inputs. One of them is input number, so it should be this one. You can copy, okay, input number module. So we need to import this one to our orders module. The same how we did with the button and other things. So we just put here input number module. So back to our template to see if everything is working fine. Okay, we have, we don't need to use NG model. I will show you later how we can get the value of that. And the mode will be this UML, show buttons through input ID quantity, and it will have. So now we have this input number. Let's reload the page. Okay, we see like some problem here that it's going out from our module. This is, I don't want you to explain you so much this because we have to add also another class for this component which is called P Floyd, which is will be for that grid. So we need to put on the grid off guard item as well, p Floyd, so in that case, or fluid. So in this case we will have the right class fixed here because P fluid is dashed with. Templates or the form components of prime end g. And you need to use it every time you are going to use form components inside some grid. The last thing I want to have here, just adding subtotal. And how much is the subtotal of this product item subtotal, I mean, with it, like I need to know how much our whole many are Homer to this price of this product multiplied by the quantity. So in this case, I can use also the subtotal concept. So we have here also carte items, subtotal and subtotal. We have span here because I am going to give it another color, which will be green and it will be hard coded to a $100. And we can style those items or those components which we added now. So first of all, I need to style that quantity. So we have here P or the cart item quantity. So the cart item quantity class which we have created here and inside of the input number. So we can give some margins, like margin. We can say, we can give two when t, like 20 pixel or 15 pixel in general, like we can, and give it like that from up and down and from left and right, nothing we can keep it as 0. And we can as well for the subtotal, we can say sub total class, we can give font-weight, which can be 600, like a little bit bold. And also the value inside this subtotal, as I defined here, I have guard items subtotal, and then guard items subtotal and then value. So I can use that benefit of thus, and I give it a green color. Let's save everything and see if we are doing right. Nice Now we have our guard initialization is ready for the buttons which are here. We need to color them with our primary color, which is orange as well. So you can do that easily by going to the cart page and say that I want to style all buttons and give them background color as we did previously. So if you remember, we gave background color, primary colors and borders is 0. So you can put it here, or if you feel that you are using that always, you can put it on the root file on here NG shop. You can, if you remember, we added here some glasses and as well you can say just all buttons give them background color. Primary color will be like this, and border will be 0. So you can do that. All you can do in that way. So we can see the changes. And we see that all the buttons got this primary color, which we have. In the next lecture, we are going to see how to feel that data from a real product. So now we have only the product. In that case, we need to feel that the cart with real data of the products from the database which the user selected and added to his card. 160. Connect the Cart with Products: Okay, in this lecture we are going to connect the cart with products. As you see here, I have two items in my cart, but I cannot display them here. So we are going to connect this cart, which we have now the cart page with a real products which are inside it. So the best way to do that, we are going to grab the services of the product. So first of all, let's go to their cart page as we did previously. And now we are going to implement here the hard-coded data which we input here with the real data. So first of all, I am going to have like some module where I will have the cart item with its details. So at the beginning here we can start using that guard service or as we saw previously. So I will go here private guard service. And then I will import the cart service. After that. On initialization of this page, I'm going to have another method which will give me the initialization of their cart page. So on NG on it, I will use a method like we can call it, for example, get cart details for example. And then we define this card details. So again, we have here get card details and I will give it as a private Git card details. And inside that I am going to use that card service. So the cart service, I will observe the current card, which we have defined previously and we have observed, so I will say here cart. And then we get pipe, we make a pipe. And then we have to remember that to make take until like when I leave this page, I am going to destroy the subscription, so we can do that later. Now let's keep it like by play this and then subscribe. And then I would get the, for example, the response card we can call it. And in that response card, I will give, for example, like a response card items. And then I will loop over them because you remember we have created all the cart items and we will do some looping inside. So as you see here, we have for each, so for each item inside cart item, so for now I have two items and they are stored in the local storage and in my cart. So I will go here, loop over every item and get the product, and get the quantity so far that we need as well to go over the product service. So we say here like Garth item. So we will get back here every cart item and I am going to loop over them. So let's console log, like to be sure that we are doing everything is fine. So I will say here, console log for me that cart item where I am looping. So after that, the application is reloaded. We open the console again and we will see that we got two objects, one with product ID and quantity, and one with product ID and quantity. But the id, as you see, is not enough because I need the product name, the price, the image, and also this up daughter, the quantity, so many information about the product. So I need to use the product service. So for that, we can use as well that product service. But I'm sure, like you don't have to follow this because I am, I want to show you an error which we will say face now, and we will continue fixing that error in the next lecture. So here I have a product service. I used it so we can get it product or service. And it will be come from the products organization name. So we can go here and say import products service from but from where? From the products library. So we can have here blue bits and then products library. Okay, now everything is still fine. We don't have any issue. I'm going here to for every cart item, if you remember, we have Product ID to get the product. So let's do that. So I will say this dot product service, dot, sorry, the product service which we define dot get product. And then cart item, which I got here in the loop, dot product ID. Because if you remember, good product is working with good product ID as we did it in the admin panel sections. So here we have that good product and we are going, for example, to subscribe to it. And we can say product like this. Like we would get the product in their response and let's keep it empty. When I save, I will get error in the console and also in the application. I will tell you why. This is because we are having resources calls or circular dependency, which is called mentioned here. Because as we know previously that we used that guard service in products library where we used it in the admin or sorry, in the product item, as we remember here. So if I go to the product item in the library of products, we have here product's page product list, and one of them is component called product item. And if you remember, we used the card service. So this is an, a big issue for me here because that product service or product library is using the orders library. And in the same time, ordered library is using the products library. So in that way, we will have looping between orders and products. So as you see here, I used from products Library and here I used in the, in the products I used from orders library. So this is the reason why we are getting an error here. And it will give some cannot read property or the of undefined, which is undefined error because of this circular dependency. How we can solve that, we are going to solve that with the simplest solution. As I will show you our, US, I will show you in the next lecture. Because we have multiple solutions for that. One of them is duplicating some code in orders library in regards to get the product. Or we are going to make a parent class which is holding two libraries that references. 161. Remove Circular Dependencies Between Libraries: Okay, as we saw previously that we got a problem in circular dependency. So in other words, we saw that products library is depending on orders library. And also the orders library is depending on products library. And this concept in x in general or in angular in general is annoying Angular. So angular doesn't like to have circular dependency because it's not tried implementation. When you are going to implement a library. The library must be totally independent and doesn't depend on any other libraries which are in the same repository or in the same project. Especially if you want to get rid of products library, you will not have issues that then I need to get through it as well from Arbutus Library. So one of two solutions we are going to do. First one, I am going to make easy solution. So which is, I am going here, for example, in their product page or cart page. I'm going to create in the orders service something called get product, which is exactly the good product service, which is coming from product service. So here as a solution, I'm going to say that, okay, good product, and this product will be implemented, for example, in the services of orders. So we are not going to use anymore that product service. So the other solution is making a base library, as you see here. So we have, for example, a dependency which is called base library. I create a third library. And then this third library will contain modals like product order, card, product I, order item, and two as well, like multiple models, all the models of my project. And then I will have abstract services. So I will not have the implementation of this areas like I will not have get total sales and the implementation of it, no, I will have abstract. And then the product library will implement this abstract service. So in that case, all those library will not depend on products library, it will depend on base library. So in any change you want to do in orders library, you need to do it as well in the base library. Or in other words, you need always to implement some staff which are created in the base library. So you need to implement always everything in orders library when you have, for example, get orders method in the base library. So in the refactoring section, in the next section of this section, we are going to make a refactoring and make this base library. I'm not going to do it now because now we are focusing on the card side. We will see later how we can refactor our project and use a base library, then we will not have circular dependency as we see here. So let's do that. First. I'm going to have instead of product service, which I imported from products library, I will have order service. So we can use here orders service. And instead of that one, we say Orders service and order service. I'm going to import it from. It's better when you are in the same library to not import from the path. You can import from relative path. So which is more easier and clean. So now we delete this part and we use the order service. The order service in that case must have a good product method. So currently we will have duplication of code, which is not a big problem for us now because we are going to refactor it later. So for now, I'm going to go to the product service. Here. Where is it? Here? We have product service. And I want only get product. So we copy this one. And then we go to the order service and create this method here. So the order service will see that product service as well. So in that case we will not have circular dependency. But look, we have here a product, also the model with codes for me, a circular dependency. So maybe you can move the model here as well, make a duplicate of it, or just put it now as any. And we are going to refactor that all of it we put now any, like I will get the product of course product object, but I will use any for now. And for the API URL, we will have another API URL here. So which is called. Products, so we can call that one products. And here we will have products as well. So in this case, we are having the application of the code, but it's not issue because we are going to refactor it. So just be patient with me because we are going in this course step-by-step. So now I can see that good product is working fine here, which is exactly the product service which we created in the products library. So now I will try to see if I am really getting those products detailed from my cart item. Let's console log the product which we got from the service which we have created. So let's save everything and go to our application. It's reloaded, and we don't have anymore that circular dependency. So as you see here. So we need as well in the future to remove this dependency which we have created about the cart service, because a car service is used in products library. So we need as well to implement that. So now we have all the product detail. So as you see, I have two products in the guard. I have the details of them. So let's create or let's template or replace this hard coded things with our cart items. So I'm going first to create like array. We can call it like Garth item detailed. So we can say carte items detailed like this will be the tailed of the cart item like to not have the product ID only, but it will have the product itself. So we can give this product detailed exactly the same type. We can give it as well. The cart items detailed. So in that case, we need to create that model. So this guard as well, we'll have not only the guard item product ID, like we have carte items, detailed product only. And this product will have or will be type any for now because otherwise we will have another circular dependency. So let's use it like this now as any. But of course, we are going to replace it with a product model, which is in products library. And we are going to do that in the refactoring. So here is not got items, is one item. So we need here one item and it will be array of those cart item detail. So we need to import that as well from our cart model. We have defined it here and we have as well the quantity we are going to add also another fields, as we will see later. So going back to this cart item detail, remember to initialize always that with empty array because we are going to fill this array inside this loop. So we say this cart items detailed, can't call it again. Yeah, cart items detailed because we have multiple here, dot push. We are going to push the product. So we can create here object. And this object will be the product, and we get the product which we have a response here. So we can have here not products, we can say response product. So to differentiate between those products and response product. So in that case we will have product. The response product and quantity will be Garth item dot quantity. So we save everything. Okay, nice. We don't have any error. Now let's jump to that template. So as you see, we have created at guard item. So I need to loop over this cart item multiple times to create multiple cart items here. So we have only one now. But if I put here MD4 and in this MD4, I will say let cart item off guard items detailed. So we need to have cart item from God itemDetail one by 1. First of all, let's replace the image. So I would say here, not the only source, like we would have SRC. And then I will say item dot product, dot image. As you see here, we are not getting autocomplete because we define the product as any. But we will get image field after we are going to do that. If factoring. The Alt, of course we can also put the product name. So for Aren't you cannot do this. You just have to do ATTR like attribute dot alt. And then you can use again cart item dot product, dot name. And here we are going to replace it with the product name so we don't say product name hard-coded. We say cart item dot product, dot name. Exactly how it is in the model, how we are getting it from the back-end. So here we are going to say dot product, dot price. And here we have the moving the cart item. We are going to do that in the next lecture. Then we have as well the quantity also we are going to work with their quantity in the next lecture. Here, subtotal is, will be like a cart item dot price or product dot price multiplied by or plus. It's multiplied by cart item dot quantity. So we will have multiple cart items. Every cart item has its quantity. And then we multiply it by the price and I will get the subtotal. Okay, as you see here, we have to guard items which are exactly two here. And we are we are having them with all their details like the prize and the name, image and write subtotal. So we have here sometimes warning, it's saying like found two elements with the same ID. Because here, if you remember with the quantity I said I need input ID will be quantity. So it's better like we can change this. We can put, for example, the product dot ID for example. So it will be unique and we will not have that application on every loop because this guard item is happening two times based on my number or count of my cart items in their cart. So after that, you see that two of these are created. So if we go to Inspect, we will see that we have to cart items as you see here. Let's do more like small styling. Like we can push this margin bottom. We can give it 15 pixels, like it will be separated like this. We can do that directly in the template. We can use prime end, like margining tools. So we can say p margin button five. So it will give it some space under it, which is already defined in prime NG. So as you see, we have them separated. So let's try to add something to the guard. I'm going to continue shopping. I want to add this laptop. So I add to cart, cart updated. We have here three items in the cart. So let's close this and go to our cart. Nice. We have three items in their cart now. So in the next lecture we are going to work with delete the item from the cart, and we are going to work with the quantity, updating the quantity from the local storage. As a recap, you remember, we have refactored our order service. We added the product to get product In order service, which is in my opinion wrong because we have the application in the code between products library and the library. But as I told you, we are going to fix that in the refactoring part. I want you to try it by your hand to see really the difference between having like this duplication or how we are going to create a base library at, inherit from it all abstract methods and implement them in the library. In that case, we will not have any circular dependency between libraries and we will have it exactly in this way. 162. Remove Products From Cart: Welcome back. Now we are going in this lecture to delete item from the card. So as you remember, we have created multiple items and I am going now to delete them from my cart. So if the user changed his mind and he want to filter some items, he doesn't want, for example, to Y this one. So he can click on this button and then it can be deleted. So if you remember in our code in the template, we have a method on click on this icon that we have delete guard item. So let's pass on as well. The Garth item, which we have here in the end you FOR loop is from car the items detailed. So and then I am going to the ts file and then receive this cart item. Of course, this cart item type will be cart item detailed. And then we are going to call a service from the cart. And this service we can create it here. So it's exactly something like set cart item. We are receiving a Garth item and then we are pushing it again to our local storage and update our observable of their cart. Duly defined it that we have a new guard data. So let's do that. So I'm going to create a method. We can call it delete guard item. They need cart item. It's enough to get only the product ID, ID, which is inside this guard item. So we can have the product ID as a string. And then we do again a receiving of their cart. So we have to get their cart again because we are going to update this guard. And then we are having a filter. So we will filter the items of the cart to receive everything again, except the product ID or the cart item with this product ID. So what I have to do, I am going to create a constant, I will call it in your cart. And this a new card will be God, the items. And then I will filter them. If you remember, we have like filter method where it's returning for me items under some condition. So if all the order, the product ID is not equal to the item which I have receiving here. Then it will return for me all the other items which doesn't have the product ID. So in that case, I will get a new cart except this guard item which has this product ID. So I will say item dot product ID, not equal, like give me everything which is not equal to the product ID which I have received from the cart item. So after that, we have a receiving this constant. And simply we say that this cart or cart which we created dot items, give it again, then you caught. So our guard got updated. Now we are going to update it in the local storage. So exactly the same how we did here. We need to create that JSON string. So we can call this JSON, we can call it as guards string and, or for example, we can say JSON string. And then it was 10 Guifei it. So I can be able to set it in the local storage as a string. And of course, we don't forget at the end to update that got observable. So we will see the updates in the front end as well. If for every item or for every component who is observing this guard observable. So let's save everything and try that in our front end. So we will see that we have two items. Let's delete one of them. So when I delete one of them, I see that nothing is happening because I am not calling the service again. So we go again to our cart page and we have to receive this dot cart service that delete Garth item, but what I have to pass the product ID, so I will get the cart item dot-product, dot ID. So let's try that now I'm going to click on Delete. Nice. It's nothing happened, but their card got updated. And here I have extra item which is something wrong. I will tell you why. Because if you know, we have a guard observable and this guard the observable is firing everything inside the subscription again when there is update coming on their cart. So in that case, I have also, again a response guard items for each. And then I get the product again and I push them to cart item detailed again. So the old guard item details will have items. And also when I delete and this got updated, it will add items again, which are still. Their cart in the local storage. So the best way to solve this issue, we can initialize always that guard item detailed with empty array. So when there is update comes to the cart, then just empty that cart item details where we are looping here. So in that way it will get empty and it will be filled again. So after that, I will see that my cart is getting up to date. So let's save this and try that again in our front end. Okay, now we have only one item. So let's add, for example, this one and this one, and go back to their cart. Okay, We have three. So when I delete this one, I will see that got updated again. Okay, It's got updated. When I add a flourish of the page, I still have this cart item here. So in that case, we guarantee that we are deleting always that kind of item from local storage. And also from our guard observable, which is sending every comment or every change to the subscribers, like for example, this icon because it's subscribing to the account. And as well for other pages where they are subscribing to the cart. So now we have here an issue. Let's fix it quickly. I want to get the card count so we can do that easily by making another variable which is called guard count here. And this at the beginning it will be 0. So for example, we will have it as a 0. We did that previously exactly here in the cart icon. So the card count will have the after subscribing to the cart observable, I will see carte items links give me the length or give me 0, and as well here, don't forget to put this question mark in case there is no items or totally. So we go again to the cart page. And inside this subscription of this card, we go here and we say like not before for each we have to say this dot or for example, response card here in that case. So we say guard Count, give me the card count here, updated with that response, which comes from the garden observable or behavior subject. And here we need to replace it with card count because if you remember, we have it here as hardcoded. Now, we will have it as a real number of how many items inside the cart. So let's save that, save this one. And then we go to the application. We will see that we got as well the right items which we are adding here. So the exactly how we did with this badge or icon. So we can check now, we see, okay, it's three. We did eat. It's changing to two. So everything is observed and up to date. So last thing, I just want to add that we need always when I visit this guard page, we need to end the subscription. So as well, we need to do take until as we do always. And then this dot n subs. Remember, we have defined it multiple times. And every component which is needed to enter the subscription. 163. Order Summary Widget: Alright, in this lecture we are going to make this order summary. And this order somebody. It's exactly how we did and how we observe the cart items and we call the product and we did the calculation of the subtotal. I'm going to do the same here. So let's go and create the component. I have created that already. So the component, I used the console an x, and then I have created a component and give it a name, order summary. And this component will be located in the components inside the orders library, and it will be automatically imported to the orders module, so we will be able to use it in other pages. So why I did it as a component? Because I am going to use it in their cart page, as you see here, I called it in our cart page how we did previously. And as well, I am going to call it in the checkout page. So when we are going to replace this content here with the address of the user. So we are going to also to keep this order summary as any formal E-sharp. So now what I did exactly is just giving like some template thing. I gave like h3. Do this order summary. I'm going quickly because we did that multiple times. I will attach for you the code so you will be able to continue with the course. Now, we have the summary price as well. And I am doing here some calculation for the total price, which will be in the components script as we will see later. And as well, we are doing some inflammation like packing and shipping. It's hard-coded information. I give it like some styling, which is called summary price or summary shipment. And then I show again the total price, which will be like the total price will be the same here. So it's just like some declaration random data. I'm just doing it like in a case like to be look like real e-shop. So we have here the seller Item and it will be exactly when I add a new item to be calculated here. So we will see how we did that. So I am having here like some template, I styled it. I added this dialing file to our public styles, which will be inside styles, lips, and then orders. And I have here Order Summary. And this order somebody I give to the container of it like white colored background and some border to keep the same styling, some padding. Then I gave the price display flex, which will be like this div here. So it will have two columns. One column will be the info or their label, and then the value of the label. Again here we have something like we have another one like item prices. And then we have here span, two spans like they are displayed as Flex and they will be aligned near each other. And I give to this diamond flex that they are as block. Because if you don't display them as block, the spans, they will be stuck to each other and they will not be considered like, as like a div, we can say. So we have here display block that span, as you see, we have two spans here. First ban and second span, say the first span and second in every row. So what, how I did style? I just read this band directly. I gave to the first one with 80%. So as you see here, it has 80%. Of course you can also use the grid. I just did it like in different way just to show you that you can also don't have to depend on the on the grid always. And then I said, last child, last giant of the container like somebody price it has span. And last child of this span will have 20 percent font-weight 600. So I have those bands. This is first child, and this is last giant of the container, which is called summary price. So as you see here, we have this 80% and this will be 20 percent. And after that I have another row and then we have a button for checkout. So this button will take me to the checkout page as we will see later. So now we have that styling. As you see, we put some information, it's very easy. I add that also the styling with this lecture. So I add that component. So you don't, you don't have to type again with me or stop the video. You can just grab the component. I have the template, I have the script, and I have put the styling as well in the attachment or to the resources of this lecture. So now we are going to do for that, the calculation of the total price. So for example, I have going here to add another product and another product. I go again to the guard to check it. Okay, We have here the price calculated automatically, which will be summary of all of these prices here. So how this can be done. So it's very simple. I just again subscribe to their cart as we did exactly with that guard page. And then I initialized on every change of this cart. Then I initialize something called total price. It's a fixed variable or class member, which will be called total price, which would be a number. And then I went to the garden again. Here, I checked if I have a guard returning from this subscription, we are observing it. And then I looked over the items of this cart and then I called the product for every card item. Take one. Here. I did take one because we are calling it one time. So when you do a subscribe for that, then it would give you ability to unsubscribe easily so you don't have to do take until like n subs until the component got destroyed so easily you can do that. You just say take one, I take one and finish the subscription automatically. So it will grab one and then finish the subscription. So here you don't have care about memory leak. This steak comes also from our x j as operators, so you can use them as well. And then we subscribe to their product. And then I say that the total price, which I initialized on every change of their guard, it will be the product price multiplied item quantity. But plus equal. This means that I want to do something like that. So total price for every item just it cumulated with like previous total price. And then with this price at all, Like for example, the supper daughter. So with a subtotal which we calculated here. So in that case, you can make it smaller. You just say plus equal. And equal will give you a product of the price, like item.quantity. And it will accumulate to this total price. Only when there is a change comes, then it will be initialized to 0. So in that case, we are able to loop over the items and calculate the total price we are adding, adding, adding. And then it will be calculated in the right way. So that's it. There is nothing complicated. So we have now defined as well subs. So it will be on NGO onDestroy. I didn't add that. So we need to add energy onDestroy as well to avoid. And then we will see these two ends ups will be next. And also this node n subs will be complete. So when I leave this component, I will finish the subscription to the guard, subscriber or behavior subject. So in that case, I am every time updating the cart. Here, the order summary will be calculated automatically. So I go here, go again, add to cart, we can add more items. I go to my cart again. I will see that here. Okay. I got more items and it's calculating for me the right order summary, the last tiling which I would like to do, maybe we can make this full button, like to be big button and shown well, it will attract the eye of the user. So we can do that simply in this dialing file. I go to the order summary. If you remember, we have here order somebody I created check out button inside the order summary so we can hear. We order somebody go and we open a new class. We call it check out button and the button inside the summary will have width 100%. And we check that we reload the application, okay, we have full width of the Checkout button. And when we click on the Check out, we must move to the checkout page. As we will see later. 164. Update Cart Item Quantity: Okay, in this lecture we are going to see how we can update guard item quantity. So in that case, we need to update this guard item quantity in the way that we update also the subtotal and the card summary. So first of all, let's start with initializing our quantity when the quantity which the user ordered. So for example, when I go, again, let's refresh this page. I don't have anything here. So let's initialize with the number of items inside that quantity. So first of all, we have to go to our input number which we have created. It's folded this one. And this input number has like quantity minimum, maximum. We are going to add something as in documentation of crime energy. So always follow the documentation. So as you see, we have here NG model and NG model, you can specify value, so simply, you can just say, okay, and you model, and then in the end you model, we say item dot quantity, okay, but we are still getting error. It's like cannot bind NG model. Always when you get this error, like cannot bind NG model since it's not known property input number. This is because we need to import a module which is called force module or forms module. So where we have to import this module, we imported previously in multiple modules, like products and also like in the application itself. So what we can import it here as well. In the orders library, we have orders module. We say that our components also using forms module four as module contain all of these items which we need for the form. So in that case, we will have that our application and got updated with the latest quantity which are defined inside the cart. And we see here that we have initialized with their quantity. I am going to add to cart another also of this item. So I would go to product and go to this product. I will add four, for example. Okay, got updated. I go to my cart. I will see that I have five because previously I had one. So now we have five of this item. And also the order summary is working fine. But now, okay, this is working fine. Likes a subtotal, as you see here, because it's coming by calculation between the item quantity and price of the product. So it's easy to calculate and it's automatically get updated. But what we need to update as well is order summary. So how we can update order summary or as well when we reload the page, you see I have here again five, but I want to save it. I want to keep this change always. So the best way to do that is to update the cart itself. How we do update on the cart itself. First of all, let's have an event. When I change this, I will read the value and do something with that value. So first of all, go again to documentation. I want some event which is fired when I changed the value of this input number. Always follow the documentation. You will go again to prime, end to the input number. And you see in the documentation that you have properties like as we saw here, that we have Show buttons, input ID, et cetera. And as well, we have also events. And those events, they are behaving based on the interaction of the user on that component. So here I have something which is called on input. So when the value is entered, when user put a value inside this input, then it will fire an event. So how we can fire or call the event? We just go here to the component. And it's like how we have with OnClick or for example, like this one or for example, on focus on something onclick, onmouseover. The same thing you have to do here That you just say on input, because it's already defined as a property of that component, which is called p input number. So oninput, I will create a method, I will call it update, guard item quantity. Okay, so what are the parameters of this method? The parameters will be first is event, because I want to read the value of this input. How much is now the value that got into value like here. Okay, I change it, I need to get four. So I need to read that value. So to do that, we pass something called event. It must be prefixed with this dollar sign. Of course, it's event which can be fired for every type of outputs. This is called output, and this is called input. So in components of angular, you define outputs and inputs for every component. So now we have this defined here, and also we need to pass the cart item itself. So let's create this method. We will go to the TypeScript file and then we create this method, the parameter, as we said, it will be even, you don't have to put prefixed with sign, dollar sign and we just put event and also the cart item. The cart item will be the guard item detailed because we are grabbing from the for loop. So it will be guard the item detailed. If you remember, when we were setting a cart item, I was calling this dot cart service and then set cart item, that cart item, we need to pass the cart item itself. So as you see here, we need to pass the Garth item and then it will be set. But this case, when I am adding a new cart item to the cart. So for that we are going to check if we have the cart item already and we are increasing the quantity. Otherwise, we push the cart item recently and in Europe as it is. So here we don't pass the cart item, but we pass the following. First, we need to have product id for the cart item, which will come from cart item dot product, dot ID. And also we need to pass a quantity, that quantity which we are reading from this event. So let's check what is this event is returning me and how we can read the value. So let's comment out this part. I'm doing this with Control slash and it will comment for me or the parts or the lines which I selected. So we have here console.log event, just like that. So when I update the quantity, I want to see something. So we open the console and then I'm going to update the quantity. Okay? I am getting object, which is called original event, like the event which is done, which is mouse-click, and the value. So what we care is about the value. So we have to say here, event dot value. We go again to our front end. We try. We change this value. We see that we are getting now that I add value, that's great. So we need for their cart item here, that quantity will be the event that value. So here we have event dot value. So if I go now to the front end and try that. Okay, we see that we are increasing but wrong. You see it's like multiple times duplicated because there is some wrong calculation happening. Look, it's really getting wrong and wrong more. So what we can do in that case, we have to check our set cart item. So if you remember, when the cart item exists, I am sending the cart item with the new quantity and then I am increasing the quantity. So I am calculating if their cart item already exist, I am increasing the quantity with the previous quantity. So in that case, we are getting a wrong accumulation. So we are just increasing more and more. So I have, now when I click on 525, it will add 525. So it will be what exist in their cars before, and then it will have more accumulation as you see here. So in that case, we need to say to set cart item to update the quantity, not for example, add to the quantity. So because before here we did that because we are going to say that if courts, if the user comes here and he click on Add to Cart, another add to cart, then if the item exist already in their guard, we increase the quantity. But now our case here we are updating totally that quantity. So we need to read this value and remove the old quantity and updated with the number which is located here. So for that, I'm going to add another parameter to set cart item service, which is called update cart item, like just this and this update guard item will be optional, like to not be required when you call set cart item, because sometimes we are only sending the guard item to update or add the quantity or push a new cart item. So this one will not be required. We will not get any errors in the other goals of this set cart item. And then we check if there is update guard item, then update the quantity totally. Or if not, then just take the old quantity and add a new item or a new quantity to the product item and update their cart. So where this have to be done. So I will check here. I will say if update guard item, like if this gum as true, then it means that I am coming here and I'm clicking on this. So that case, we have to say item quantity is only equal to the cart item quantity. We don't have to do any accumulation or adding all the quantity to the new one. Otherwise, else, if it's false, then, or if it's unknown, undefined, or false, then we have to do this accumulation. So let's save that and we need to update our cart item page component here that we have the set guard item, okay, first parameter is this guard item. And then we say through because we need to update the card item, not add to Descartes. And let's say more of like some items which are really got big. So we can have only this one. So I am going to increase the quantity as you see when I am updating that card is getting updated. And also the summary because everybody in this application is observing the cart, because as you remember, we have this cart observable. And in the cart service, every time I'm setting a cart item, I am saying to the observable, update the guard and notify everybody. So in that case, we have updated the garden items quantity, which will help me to always track the order summary and that God will stay the same always even you add another item, for example, here, and you go to the garden again. You will see here the item. For example, I am going to add this item. Again, this will be seven. So we have to go and find it. It's this one I added. Go to their cart. We will see that it's got seven. So in this way, we are sure that our data are fixed, our cart is fixed. We don't have any issue here. And we are ready to go to the checkout. 165. Checkout Page: Okay, After having our cart page, we are going to move to the checkout page. So for that we need to create as well a new component which we are calling it a checkout page, like how we did with their cars page. So let's go to the next console, generate. And then we will have component. And this component will have a name which is under component or pages. It will be under pages. And then it will have check out page. The name of the project will be orders because we are putting into the orders. And then we do the same thing, which we did for every component. And we keep the the tests. And also we need to add a selector which will be orders check out page. So in here that we have now ready for us the component. We press Run. We go to the pages in our orders library. So we must have here and you check out page. So we check that. We see that we have checkout page here and we have the component as well. So what we need, we have to add a route in order library, exactly how we did with the guard. I will have here checkout. And we will see later how we are going to authorize this page. So we will force user to, to look in and then he can put his address and then he can place an older. But now we are going to make a formulation for checking out. But as a guest, like we don't have. For example, the reader user is logging in. You are going to do that in the next section. But now we are just making normal placing order with an existing user account which is called guests. And then we need to check out or go to the check out page when we click this button in their cart. So how we can do that? It's very simple. We do the same thing, how we do with normal navigation. So we will say like router dot navigate and then we go to a specific page. Or you can say a router link on the checkout page and you give like that in the order summary. So we have to go to order somebody component because the Checkout button exist in the order summary component. So here we will give onclick. And this onclick, we will give it like navigate to check out. And then we have to create this method. So we go again to the order summary, and then we create this method. We say navigate to check out, we need to import also the router service. So we say here private router, and then it will be router. And this router will come from angular core, as we know always. So we are going to use this router service. We say this dot router, dot navigate. And then we opened array. We say inside this array that navigate for me to check out page. So that's it. So let's save everything and try if we are really navigating to our checkout page, which we have created previously. But I still in the checkout page because I made a mistake. Here we go to the orders module and we have to say that that component will be checkout component, not guard page component. So in this way, you guarantee that you are going to the checkout page. So let's go back again. Go to our guard, click on Check out. Okay, perfect. We have checkout page works. So the checkout page, it will be exactly like the guard page. So it will have on the top Something like back to their cart, like button. How we have like back to their cart here and all, for example, back to shopping. And as well, it will have a form. And the form will be exactly how we have built in the admin panel. If you remember, I am going to look in and as you see here in the users, we have created a form which is giving us name, email, password, and all other information about the user. We will use the same form so we can copy it exactly the same. And we have to remove is admin and the password and the other information can we can use them. So I explained already about this form, how we got the countries, how we got always the validation. So when you want to create a user without validation, the only difference that we need to validate those fields when we are doing that in their checkout page. So in that case, we are going to use the same exactly foreign which we used in the backend panel. We will use exactly the same components like this input. So first let's do that template for the checkout page. So what I need as well to have like a checkout page here, like exactly how we have with their guard. So we have. Checkout page and we will have button we call it back to their cart, not back to the shop. And we make a button here which is back to their cart. So we have to add as well this method. So we have back to their cart. We would use also the router module. We say private and the router. And the router. And this router will come from Angular. And we say, this router dot navigate. And I want to navigate to their cart page. So it's exactly how we are navigating always. So we save that, we save that. And we go to our cart page in the front end. So we have here check out. Okay, we have now the button back to their cart. So when the user wants to change something in their cars before checking out, he can go back to their cart. Now we are going to add the form. So the form will be also inside a grid. So I will give it like an aim big grid. And it will have a name which is called like check out form. So exactly the same. So we gave out form. And then we need to use the form which we used in the users for form in the back and all in the admin panel. So we are going to use exactly the same one. So I have prepared this code already because we have repeated everything like we talked about how we create form control name, how to use every component, how we use the switch, how we use the dropdown, how we got the countries. If you don't know how to do that, you just go to the lecture where we have created the user in the admin panel. So here you can use the same concept. We are going to use the same, we will use as well. Same initialization for the form like here. We are going to use the same submit. We will have as well that same validators which we use previously like this is required, this is not required. And after that, we will use the same exactly orders template model and then we will place the order. So let me now import this code. So we have all the code here in the grid. So I have prepared that already. I click here and we have now the things are imported. So we need to import some controls. Like for example, we need to import the input text model module and we need to use an input mask and also the other inputs like the drop-down. So we can do that as well in orders module. So we import all of them input text module, input mask module, all of them to our modules which are located here. So we have an input mask and we have as well the input drop-down. So we will not have any issues in the template. So the template should works fine after that. So we save and we should not see these errors only because we are still seeing this error because this form control name is not defined because we need also to import something which is called reactive module. So reactive forms module, which we have used as well in the admin panel and we talked about it previously. So here, now we don't have any errors. So if you remember in the user is form, we have to initialize a form and also get the countries. So we need as well to use the same code which we have here. So I have prepared that as well to not get so much time from you in the lecture. So I don't need to explain that again because we explained that already in the lectures of users. So here is the form I said on an NG on in it, I have any checkout form and any check out warm we have these checkout form, group, form builder and group. And I listed the fields which I want to use. And as well, I used get countries, get countries. We got it from user service, if you remember how we used it. And the checkout form, which return for me the controls as well. And then we have is submitted checkout form group or their items because we need to read orders item to place the order, as we will see later, the user ID which is used, we need to use as well the user ID. So, and we have the country's list which will be listed in the drop-down. So it's exactly this code now, currently is exactly how we have it in the user's form. So you don't have to write it. Again. I am going to attach it with this lecture. You just use those codes for your components. I will attach checkout page component, the HTML and the TypeScript. As well. You don't have to forget to import those modules, which I talked about previously in the orders module. So now we need just to style it. But first let's save to check. We have now everything is fine because we need as well to style the checkout page. So I go to the checkout. Okay, we have now everything. But we still have this button check out because it's in order somebody components. So we need to check if we are on checkout page, hide this button. And we have now here everything, but also the buttons are blue. So let's create a styling file first. We have to add here. And not only orders, we need to add a new folder or file, we call it check out. Like we can just say check out, SCSS and inject out or in the orders we need to import it. So in that way, this one would be important as well. So we have to put here, check out. So after we imported them, we are putting the style for that. So what I did in the styling is just exactly how we did with the cart page, if you remember. So here I have the checkout page. I give it min-height to give it like some minimum height to not be like very, very thin. And also the buttons I gave them primary color border 0, like how we did previously. And check out the form. I give it like a little bit margin top from here to be far from the button. And also the bot placing order. It will be full width because here we have also Place Order button. We will put it with the fluids. It will be colored as well from this classes which we defined here with orange. And then we see that we have everything like they check out back to cart and the place order. But as I told you, we need to hide these checkout. So I can't say in order somebody component, if I am in checkout page, hide for me this button, how we can do that? We can do that simply. We go to the order summary. We call it already that router component, if you remember, or router service, we need to check this router if contain check out page or not. So in the constructor method we say this router, that URL, like the current URL of the router. That includes. So you can't say includes for any string to search for a specific string inside the string. So here the URL will return for me this URL. So I will check if this URL contain word which is called check out, then hide for me the like the chick out or the Checkout button, which is in the order summary. So we can't say if it's contained, check out. We can use end line. If so we have here, we can give like a variable or a class member we call it is checkout. So to know that we have the checkout page and we give it at the beginning as a false. So initially it will be a false. If we have a checkout page, then we say this is check out is through. Otherwise, like else, it will be false. These check out, it will be false. So now with this variable which we have created, we go through the order somebody template and we say that this one, this button will be hidden totally. So we can say ng-if the expression is check out. So when it's not check out, then show the button. But when it's checked out, then hide the button. So we save, we save this as well. We go to the template. So as you see here, the button is hidden in the checkout page because I have checked out button here or takeout string. But when I go to their cart, I will have check out is appeared here. So as you see, I checked the router. I did it in the constructor, of course you can do that in NGOs in it, no problem. But I did it in the constructor, which is like before NGO on it before initializing component. When we construct this class, then it will call router, URL includes checkout, then it's checkout through or check out false. So then we use that in the ng-if to show or hide this button. So what we need to do, the only difference that we want this form to be validated. So we need to validate all of these fields because when we copied them from the users form, those are not required. So we need to make those as well as required. So let's do that quickly. I will have here like city, is it required country zip code? All of them are required. In that template, we need to have, for example, email, okay, we have validation. For foreign, we have validation, but street we don't have. So we have to change all of those to be not formed, but it will be Street. So a street is required. So there same thing. I have to copy this part and put it for apartment. I think it's not required. Let's check that in our form. Okay. It's required also, it's important when you deliver a shipment, the shipper must know the apartment. So we say as well, here, apartment and apartment is required. The same thing we do for the zip code. So we have to add as well that zip code here. So we have zip. And then the city. You see, it's exactly the same thing how we did with the users form. So you don't have to like, tell me if you, if you don't understand this lecture, just go back to the users form. You will understand all of this point. So that's why at the beginning of this course, I prefer to you to not skip any part of this course because all of them are, you can consider them, are required to attend in the case you want to follow me. But I am mentioning in every lecture where I explain this, so you don't have to worry about that point. So now I have everything is validated. So we need to add, well, add a button for placing order. We say like play onclick. We have here the button onclick from Prime NG. So I will say Place Order. So this place order method, I have to implement it. So first of all, I need to place the order. So I will say here, if this, like, if you remember, we have this dot form, like the checkout form is invalid, then return and do nothing because we didn't achieve that validation conditions. So in this case we go back. So then when we submit the form, we need to set the variable which we have created, which is called is submitted to true, like to enable the validation. So when the user click on Place, Order, it mean like he submitted, but he has a problem in the validation. And then next lecture we will see how we can place the order we need to collect the data and make the order model. So in this way, we have finished this lecture. So you see here we have the template, we have defined Place Order button, and we have the form ready for bracing or placing the order. And as you see here, when I clicked on place order, all of those fields are required. 166. Placing Order: Okay, what we are going to do now we need to place the order. If we go to the checkout page and click on Place Order, then the order will be placed after validating the form data of the user. As I told you, we are going to place an order as a guest, we are not going to implement the login now. We will do that in the next section. So first of all, we need to try the placing of the order step-by-step. And then we move to the log in and grab data of the user from the database. But now we have to place the order normally. So let's collect the data from the form. As you remember, we have in the orders library and model which is called ordered. So in the orders library we go here and we see here order. And in the order we have like ID, order items, shipping, address, one shipping at this too, and all of the information we needed to place an order. So we need to collect those data and place them exactly the same to their back. And if you remember with the Postman, we were posting the order as I showed you previously in the back-end part. If you don't see the video, you have to go and see the video of creating an order in the database. So let's copy this data and go to our checkout page. On the Place Order method, when I click on this button, which is here for placing the order, I have submit and then I'm checking if the form is valid. Here we need to create the order model. So we need to create const order, and it will be type of order. So the order will come from the models. And then this will be equal to my fields, which I need to feel here. But first we need to replace those strings with value, the ID. We don't need it because when we placed the order, it will come automatically with the ID from the database. Mongodb will do that for me. And then order items. We need to collect the order items. For now, let's define a class member. We call it this order items. And this order items, we can define it here as a class member, as you see here, which will be array of order item. So we have one order item and it will be an array. At the beginning, it will be initial array. So we need also to remove this question while we still have an issue here, because we need to put a comma. We have here error because it's saying that the type of order item is array, but it's in the model, it's only one or the right. Let's check the order. If you remember, we've made, I think I forgot to put here an array, so we need to fix that. I think the admin bundled application will not be affected for that. So let's check the admin panel to be sure that we don't have any issue here. Okay. Everything is still fine. We don't have any problem. Okay. Go back to the front end application. To the end you shop. Now we have the order items to do now the address, so they're shipping address one. We can say that this dot check out form. You remember we were accessing the controls of the form group like this. Dot. We can put now the street for example, that value. So with this, we have accessing the street field and we say that we have the value of it in the shipping address one, we must match exactly the model. So you don't have to forget that maybe shipping address two can be also like the not the street, but we can use the apartment. So we have here apartment dot value and also the city will be the same. So we need to copy this, put it here, remove this question mark and we say the city, that ZIP code the same. We have to add also the zip code here as well. So we have to put here comma, comma and here country. Again, we have to do the same. I'm going to do it fast. So we have to add all of them like this. And we will have issue with a user. I will explain it later. So first of all, we need to have like all the values to be right. We have country that remove this question mark. We're gonna go here, country phone, we need to put as well. The phone here state 2s, total price, total price. Also we need. As well to calculate it somehow. User and they ordered. So we have as well here. They ordered or it can be date dot. Now, let's remove those question marks and we are going to check if everything is right. So we have the city, country status, total price, and the user. So the user we don't have in the form something called user. So we are going to use something called user ID. And this user ID will come from like a static ID or static user, which I am going to use as a guest. So we go to the admin bundled application. We can create a user like random user. We give it a name like guest, and we can fill the email. For example, if your organization we can say and we can give it a password like and all other information. Maybe we can give them like that. We can put any number here. And we click on Create, created, that guest. So what do we need to do? We go to the database and the grab the ID of the user. So I went to the database, cloud mongodb.com and I log in with my account and then I see all the users, which I have here. I have created this guest. So we take this, so we can click on edit. Maybe we can copy this part here and go to our application. We need to replace as well. They check out page, we have to add that to this user, but you can make, as a default, this user will be the guest. Of course, we are going to display or replace that when the user get lock-in. So we need to add this string here. So we didn't need the time to not get an error. So the user ID for me will be this string. So we save that. And then we need to move to the user. And we see that we still have an issue here. Why? Because I made this mistake by purples just to show you like when you get a different requests. For example, in the admin panel, we were getting the user as an object which will contain the user type, the user which has an ID name, password to the back end was returning for me this object, not all of it. It was only name, maybe an e-mail, and some other information. So in that case, when you have conflict between the a post request and they GET request, then it's better in the front end to define this as any. Because in there GET request, we are getting this as a user object. But when we post a request, we need to send only the ID. So it's better to solve this issue, that conflict between the application. You just say that this field is n. So in that case, you will be able to use the form which we have created here as a string as well to post an order to the database or to the back-end. Because if you remember the backend with wires getting the user as a string of its ID for the date ordered, we just need as well to put date. So it's capital letter dot now. So when the user post this order successfully, then we put the dot now. So if we go to the date order, so we need to have this date now and you can encapsulate that as a string. So you can use a bat pigs and take this as a string because it's asking it as a string. So as you see here, so we go to the order it say that I want that as a string. So we can grab that between us, think ticks. And now we need to get the order items. So we want to post an order. We need to send the order items. So every order item, as we remember, contained product and the quantity. So we have to subscribe to their cart again. So if you remember, we have created a guard service and discard service. I can retrieve all the cart items. So we go here and say private. And then we have to get like cart service. And it will be cart service type. And we use this guard service to get the garden items. I have created here. Class member, which is called order items. So an MD on in it after intializer form, we can say this and then get carte items. So in that case, we have to define a method after initializing of the form, we can say private Git cart items. And this get guard items will be using that card service. So we have to say this dot card service and then observing our guard. Or you can use as well get guard because we don't have to use directly. The cart items, which we have, like all observe that guard because we are not doing any chain. So every time we visited the component, we get that card from our local storage and then we read the data. So you can say like a constant cart. And of course you can use the card which we have created the observable. So this cart will have a type which is called card, and this card will be imported from the models. Now we need to get carte items. So I have to say this dot order items, which we have defined previously, we would say card dot items. But here we will have a problem as well. Because if we go to cart items, they have cart item product ID. But in the order item of we go to the model, we have only product. So we have one of two options. Maybe we have to change this to product ID as well. Or we can map a new items to fit on this order items. So I can say here that this guard order items dot map. And then in this map I can say item. And every item will be like return for me an object. And it will be product, and this product will be item.name, product ID, and then quantity will be the same item dot quantity. So in this way, I am mapping all of those items to have a product ID but product. So it will loop over all items inside, guard item, item by item, and change it to have product not product ID by reading the item dot product ID. And this were returned for me array, as you see here, of order item. So in that case, we have filled our order items. So to make sure that we have everything is fine, we can just look in the console log this order items to be sure that we are really doing fine. So we can't say console log this third order items after we did this mapping here. So I will refresh and then I will open the console. And we will see that we got array, product and quantity. And it will be a product not product ID, which fit exactly with the order items. And then when I am submitting a new order, I say this or other items will be older items which we have filled here. Do we need to calculate the total price? No, because we are if we send the total price to the back and then any user can post the total price at. In that case, it will make for me an issue that like I will place. For example, hack their website and send an order with a fake total price. Like I can put 41, $1000, I can put $2 and I can send it to the API. So the backend is not receiving the total price, but we are calculating it internally and pasted do the database, so we don't have to send that total price, the total price in the model we used it because we wanted to use it in the admin panel application. If you remember, we went to orders and we, we're getting the total price here. So in that case, we guarantee that everything is happening in the backend. We don't send anything to the front end. So always when we are doing this calculation, when we place order, everything should become from the backend. Otherwise, if you send from front end like this here as a string, for example, you send it to the back-end, then it's not good practice because anybody can fake this price and send it to the back end and to make an issue for you in the e-shop. So after that, we have made the check out. We have created the order model. If you remember, we have created a service which is called create order. And this create order will post an order for me to the database. So let's call the order service. We go here again to our checkout page. We ask for the order service. So we have here cart service. We need private orders service. And it would be type of orders service. Then this order service, we need to use it to create an order. So I will go here again. And then I would say this dot order service, dot create order. And I will send this order, do the back-end. But as you remember, this will not be executed until I subscribed. So when we can do the subscription, and then we can say order here or we can just keep it and empty, like empty. And then we can redirect the user to a thank you page, as we will see in the next lecture. So we can hearsay. Direct too. Thank You page. And as we will see later, I am going to add it to their course soon. Like after you, okay, you look into this course, you enrolled, but you don't see that payment. I'm going to add this payment maximum after two weeks of creating this course. So we here, we do maybe not too, thank you, but also maybe to payment. So payment page. So we will see in payment that we are not going to paste any order or any order to the database until the payment gets access. And we will do that with sprite payment gateway. But what about the status, if you remember, we had a status also for the order and you know that the order is coming always as bending initially. So the status of the order, we didn't feel it because we don't have a four member which is called status here. So if you remember, we have created a constant in the admin panel, which is called status. So the status for the order initially must be like bending, like the initial state of the order. So when we go to the Admin application and then to the order, we have order constant and we have order status. So it's better here to use this order status the same, which we used in the back-end. So in that case, we can read in the backend the same data which are pasted or both through their front end. So here I would say maybe we can move this order constant, like from here, we cut it and move it to the orders library. So we go here and we can hear pasted near the components model services. We can't based directly on the library, so it will be near the module. And then in the admin application we will get error because this file will be missing. So especially when I am leading the order detail and also the order list. So as you see, the order status will not be exist anymore and it will give me error. So first we need to import it from this one, from Blue Bits orders. So we got this one and pasted here, Okay, and remove this part and save this one. And also in the order details, we got this here and paste in the order like I am going to get it from the orders library, but we are still getting the error. So the order status here is not exported from orders library. So we need to go to the index and say Export for me, start from. And then we say lip. And this lip will, I'm going to import or export the order constant. So in that case, the order details in the admin panel application and also the orders list. We'll see this like the order status constant. So in that way we can be able to use it as well in the front end or in any shop application, or in the library itself where we have created the order or posting the order. So the initial status for any order, it will not be like processed or shipped. It will be bending. So when I go to the admin panel application, I go to the order detail here the user will get the order, the admin will get always the initial state of the order for new orders as appending. So in this way, we will be sure that we are getting always initialized that bending. And then the admin can change the status here as we see here. So now let's go back to our checkout page. So let's import here the status order status constant, which we have used here. So we can import it as well to our checkout page. So I will go here. And then I would say import for me the order status constant from. And then we select the current path or the patent because we are in the same library, so we don't have to care about that. So after that we say the order status initially will be order status. And then if we need to go and check the order status. So the order status in the stored in the back-end as following, as you remember or in the database. If we go to orders and we will see then the status is stored as a number. So we need also to get the key, so we don't have to use the label or their color. We need to get the key so far that I would say maybe we can go, going back to our checkout page. So we have here the constant we have checkout page. I will say here object dot keys. So you know that this will return for me the keys of this object which I am passing here. So we need to get the keys of the first object. So if I get the keys, then we would get array of the keys, which is 0, 1, 2, 3. So what I need is the first one. So we have like this 0, all you can directly without anything who just say I want the status 0, which will be stored in the database, exactly how we have a defined our status mapping, which is also in the constant, as you see here, we have the 0 for pending. So I want the 0 state and it will be stored in the database as status 0. And in the admin panel, it will appear initially as bending, which is the 0 0 status. So I will go first. We can make like here a console log. Maybe we can confirm that it's success. So I will say console.log, like successfully added. Of course, as I told you, we are going to replace to thank you page or direction or with the payment as we will see later. So let's save. I am going to fill this data quickly. So I feel those data, I'm going to place the order, but let's open the console so we can see our message if it appear after placing this order. So when I click on Place Order, okay, successfully added. So let's check their database if we are really adding this order successfully. So let's close again these and then we refresh our database. And we will see that if we are getting the order, nice, we have the order here. So we have order status and hear everything which is related to me. And as you see that we have the user is that guest one. So we don't have, as we'll hear, the name and the email because we are not letting the user login. Because as we said, we will force the user to login on checkout page so we can get his information without, for example, putting all of those information into the database. So actually, we can get rid of name and email here because we don't need it, because we are going to ask the user when he register in the future, when we are going to make the authentication to enter his name and email on registration. So we then Just make, for example, these are read-only variables or read only fields. And all of this information are editable so he can place order with his email and the name which he registered with. So we go to the admin panel, we see if we have really that order. Okay, Nice. I have here the order bending so I can see the order and it comes from the guest. Of course, as I told you, we are going to replace that with a user, as we will see in the next section. But now we are posting the order as guest. And later we are going to use the login and authentication in the front end to get the real idea using the shared library. So as you see here, we are going to see how we can use the login component, which we used as well in the admin panel application. So the same lock in, we are going to use it as well in the front end to log in that customer and let him place orders. In the next lecture, we will see how we can really direct the user to a thank you page after successful of placing the order. And one last thing I want to show you, if we go to the detail of this order, we will see that we get the same quantity, exactly the things which we had in their cart. 167. Thank you Page: After a successful placement of the order to our e-shop, we are going to redirect the user to a thank you page, like we can't tell him. Okay. Thank you for your order. We are going to ship your package in next three days, for example. So we can remove this console log which we have created here. And then we are going to read, direct the user to a new component. I have already created that component which is called thank you and thank you page will be like some checkout page. It'll be the same in checkout page. And inside there is a div which is called Thank You page. I put H2 like first title, like thank you for being with us. And another h3 we have received here I have error. So your order and then it will be delivered in next three days as well. I have a button which will be back to shop. But here I didn't use navigate and onClick. I used router link, like it will take me to the homepage of the application. So now let's try that. So I, of course, after adding all of this, I added the route for the success page. I called it success. And the component will be Thank you component. And of course, this will be also authenticated as we will see later. So in my check out page component, I will just use the router again. So we have to say this router book navigate to our navigate. And then it will be an array. And it will be the directed like to success. So in that case, we will have like the redirection of their success after we ensure that subscribe like Succeeded. But if not, you can also display an error message to the user. You can have it as a homework for you. So you can just say there is error. For example, you can display some message to the user as I told you. So we can just say like this. So after the subscribe, we have here, the subscription, those brackets. After this brackets, you put a comma, then it will response for you with the error. So if there is error in this subscribe, then it will be executed here, so it will not navigate. So maybe we can say display some message, for example, to user. So you can do this as a homework for you. So now let's try that. We go to like navigate to see if we are navigating. After checking out, I go to checkout page, I feel that data. And then we are going to place the order and when its success, it will redirect me to the thank you page. So we place the order. Perfect. We have thank you for shopping with us. We have received your order and it will be delivered in three days. And then you can click on back to shop and you will go to the homepage again. So that's great. So we have placed the order successfully and we have now fully E-sharp, like we can say, functional, we just need to add those points, which I told you about authentication, which we need to force the user to login before he can check out. Another point, I need to mention, you see that our guard it's still fall. So we have here like it's still two items after we place the order so we can initialize as well the local storage with empty cars because after successful off check out, I want to have this guard as empty when I go to the back to the website or to the shop, I have no cards because I ordered that already. So for to do that, we can as well go to our like here where we are successfully creating the order. We would call that card service. So they stood guard service. We need to not call init card local storage because in any current local storage, as you remember, we have checking that if we are having new card, initialized and new card, then okay, make a new card. If not, then use their card in our local storage. So we need something which is called empty that cart. So we can as well do empty cart. So we can have this method as well. And here we can copy the same. So we can create initial card, we can give it a constant. And then we can say check like local storage dot set item and then with initial cart. So after that we can call this method. I'm going here. And then I were to place this method to our page. We still have error here because also we need to change it to JSON because otherwise it will not work. So we have here initial card and I am going to pass any shirt Card JSON. So in this way, we have empty cart again. So let's go here and say empty that cart. So after navigate, so it's better to do it before the navigation. So we empty their cart and we navigate to the success page. So let's try that. So I feel the form. I'm going to place the order. Okay. We go to back to the shop. And as we see that we still have this two here because this one is observing, as you remember, is observing the cart. So somehow we have to say to the observer to get initial card, we don't have to have like the guard observable which we kept already. So for that, I go to their cart service and I say that this dot guard observable dot next and then we give the initial cart. So after emptying the card here, we can't say these two card dot next and then initial gut. So in that case, the person who is logging to the application after, if he stayed in the page, for example, then he would go back to the homepage again and he will see that that guard directory empty. So let's try that again. I'm going to add two items to this guard and then go to the my cart, check out, fill the form again. So I will tell you later to not fill the form again, again for development, I will tell you how to initialize those fields with initial values. So you don't have to feel that form every time you test something. So I have here, again the form field, so I replace an order. As you see, okay, back to the shop. We have here that Garth empty. We go again and we see that we have, our cart is empty already. So when I go to the product, I add some item. You see that we have the item back again. So in that way, we guarantee that we have empty cart for the user. He will not have any issues when he wanted to go back for shopping from my e-shop. I just want to mention for you something in case for development purposes like you want to develop. You don't have to feel every time this form when you want, for example, to test the check out, I'm sure you will try to always to test the checkout when you are developing. And then you need to feel always this form to make easy solution for you. If you remember, we have here some string which is empty when we are creating the form group. So you can give here a default values. So you can say here name one, for example, e-mail. You can give some email, email.com. And when you are reloading the application, you will see all of these data are filled automatically, so they will be by default with those values. As you see here, I reloaded and I see those values default. So in that case, you will not have to care about filling this application or this form every time you are refreshing your code and then you go back, it will be a very tough for you. So you just set up some default values. And then after you finish development, you are sure that everything is fine. Then you can replace, remove all of these default values. So it will be empty by default for the user in public or in production. 168. Enable Login On Checkout: In the previous section, we saw how we were able to place an order as a guest user. But now we are going to make the placing of the order based on the user data. So in that way, as every shop we are going to ask the user to log in when he is pressing on the Checkout button. So how we can do that easily? So first of all, if you remember, we have created guards, and those guards, they are created especially to protect pages. And we use our login component, which we have created previously in the admin application. So going to lips, if you remember, we have orders and those orders, if you remember, we have order module. And in the order module I defined my hypothesis. But how we can create or protect the check out page, checkout page, we are going to use something like, for example, the guard which we created for the admin page. Going back to the Admin application, if you remember Going to its routes, we will see that we have in the app routing module here that we've created can activate out guard. And the out guard coming from the user's library, which we created before, which is checking the links and the token. And then based on that, it will direct you to the login page or it will tell you, okay, you are welcome. You can enter and return, true. We explain that all before. So in that way we can use also the mouth guard to protect the checkout page. So the checkout page, if you remember, we have defined the air out of it, the orders module. So in that way, I can't say after the bath can activate. And then we say use our mouth guard. And the Asgard come from where? From users library. So if you see it's automatically imported here. And don't forget the comma. But here we have a problem because we need to say that this is an array. So you have to put it inside an array. So array out guard to avoid having some error. So now if we go again to our application, going for example, to the shopping cart, and I go to the checkout page and then say here, check out, I'm not able to do anything. So let's open the console and see what is the issue. We will see that there is cannot match any routes URL segment login, okay, So I am really read directed to their login, but I cannot go there because a look in route is not defined. If you remember, the route defined in the user's library or in the user is module. If I go to the user's module, I would see the path login is defined here. So in that way, I need to include the users module in my application. So if you remember, we have included as well the user's module, in the app routing module or in the app module of the admin application to get defined for all routes which are included in that library, as you see here. So we need to do the same also for the engine shop. So I will go to the end you shop application and then say in the app module, import for me the user's module. So in that way, I'm going to use it here. And then I would use the possibility of Auto Import All you can use it or imported by yourself manually. So pressing Control dot or control space, then you will be able to see the Auto Import Method. So in that way, we will see that the module got imported. Okay, Let's save now and our application will be reloaded and I will try to click on Checkout page again or on Checkout button. I click. As you see here, we have moved to the login page of the I-N-G shop. So the logo in it's exactly the same styling how we have created before with the gray background and also, for example, the image and also the text. So it's using the same component which we have used previously in the admin page. But as you see, everything is kept here. For example, the header and also the footer, so only in the container. So now if I look in as a user, as my user which is registered in their database, then I will be able to see the checkout page. Otherwise, I cannot see or I cannot check out only if I can or if I look in to their shop. So I'm going to try to login. So I will put here my e-mail which I have. So I will put here the e-mail and then I have the password. As you see here, I am redirected to the homepage. Now, I will go again to the check out page and I will see okay, that I can access the checkout page. So in the next lectures, I am going to fill my data automatically. You know that I have, my user has already data in the database. So in that way, if I don't have that at the beginning, I can place or fill the form, place the order, and my data will be saved in the database. But how I will load user data, this how we will see in the next lecture, we are going to use NGINX to save all the user data in some store where we can be used everywhere in the application. So for example, here in the products, as you see, I can't see a product, but I cannot do a review only if I am locked in. So because here we are going to add some review section which will not appear only if the user is logged in. How I can know that the user is logged into the application we would use for that MDR x with the current, we use the observables as you see before. But now we are going to use the MDR to do a state management of the user state or the user session in their shop. 169. What is NGRX: Okay, in this lecture we are going to know what is MGR x, y. We need NGINX. So NDR x in general is a stage management. Okay, you didn't understand me, but I will explain it in a way which is practical for you. Many courses are covering and DRX like as a library and it can be used for stage management. But what is state management? If you remember before we created Add to Cart. So when I am adding something to their cart, I see that the number here is increasing. So it's like I have a public variable that all application has access to that variable. It can be increased from anywhere or from any component. So when I go here or when I go for example to product page, I click on Add to Cart. I will see that this number is increasing directly from any component which is using these, for example, that the state. So in that way we did that, we using observables, but now we are going to use that using NGINX. So NGINX actually is a store which hold the public variables which are used among the application. So for me, I have a variable which is public. I can access it from any component. And this is exactly the goal of x. Of course, it has also more abilities, as we will see later, like having effects or is fetching data from the database, etc. So the usage is for public variables which can have r can be accessed from any component. So as a structured here, I have a store of variables. So store or variable has, for example, access to something called reducer effects and the rest service and smart component. So we have, for example, our smart component, which will be in our case like this one. So I have here our smart component, which will be the product itself. I click a button and then I do an action. So this action is giving me the ability to access that variable in the cart. So the smart component in that way or any component in Angular, is observing or subscribing to that store of the variables and reading data from it. Of course, that also there, for example, the smart component can create an action. So it takes an action to change some variable in their store. So for example, I have an action which is like Add to Cart. And this Add to cart is going to fetch some action is called Add to Cart to change the value of the variable of card number or cart count how many products in the cart to be increased in the store. So increasing that in the store is using something a reducer. So the reducer is used for filtering the data or updating the state of that variable. It will move, for example, as we saw here, from three to four when I click on Add to Cart. So in that way, the application or any variable can be seen from all components. So I don't have, for example, how to say we can't have a private variables for each component. So in that way, many people are asking how I can define a public variable which can be accessed our transfer data from component to component. This is the way we NDR x or using epsilon observables as we saw before. So now, as you see here in NGINX documentation, it's saying that is a framework for managing global and local state. I am going to show you also an example of usage of MDR x in something like a real-time data. So I want, for example, I have a trading application. And in this trading application, I have multiple components and the prices are getting changed very fast based on WebSocket. So for example, this website, it's called hetero. I don't know if you know it. And it's observing the prices of every like stock, for example the oil or for example, that Bitcoin here as you see the Bitcoin, for example, this component is getting increased or decreased based on some WebSocket connection. And the state of this component is getting updated, always like the numbers here are getting updated. How this is happening, how like this is getting updated, the time. This is called a state. So the state of this component, which is called Bitcoin, and this number is getting updated always based on the WebSocket data which are coming in real-time from database or from specific server. But the other components are not getting updated because there is no any state action is mentioned or going to those component. So only that component. So I have to assume that I have, for example, a variable which is called Bitcoin in the state store. And this variable only is getting updated, but the others like gold or euro-USD is not getting updated. So the same thing as we do here. We used only one variable in our state store, so we used only the cart. So as you see, there are multiple. So here we have only the guard variable, so which can be accessed from all components in the application. So this is the main idea of MGR x in general, we will see in detail how we are going to implement and the r x to observe the user session. So in that way, when I am going to check out, I have stored a variable, public variable, which is called user authenticated. So this user, when it has data, then it's going to fill this data here. And also, for example, I am going to use it as you see you later, that we will have here some review and comment. So the user, if he is locked in or if this variable is defined in the state store, then we are going to have here something like a review and comment field. So the user will be able to see that if he is not logged in, you will see only this page. If he is not locked in. 170. Let's Do Create NGRX State Store in Users Library: Going through the documentation of NDR eggs, if you go directly to something called architecture or getting started in NDR x dot au website. Then you will see this diagram. And in this diagram it's explaining for you more what I talked before. So as you see here, we have a component is always doing an action. And then this action may be, it will use data to get some data from the database or not. So that's why it's dotted. So this action is going to use the reducer to change a state or a variable in the state store or in the store itself. So here we have something called selector. It's like, for example, I have here 20 variables and I want my component to select only one variable or subscribe to it to observe always the state of that valuable in the States door. So in that way, all other components, like if I have here another component, we'll see the changes also of that variable in that state dot. So using selector is also something which we will see now in action. So if you imagine with me that in the architecture of MDR x there is something called actions reducers, selectors, What are they? They are files and all those files, they are classes. And they contain some functions to achieve this diagram. So to see how to create those files, impractical, I am going to show you a way with NX here in the NX console. If you remember, we were creating components. We were creating multiple staff using this console. And it's helped us to generate also some boilerplate of n DRX. So when I click on Generate here, I will have a list. And in this list I will see that I will have novel angular and DRX. So in that way, we're going to generate the files which are required for Angie RX or the state store using this console. So when I click on it, it's asking me to define a name for that feature. So if you remember, our application is divided two features or libraries. We have orders, products, UI and also users. So we need to have the user state or the user session in our application. So all components in the application or in the shop can access that variable to fetch user data everywhere in the application and observe the changes if the user is authenticated, locked in or not. In that way, I display some information on the application or not in those components. So first of all, it's asking for a name. So this name is will be always the same name of the feature. So for example, here I have users. All you can define any name, but here in this case, I will call also users and also the module. The module here you need to specify the path exactly how it's here. So first of all, you have to say lips. And then after lives we have SRC slash SRC. And then we will put lib, and then we will specify the module. What is a module as we saw here, its users module. So here this file is going to be changed based on like generation of the state store because it's going to add some libraries and some imports where it's using the state store. So here we have to define the file, I will say users.js module that has exactly the same name of the file here. Okay, What is that dictionary or directory which will be defined? Normally they are naming it like this. It's called state. But for example, for us, we can remove this plus and define it in that way. Also, as you see, the comment is getting executed and it's telling you what errors maybe can happen. So for example, here it's a past does not exist. I made here error, especially to show you when you get some type of error, you have to see what is the problem. So as you see here, I have here missing S. So it will be after the adding the S should be fine. Okay, we still have the error. Pass does not exist y. Let's check why. So for example, we have here the lips, as you see, we have defined from the top lips and then we forgot the name of the library. So I have to put lips, users and then SRC and then lib, and then users. So after that, it should be fine. So as you see, it's showing you what it's going to happen. It didn't happen yet. It's created a file which is in this path. It's called effect, exactly as I told you, model and also user reducer and then selector and as well some the update on the user's module and index.js. So in that way, I have also multiple options where I can define as well, some specific behavior of this state store. So for example, I can generate FSH. This is for Sayed. It's used for using some functions where I can access the state store and make my code more organized and more beautiful when I want something from the state store as we will see later. So check this as well. It will help us as well as we see here that it's generating some models. And if you remember, we have models already defined in our application. So no need to create as model. So we are going to remove this one after the state stall get created. So now we are ready to run this command. In that way we will be able to use the state store. So name module that pass through the module, the right one, the name of the directory. And here are some options. You can use them or you can dig about them. For example, here you will see that this barrels is going to create for you the import or export the components so you can import them at once. But I want to show you the pure state only what is really needed, for example, here for assayed and also the minimal sum replicated. More comments are here. So you don't need to use them. Route setup, route for feature state management with MDR x. You don't need to do that because we are going to do that manually. It's more safe for keeping our application in the right way. So here, there are many information like for example, skip back a JSON. It's Our going to add the NDR x dependencies to install and DRX library to our node modules. So in that way you can skip it if you have it installed already. But if you don't have it installed, don't check this one. And also the science TX and RX you can define, as you can see in the documentation or as we will see later, two styles of creating the NDR next door. Glasses and creators. For example, here I will show you the action. I'm going to create action. And this action can be created in this way. So something like constant login create action, and this action has some properties. There is also another way by creating a classes, but I prefer the way of creators. It's better and it's going to give you a more dynamic on typings for the TypeScript. So before finishing this video, please review what you have here to have exactly as I have. And then click on Run, and then you will see the file state or the further state got it created here with the test files as well. In that way, we will see in the next lectures, what are actions FX for saids, et cetera, which will help us to create our state store of the user's session in our shop. 171. Diagram Building User Session Process: All right, at the beginning, I would like to explain like a diagram how the process will be when we are going to get the user or build the user session. So as a reminder, the main goal that I want, every component of my application like product detail, pump component, and also check out page component. Get some data from the store which are shared among all the application. So for example, I defined here two variables. One is user. It will contain the user data of the current logged in user. And also it will hold as well, is authenticated, is like, for example, it's a Boolean variable. It can be true or false, which is saying that, okay, Now the shop or the website has authenticated user or not. And based on that, As I told you, we can show, for example, some parts of the application like the product review and as well the user data. It will help me to do a checkout page component and also a grab the data of the current logged in user to my check out for. So how it will be the process, the process actually that we need to action, to do an action as you remember. So some component is firing an action and then it will fire for us to fetch data from the database of the user based on the token and how we talked before. So I will go with the easy process first. For example, we have here a login page, and when I click on Login, I am creating a token which is coming from the database or from the server. And then I will ask the state store to fire for me and action, which is called Build user session. Of course, this is after successful login. So in that way, after I build the user session, I would say to the store, okay, the user is user data, which I get from the database and also is authenticated, is true because I have successful login. So the login itself fired the data or fired this action and change the data in their states. Dog the two variables which I have, which are user and also it authenticated. Also another action can, for example, or another component or another event can change for me, the state store, okay, the user is logged in already. He came back, for example, after two hours, he opened the application again. Now, as you remember, we are reading that token from the local storage to see if this user is authenticated or not. So in that way, I will judge if it's like a valid token, then we are building a new user session, okay, say to the effect and also the reducer, as we will see later in detail, to set that is authenticated to true and also get the data of the user from the database and pass them to the user variable in the States doc. If not, which is possible, like then we have, for example, the token is not valid, then I will say, okay, in it user session to session, or for example, reset the user's session. So resetting a user session is to set, is authenticated to falls and the user data will be null in the store. And who is watching was what's happening in the store. Those components. So not only checkout page or product detail, maybe another component as well in my application. So this is the main idea of NGINX or the states management. Of course, there are many usages. You can also hold all your data state store. But I am specifying here a case where it's really needed the MDR x. So in that way, you learn how to build an action, how to fire it, and then create effect and reducer to change the state of the variable in the state store. And then we will see how we can read all of those variables in the components which I need to build my application to show or hide stuff. I invite you to take a look to this diagram. Again. We save it in your brain. It will help us in the next lectures to build our state store regarding the user and authentication. 172. Init User Session Service: Now let's continue creating our logic, logic for initialization of the user session. We are going to do this logic here. So from loading the app, I'm going to read a token gesture if it's valid. And then I will do with a proper action to set some variables in the state store. So first of all, we need a service which is called init user service. So how we can call this service? We can't call the service actually in our initialization of the application. So going back to the end, you shop the entry point of the application in is in the app component. So we can hear, have in the initialization of the app, we can call a service in IT application session. So for that, I am going to call the user service. So we have here in the constructor as always, how we are calling services in the components. So I will say here a private and then I will say users service. User service will come from users service, which we have defined in the user's library. Then inside this constructor, we are going to initialize the, for example, the application session. But you can as well doing on, in it. So you can have here like on initialization of app component, like our application is going to call the service which is called init app session. So let's have here on in it, implements on in it. So in that way, we need to call something called NG on init function. And this function will be executed when we are going to call the application or when we start our end you shop. So in that way I will say this dot user service, and then I'm going to call the service which I want. So let's go to the user service by clicking control and the mouse click, it will take you directly to the user service. And in the user service, if you remember, we had many services which we created for our users, creating, editing, and adding. So at the end here we can have like some service, we call it any app session. And in this init app session, we go and call something or some action which will come from the state store. So in this way, here we are going to start our initialization of the session in the state stock. Let's see if everything is working fine. So I am going to save this one. So we need also to call it here. So after we have it in it, obsession, okay, We have called it. And then we save, and we save this one. And our application is running without any errors. So let's check the browser. Okay, we have a problem that we have app module, store feature module, but reduce her manager, reducer manager, reduce and manager. This happens because we are creating a state store in a library. So here users is a library, but the application doesn't know anything about this state store. So to initialize the state store in general, we need to create or call some methods in the application module. So in the application and you shop or in the application which you are going to create, you need to init the state store somehow how initialization can be. We need to call two modules. So those two modules will be first one store module. So is this door where it's going to initialize my store. So store module, you have to be sure that it's imported from MDR x library. And then you press dot and then you have four root. And this four root, it will call an empty object. So here we are initializing our store with empty object as well. We are going to use effects, effects. We will know what they are used for later. So we have here affects module. So, and then we can call again for root and we initialize it with empty object or no, we initialize it with empty array. So in that way, we can be able to initialize our store. And let's save and see if the error is gone. Okay, now our application knows that there is a state store. So in that way, I am able to start working with my state store in user's library. 173. Creating Build User Session Action: Okay, Our state store got initialized store module affects module in the application level. Let's see what happened in the user's module because if you remember, we said that it's got updated. So here it says that also it's calling the module itself. The library, like the user's library module is calling the state store. But for feature, because users is featured in the application. So in that way, I am not calling for route, but I am recording a feature. So this from user, users feature D. So you need for feature two parameters, one, that feature name, and then also the reducer. Reducer, which is going to be used in the state store for changing the states and changing the variables inside the state stored. So here we need a name and also the reducer. Reducer come from reducers file. So if you go here to the road users, you will see that we have initialize something with the reducers. Okay, we are going to work with this. We are going to delete some code which is initialized automatically by the plug-in of an ECS console. But first of all, let's create an action. Okay? The action is going to check or build the user session based on some token. And this token will be handled if it's valid or no inside the effects. And in the reducer, I'm going to change the variables based on that. So let's see how this example or this initialization of states door gut calling the action. So if you go to the users for assayed it saying here like it's, of course it's a service. So as you see here, its users for assayed. And this user assayed contains some variables, Let's see later. And also constructor which has a store and then in it, and in this init, it's saying this dot store this badge user's action in it. So there is action in the user's actions, which is called end it. Let's go to the user's action, okay? In the actions of the user, there are actions are initialized with our creation of that state store. So we can create now our own actions. So let's put here some space. Of course we are going to delete those stuff later, but we are going to create our action. So first of all, I need to create the action which is called Build user session. So you would initialize constant and this will be called build user session. And in this way, I will have a create action method which is called from state store. So here, as you see here, create action is imported from stored library and GR x. So in that way, you need to give a name for this action. So the name normally is called in that way, you define the feature name, you can say users, and then you can define what this action is doing. In our case, it's called Build user session. So in that way, we have created our first action. Of course, there are more actions which will come later, like on success or failure, like unchecking the token, repelled or no. So this what we are going to do later. So now, Okay, I will go back to my FSA ID. Let's clean up something here. So let's remove all of this stuff. We don't need them initialized. And also we can remove this comment here, and we can say build user session method. So here we have build user session as well. And it's going to dispatch for me an action from the action which we have created before, which is called Build user session. In that way, I'm dispatching the action. So we need to call this somehow where we are going to call it. We are going to call it in the service which we have created before. So in that way, I will go to the User Service. And then in the constructor, I need to call the FSA ID, if you remember. So here I will say private users for Sayed. And then we will call the user first aid from the state store. So I will say here users facet. So in that way it got imported automatically and I can use it and use the methods inside it. It's a service. It's like we are calling a service inside service. So I would say here, these dots users for assayed. And then I will go build user session in that way, this bill, so user session, it will dispatch an action for me which is called Build user session. And based on that, the action will send notification to the effect to do something, as we will see in the next lecture. Let's save now everything to see if everything is still working fine. We don't have an errors. So we go back to our browser. Okay, we don't have error. The application is still working fine. 174. Creating the UsersState: Okay, Let's do now the store, the store of the users. So in the store, I will have two fields. One is a user which will hold for me the user data like name, address, email, et cetera, and also if authenticated, if the user is authenticated or not. So now we are going to create that state. That states are created in the reducers. So in that it user, we will have some class or interface which will have the fields or the variables which I need to use in my store, like the user, and is authenticated in this way here, as you see, there are some initialization already done. We are going to not use it. I'm going to explain it and created in front of you step-by-step to not have an issue or misunderstanding. So first of all, we can keep all of these imports. We are going to remove what we will not need in the next lectures or in that refactoring. So first, I need to create a state. To create a state, we need to have Export and then we define interface. As you see here, he created already estate, but I will give it a name, user's state, which is better name and more clear to not have a duplicated names dates between the library. If you want to have another state store in another library. So you don't need as well to have here Entity, state or users entity. We will talk about that later in more advanced subjects. So I need to create a pure interface which is called user state. And this user state will have two fields. One is called user. It will have a type, it's called user. The user model, which we have created from user in the model which will contain email, password, etc. So all of those information, they will be in that field. And as well, we are going to create a variable which is called is our authenticated. So in that way, we can know if the user is authenticated or not. So it will have a type boolean. Okay, So for that we can remove this original which is created by the NX console. And now there is interface which is called users partial state. So we just need to replace users partial state. Normally we don't need it for now, but we will need it as well in more advanced subject. But let's have the type of this users feature key, which is called users. And then it will have a user state type. Okay, this adapter we don't need. Now after that we need to have initial state. So the state or the beginning state of my application, normally the user is null at the beginning and also it authenticated is false. So we need to have initial state as well. So I will call here export constant as well. It will be called initial state. So I will have here initial users state to have like more convenient names. And then in this initial user state, it will have a type of user state, and it will be equal to an object. So this object will have a user empty like null at the beginning as we said, and is authenticated will be false at the beginning. So we have initial state like that. So in this way, we created our state. So now we are going to create the reducer, how it will feel the action. So I will say when some action happened like Build session state, I'm going to call something. If there is nothing, then it will not do any thing or any changes on their state store. So I'm going to first remove all of this like we have initial state already. So now we create a reducer. It would be called as well users reducer. It will be the same name of the state store, like always users, users, it's plural. So now we create a reduce it creates reducer method come from DRX states door. So here we have create reducer and it will ask for us initial state. What is our initial state? Is this one? Initial user state? And what is the other or what are the other parameters? Other parameters will be, for example, the reducers types. So let's have more organized code. We can put this down and as well put this here and we will put comma, our first or second parameter will be on. This on is also imported from the reducers or from MDR x. So as you see here, we have here on is imported. So on. Then I will say what action on action, which is from user's actions. As you see here, it's imported star as users action, like import everything from users action and then you can use them. So we have here also load users access, or we have here build user session. And this on method, it will have two parameters. First one is the, for example, the action itself, like what action is going to happen. So I will have here user's action dot build, user session. Okay, What will happen? So here the second parameter, we are going to change the state. So I will have also a callback function which will have as a parameter state. And it will do some stuff for me or changing the state itself. For now. We can only do like a change on the state, like to copy as it is. We are not going to update the state. So I have here also another brackets. So I will say here, just copy the state, so don't do anything to it, just clone it. So in that way, our state didn't change, nothing happened to it. Okay, In that way, we know that our reducer will execute something based on this action and change that state. We will do more changes in the next lecture when we are going to work with the effect. But first, let's remove this code which is not needed because we created it already. So now we have here the function reducer, which is exported and used in the user's module, if you remember. So we have here the state, it will be from the type user's state and, or undefined and the action. And here the user's reducer got created and it's imported and used here. So in this way, our state store is ready from state a viewpoint. So in this way, I can call all the actions which I need and change the state based on that. We are still having some errors in the console. You can ignore them for now because they are in the selectors and we are going to fix them in the next lectures. 175. Create Effective Actions if Token Valid or Not: After having the understanding of actions and also reducer and the state store, I am going to do an update to our diagram. So if you remember, we have created action which is called belt user session. So in this way, we will have two options based on the token. So the token, if it's valid, it will say that, okay, building the user action session is success. And also, if not, it will be failed and it will change there. Or it will order the reducer to do something to the state store, like setting is authenticated to false and the user to null. And the opposite way, it will happen when the token is valid. So the action build user session will fire effect. This effect will validate that token which is stored in our local storage to get the data of the user from the database if it's valid to set with the user data. If not, we are going to set it on null in case there is an error in the API or in the case when there is a token not valid. So in that way, we are going to create two actions which will decide the user session builds successfully or it's not. And the effect is going to call those actions based on the validation of the token. Okay, first, let's create those two actions. And I will have two actions which are already in July. So we can delete this one which is called init because we have build user session. And the same way we are having a great action. And also it will have a name. So I can replace all of this text here. We can say users build user session success, like how we have here. And also we can rename this one so we can, instead of build or allowed users, we can say build user session success and also build user session failed. So we can have here instead of failure. So in this way, we can have the action, okay, what are the properties of this action? So the properties will be the data which are loaded. So we will have the data is authenticated through and the user data is, for example, the user itself, the user object. So in this way, I will be enough of only loading the user data. So in this way, we can have here props or the property which will be called user. And the type of it will be user model, which we have created before. So no need to use all of this user entity here. And as well on failure, it will have as well the same thing, like it will have the same string. And also it will make for me some action based on that. It will load an error or it can load, for example, like some message that the token is not valid or something like that, we will be enough on creating the action only without props just for now. So now I will have 2, three actions. One, build user session, which is this one, it will be called and fire the effect. And the effect will be deciding what is the right action to take when its success, when the token is valid and the user data are ready, or if it's failed and the reducer will behave on specific way, boy, based on those actions. So here we just have to not forget that we have here the failed sentence to not have confusions of the name or naming of their actions. So now we can add more reducers. So in this way we can go here and say that, okay, on user's action Build session state, do something. You can as well do another on. We have here another comma and we say on like users action as well. And we can select on success. So the state will be, or will be updated based on what we income from that action or from that effect. So in that way, we will have this date. It will be updated with a clone of this date. It's very important, this one, and this line is very important. Like we are going to update the state, not going to change the whole state. This is called immutable. You have to track all the actions or order changes on your state store. So as I will show you in the dev tools later, when we create a dev tools, we will see how the state is changing step-by-step on every call of the actions. So now we have the state and I am going to update now my data in that state store. So when you define an object in that way and you put comma here, and you add the fields which are going to be updated in that way you are saying, okay, take the same state, but update only two fields, which are really those one, you can update only one field, for example, user, and then you update the user filled with the user data. How I can get the user data which are passed to this build user session success. I mean, this one, this property which will come from the effect as I told you. So in that way, you can also add a parameter here which is called action. And this action, it will have the fields of that action. So we have here in this case user, so the user be action dot user. And because the session got successes, we can update also is authenticated to be true. So in that way, we will have two fields updated in this state store. But when the action failed or build user session failed, then we are going to make user is null and ethos indicated is false. So we can do the same. Or let's copy this part here. We can say this on, we put comma and we just change the action. So here we will have the built user's session failed. And as well the state action all the same. We just have to update the user to be null because it's failed and that is authenticated will be false. So in this way, we have created the actions based on validation of the token and the impact on the reducers. But we didn't handle this part yet, like this part which is affect and valid token. We didn't work with it yet. So now our state store is updated based on the behavior of those actions. In the next lecture, we are going to handle the effect where it will be decided to take this action or this action. 176. Creating Build Session Effect: Creating an effect. It's a quiet simple. It's always coming with the action. So the action is going to fire the effect. And the effect will decide based on what due to the success or the fact that created structure of MDR X allowed us to have actions are also allow us to have effects. Also the FES aids and also reducers and selectors. We talked about the reducers, also actions and also we talked about the passage, let's move to the users affects dot ds. So in the effect here, it's also using something called Create effect. Create effect is a function which is coming from MDR x library. So because of the changes which we did in the actions here, we lost the init and the default functions which are created before by the NX console. So let's do a clean up here. So as we did before, I'm going to start from scratch. We have here users effect, which is used also in the module of users. So we are going to delete all of this. Now we will create an effect. So the best source for having how to create effects is a documentation of n DRX. So as you see here, we have the inner documentation, something called NDR x effects. And it's showing you here an example of how creating of the effects. There are some explanation about Angular template and also how to use a service for which the movies. And then here he is fetching the movies and then writing effects in their writing effects section, you can see example of creation of that effect. So exactly like the documentation, I am going to have a name for my effect. So the name of our effect is build user session. And always the effects are suffix with the dollar sign, as you see here. So now we can create our effect using the create effect method. The parameter of create effect will be a function which is observing always the actions are going in the application. So for example, I will have here first a callback function, and this callback function will return for me these actions, the pipe. So I am here observing the actions which are running in the application. This is service which is provided by n DRX to observe the actions which are going in the application. So here in the pipe, when I have the action which is called Build user session, then I will do something so forth that you need to say of type, like when that function or when the action has a type of the, for example, the build user session, then we are going to just darken and fetch the data. So if you remember, we have imported user's action here. So I will use it, and I will say user's action dot Build session or build user session in this way, when this is the type, then I am going to do something with it. So you kind of put a comma here to add another pipe, which is concat map or merge map. This is an RTX to us to be able to map, that is bonds from all of this observable to a new type to a new action. So in that way you can have a concat map. And this concat map as well with have also as a parameter, a callback function. And this call back function, we can do inside it what we are going to do for the token. So as the drawing, I am going to check if the token is valid or not. So if you remember, we have created a local storage service, and this local storage service contained for me everything regarding the authentication token. So for that, I'm going to add also another method here with the local storage service, which will be, is valid token. So here we can have is valid talk AND function. And this function will validate for me that token, which is now in the local storage. And then it will return false or true based on the validation and expiration time of the token. So the implementation of this method in local storage, this service we are going to have here first caused token, and I'm going to grab the token from this dot, get token. It's like I'm calling this method to get the token from the local storage. And then I will check if there is token or if there is really token like it's defined, like we have token in the state store or in the local storage, then we are going to check it. So we need to decode it. If you remember, we were doing a decode for that token in the guard. So here I will have token decode and then I will have that the guard or I will copy the method which was in the guard here. If you remember that we were parsing that token to some parts and then we are getting the exploration or also some fields like is admin and also the user ID, if you remember. So now I'm going to copy this part and then go back to the local storage function. And then here we will have, and then we close the bracket. Now we have the token. So now we need to get the x by arranged in time and validate that token. If you remember also, we have in the old guard some way for validation, which was token expired and we were doing some calculation. It will return for me through all false if this, like for example, the token got expired. So I will copy the same method we will do later, some refactoring. So I will have it here as well. It will be a private method. And as well, I am going to say that here, if the token is not expired, then returned for me through, because here I am saying is valid token. So if it's valid, then it were returned for me through. So here I will have if it's not expired, because here token expired, it will return for me true or false. True if it's expired. False if it's not expired. And here I want is not expired like is valid token, so it's not expired. So also to close all the gaps of this function, so we need also to add else. So when there is no token totally, then return for me false, like you don't have a valid token. So we can have here return false, okay, is valid token now can be used in the effect, how we can use it. We can as well import that service. So we can say here local storage service. And then this local storage service, we can call it from exactly how we have it. Here. We have local storage service, and our local storage service will check if the token is expired or not. So I will have here, if this dot local storage service that is valid token, then I will do something which is action for succes. Else I will do or grab the action of fail as we saw in our diagram. So here I have exactly the point where I got here. So we have here, yes, we are going to grab the action of success and build the user session. Otherwise, we have also to grab the action which is failing or there is no token or expired token, and build the empty state, which will be reflecting that we have empty set or there is no user logged in already to our store. In the next lecture, we are going to build or to see how we can do those steps. As I mentioned before. 177. Calling Action on Invalid Token: So the behavior here that when it's invalid token, we are going to call this action. So in that way, I'm going to do the easy one here. It's harder a little bit because we are a need to grab some data from the database using our APIs. So I will do first the easy part. So now in the else, when the token is not valid, Let's call an action. Calling an action in the effect. It will be in the way like return off, like off will be imported from RX JS. It will return for me and observable off some action. So in this way, I can say user's actions dot and then build user session fail, but you have to call it as a function. So this is the important thing to notice, to not miss that. So here we didn't call it as a function because it's a type. So we are asking for the type of this action, but here we are going to execute this action. And this action is not executed like when the token is invalid, then we are going to have in our reducer some behavior. And this behavior will be setting the user to null and is authenticated to false. So in that way, the components will notice that who are observing those variables or those fields, then they will know that the user is null and is authenticated is false. So don't show something or hide something from the global user. So now the part, if we are going to have here, like if there are valid token, then we need to check or grab the data of the user and then add them to another reducer and call the action, which is Session successes, which will have the data of the action, which will be user and add to the variable of the state, store the user and the user object and is authenticated will be true. So from where I will get this user data, the user data will come from the service, the service which we have created before, which is called Git user. And we need for that, the user ID. So that's why in the back-end, we stored also in the token, the user ID. So we have expired ration, we have is admin or not, and also we have the user ID. So as I suggest, we can create also a function which is called Get User ID from the token. Why we need that? Because I am going to call in the effect the user service. So here as well, we are also in need for getting the user service. I will have here private and then users service. And this here users service type. So we have here the user service, so we can use it now. But first, after that. So this dot user service, dot get user is in need for user ID. So here I need to define a user ID which is constant, and we can call it user ID like this. And we will call this dot local storage service. And then I will have a function which is good, saying Get User ID from token for example. In this way, we will have the user ID from the token. Let's do this function. So I will copy this part to have the same naming, and then I will have that dopamine here or the function here. It will be exactly the same. We are going to decode and do the same thing. And we are not going to get the expiration, but we will get the user ID, which was stored with the token. So exactly the same. I will have here token getToken and then I will check that token. I will decode it. First of all, I will have to return the token dot user ID. So in this way we can delete this part. And I will say token decode and then user ID because I know and I am sure that there is user ID in this token after decoding it, else, return for me null. So when there is no token, then returned for me null. So in that way, we will get the user ID from the token to be more safe, like to not have an errors or problems in case there is no user ID, then we can have also if here. So I can add here, if token decode, like I have here some token, but for example, it's not possible to split it. So this way, token decode, we'll get undefined. So in that way, I can have if, OK, and the code, like if I get really a token decode, then returned for me, that token decode that user ID. Else, return for me as well, null. So in this way, we are covering all the possibilities can happen regarding the user ID from the token. So here I am getting the user ID from the Docker. Now we are able to use this user ID inside that service. But also it's better here because we have possibility that User ID can be null, so it's better to have if here as well. So if there is user ID, then we are going to return as well, the service data return and action. So this will be like this. So I will have return. I want to return off this action or of success action, but I need to call the service. So in the service, when I call the service, I can add also a pipe and map it to another type, which will be a build user session success. So to explain that, I can have here this dot user service that getUser and then I pass the user ID I want here. So we are still giving error, getting error because are the types are not matching together. So we need to manage this type to be exactly the same of the types of actions. Because Create effect, expect for me. Actions not, for example, like observable of data. So in that way, we will have here as well pipe. So we need to map this data to a new type. So the map should come from our x js as you see here. So here we will have a map. And then this map, we would get the user data from it. And this mapping, or we are going to return like not for example, the user data itself, but action, action of success. So we can have here return after the mapping user's action and then build user session succes. But this user session success need a prompts and those probes are users. So in that way, I will have here, this prompts will be the user. So the user will be the user data, which I got here. So in that way, I am saying when there is a valid token, then find for me the user ID from that token. And then if their user ID is valid, then grab for me the user data from the backend, and then change the return data to be as an action of build user section or session success using the user data. So in this way, I am saying that fire for me this action. And going to the reducer of this action, we will notice that I am getting in the action from the action, the user data and put them in the user field, in the state store and also is authenticated. I am making it as a true. So in that way, I have created the effect. But now we are missing some points. I told you always when we have apes, always cover all possibilities, okay? If I don't hear have valid token, then returned for me action, okay, session failed. Here for example, if there is error with the API. So when I'm grabbing the user data from the user service and there is an error. How we can send, for example, the build user session failed. Here, you can add the comma after the mapping inside the pipe method. So in that way, you can say catch error. And this catch error will have for you an error or a callback function where you carry turn exactly the same here. So you can as well return of users action belt session failed. So this will be called when there is a failure in the API and then it will initialize decision and is authenticated will be false. But also a year we have an if, if there is no user ID, we need also to catch it. So we have as well to add here else for the user ID. So if there is no token valid and else, if there is no user ID and else failed, if there is user ID, then do your job, grab that data and field for me the state store, as we see here in the reducer and as we discussed it before. So now we finished also this part. So we have now action when it's failed and also action when it's success. We loaded the states told using the reducer with the data and the data is out of the store, is getting updated always based on all of this date. Now we need somehow to read all of those variables in components. For example, I'm going to read it in the check out page and fill the form of check out data and say that the form will be filled automatically when I log in to the checkout page. So I don't have to feel my data like my name, e-mail, address, etc. 178. Observe StateStore Fields Using Selectors: So now we are going to grab a data to our components. So I want my components to see the data of the state store. But first we need to create selectors. Selectors are actually for grabbing the data from the state store. So if you remember that our structure is created for us, a user's selector. And in this user selectors, we are getting an error here because it's, we changed the types, we changed the actions. So I am going to remove everything from here, which is automatically created, and also remove all of those errors which are defined in the import and start from scratch. But I will keep this part is look up the user feature state managed by NGINX. So here it's like I am getting the user state. I am getting all the store here. So with this store, I can do some stuff. So I can select the user data and also the user authenticated or is authenticated or no. So here we have just one error is a state, we need to replace it with users state. If you remember, we have created user states in the reducer. So we have here import user state from there you do reducer. So this constant is getting the user state is using create feature selector. So select for me the whole user state using the users feature key, which is called users. Because here, our application, if we create another library or in another state store, for example, your products, we need to differentiate between those all of those states doors which I have here. So the users feature key or the state name which is used in users module, which is this one for feature is called for feature I call Users feature Qj is called users should be different from library to library, or from library, or from feature to feature. So here I'm going to create also a selector. I know that you don't understand what a selector, but soon you will see the usage of it and you will understand it. So I would create here a constant, I will call it Get User. So from the state store, Just give me the user field. So here I will call something which is called creates a lector, and this creates a vector is from MDR x. And then I will use getUser state here. And then I will say from that state, which I have got here, then I can use it to return some specific fields from it. So I will say here from that state, then returned for me, state dot user. So the user or the user filled inside that states door where it will be with data or it will be null based on the decision here, then I can get the user data exactly the same thing we can do also for authenticated. So we can create another constant which will be also selector. So we can say get user is authenticated. For example, all is ours to be shorter. So creates an elector is ours will be also getting from user state. And then I will use exactly the same here. But instead of user field, I will use is authenticated field. So here I am getting is authenticated. Okay, I created this electron, everything fine. Now what I can do with it, how we can use those selectors. If you remember, I told you that we have the facade is for making and beautifying our code more. We will not have a big calls in the components. We can have only short calls when I want to call the get user or when I want to have the user data from the state store. So let's go to the usaid. And here we can create something which is called like observable, we can say. And this observable will be a variable from user for assayed. And it will have current, for example, we can give it a current user. So this is a name and it would be observable as i, they'll do that. Observables variables are always suffixes with dollar sign. And here we have this dots door. And then took pipe here how we can call a selector. So if you remember, here we are calling an action. Now we can call here a selector. So I will say this dot stored the pipe, and then I will say select users, selectors, user selected, what is it? It's here. It's import everything for me from users selectors. So important for me, everything, what is exported here. So exports for me this, this and this. So now we have in the facet, export or selects for me user selector, which will be, for example, getUser. And also we will create another one or another variable which will be called is authenticated. And this is authenticated, it will be also observable because this pipe will return for me observable and select for me a specific data from the store. So I would say here store dot py pz as well, and then select, and then user selectors. And then I will select Git, user is out. So in that way, I have here two variables in the user's usaid. I can use them and pipe data from the store and observe those data which are stored in the state store. We don't need this import so we can remove it. So in the next lecture, I am going to show you how we can also call all of those observables. So we will move to the component level, for example, in product, and we will call the user service and call, for example, this get current user. So current user, it will fetch the data of the user from the state store if it's authenticated or not. 179. Auto Fill Checkout Page Based on Logged User: Okay, now we have those two variables or two fields from the state stored which are observing for me the current user, and if the user is authenticated or not. I just want to mention again that we did this part. So loading the app from beginning, we assume that we have a local storage token already. So we have locked in before somehow and we have the token already in their state store and we are checking if it's valid or not. We didn't do this part. And this part will come later after this lecture or this sum of lectures after we finish completely this part and observe or fill the checkout page based on the logged on and logged in user. So now we have those variables. We can then use users for Sayed directly in any component in our library, for example, in orders. Or we can as well call them or call that through the services. Because we said that the libraries are communicating between each other through the services of those libraries. So we can have here as well some service which we can be called observe, get into user. So I can add here a service as well, which would be observed, or it can have its small letter observe current user. So here we have a current user. We assume that we locked in and we have the current user. So this way, I will call that fast Sayed, which is users for Sayed. So with the users for Sayed, it will have two fields. One of them is current user. So in this way we can return this. So this one will return for me and observable. And these observable will contain the current user. And we can also create or is current user authenticated? Is current user authenticated? And in this way, we can also call or return that observable, which would be these, the user first aid though, is authenticated. So in that way we can go again to our orders library or to the check out page or checkout component page. And we have here in the checkout page, we can call User Service. We have called it already. So now, based on that, we can get the data of their current user and feel that check out form. We can add here a method which can be this dot auto Feel user. That. So in this way, we can have the user data already filled in the form when we do a checkout. So I mean, here in this page, when I go here to the guard and then click on Checkout, I will have here my data based on my token after I login. Because if you remember, we have activated the logged in here. So we need to log in and then we will have here this page or access to this page. So let's go here again and say private. We define a method and we call it autofill user data. And this autofill user data with gold for me, this dot observe current user. So we need to observe the current user state. We can see if he is logged in or not. And then we can get also the user data. We don't have to check here if the user is logged in or not because this page is already protected by the route, if you remember. But we will talk about observing the user is logged in when we do hear the product review. But here it's already protected. So you don't have to check if the user is authenticated or not. You just need to get the user or current user data. So observe current user data. I will subscribe to it. We can instead having gleich this pipe and take until and all of this stuff. You can't add also one pipe which is called take, and it will be take one. And you can take only one value from the state store. Like you don't have to take the value always, always, always, and observe it. No, you just take one and automatically their subscription, as we talked before, it will be finished. So in that way, you will not have any memory leak. So here I have a pipe, take one, okay, subscribe, and then I will have user. So here this user will return for me the user data. So if we check here that type, as you see, it will be type user. So we need as well to return, It's a callback function. And we will notice that this parameter has user, user type. I save its auto formatted. I open these brackets again, and then we are going to fill the form. So how we were failing the forum before, we were just going field by field. So I will say here, this, the checkout form dot seti dot set value. So in this way, I will have here this though, checkout form dot, for example, name. It will be dot set value, if you remember. And then I will set the value from user dot name. So in that case, we will have the username automatically in the checkout. So let's go again and try that. So I will go here again, check out. And we will notice that we didn't get anything. Okay, let's check the console why we don't have any data and I'm sure we have some error. Okay, nice. There is some error here already. We need to check it. So this error saying that failed to load a resource, the serverless bond with status for 01, unauthorized for the API getting user. So we are really getting the user, but we are unauthorized. Why? Because if you remember, we didn't do any interception, any HTTP interception for our application in a candy shop. We did it only for the admin. If you remember, we have here in the application module, we provided with something called provide http interceptor, and then we called JWT interceptor and multi is true. So in this way, we can load every HTTP request with our token. In this way, the server will authorize us to use that API. So now we have here in the admin, but we don't have it in the end you shop. So I will go here to the application, to the module, and then to their providers. And then I would use here that provide http interceptor control dot to Auto Import. And also I have here JWT interceptor from Blue Bits user, and then we will have it already here. Okay, Let's go now again to our homepage. And then let's save again. Let's remove this breakpoint. And then we will go and check out. We will notice that we have now the name filled already in that field. So to continue here, you can also feel all of this data based on user data or locked in user. So now I will go again and I will fill all of this set of value username. So it's better as well here to check if we have user to avoid of having error. Sometimes we will not have a user if you remember, and it will return for me null because the state store said the user can be null. So in this way we can have if here is better. So we can say here this DO check out form. And then, and we will go on over all of those fields. So I will go quickly on them. Of course, you can feel them by yourself as well and finish this lecture with filling the form data. So here I feel all the data acquired by the user in their checkout page. So when I go again here, as you see, that we have all the information. So now we have here home and I go to the checkout. So let's remove this part and then I will click on Checkout. And I will see that my data automatically filled in that every field I have here. And also I can place an order. But still now, if you remember that placing the order is based on the user Guest ID, Mao, we are going to have the user ID which is locked in. So you will do that and do many refactoring in the next lectures. 180. Refactoring + Place Order with Current User: Okay, in this lecture, let's fix some bugs and also locate an order based on the logged in user. So first of all, I am going to have a bug here, which is I, as I told you, it's take one. So here we have the Q1 and when you save the page and the application gets reloaded in that check out page, then you will see that there are no data. This is because that when you are taking only one, maybe this user is null. And we have here, if the user is null, then we are not able to set the values of the user to the form. So the better way when you are subscribing from state store, always to take until they until the subscription finish or when the component got destroyed. So exactly how we did previously in the course, we are creating an, a variable which is called end subscriptions, or we can call it unsubscribe. So here I will have an unsubscribe and this will have a subject of any, and it will have a new subject. So we can have the type, sorry, here we have a type and also it will be a new subject. So in that way, I can define my new subject and I can initialize it, then finish it when this component got destroyed. So here on destroy, I can call this unsubscribe. It will be like next and then complete. So when the component got destroyed, this subscription will be done. So here we will have this and then conflict. And don't forget always when you are using NDI on destroy to implement also the component with destroy. So we will have here on in it and also onDestroy as we saw before. So now we have to finish this cup subscription, take until this subscribe. So in that way, our subscription will work. And when I refresh the page, I will see that my data are still there. So here I have one problem. I must replace this with email. And we will have all the data are fine and coming from the database. Okay, now let's do another refactoring, which is exactly to place the order based on the user ID, which who is logged in. So instead of this user ID, I can make it without anything. Like we can say it's only a string. And then we can say, after we get the user, this user ID is the user dot ID, which is coming from the database. So in that way, we will have the ID in the right way. And when I am placing the order, I will see the order in the backend based on the logged in user. Let's run the Admin application to see if our orders are really going to the back-end to test that. So I am opening a new port to open the application on the same time. So we will have opening the front end and the admin panel or the shop and the admin panel, the same time. Okay, it's running successfully. We can go for example, to this and we say local host. And we put the port which I have specified in the NX or in the comment. So you will have here the Admin application running. But as you see here, we are getting the same error which we got when we were creating the state store. So also we need to initialize the Admin application for their state store. So we need to copy both of those lines store module and also affect module to run the Admin application successfully without any problem. So now I will go here and then I will get the imports. And in the import after the HTTP client, we say, okay, stored module, Auto Import and also affects module will be Auto Import and save and our application should run normally. So now we have the login page without any problem, I am going to login and then click Submit. And we will have our obligation or our backend running. I will go to the orders. I have here, the orders. So let's try to place an order in the front end or in the shop. So a year I have placed an order already. I'm going to click on Place Order. Okay. My order that successfully added and I have here button to back to the shop. Let's go to the admin panel and go again to orders. And we will see that the orders or the order which I have placed is here. So and also it's going with my name because I locked with my name as a user. And it's come successfully here. And I can also view it and see all the details about the order. So I would like to advise you always do check this graph or this graph, how we have built all the state store process to grab data from the state store and also use them in our components. 181. Stripe Payment Gateway: In this section, we are going to add the payment method for the user after he is checking out. So after I do a check out, I am asked for email and password to log in. And then after that, when I check out or place an order, I must have a payment gateway so I can pay and then I can place my order and then the shop will handle it and deliver my product to me. So on this page when I am clicking on place order, I'm not going to place the order directly. I am going to be redirected to some payment page. This payment page will decide if I place the order or not. But how we can add that page. We are not going to create a component which is done by Angular. So if you remember, we were creating a component for the page and then we are adding some fields for the card payment and then we are placing the order. No. Now, in this way, we are going to add some different gateway which will come as well with the form and everything regarding entering the cart data. So for that, we need a payment gateway. And this payment gateway, I would suggest to you to use something called stripe. Stripe.com has ability to provide you with an API where you can place an order and pay for yourself or to your shop for people they can place or those in your shop. And also it will have ability that you track the payments on not only in your shop, but also in some dashboard which is created by stripe. So first of all, you need to register. So I have here like sign in, but you need to register first. So registration is by clicking here on sign up as you see here. And then when you click on it, you will have some information. So you have to fill your e-mail, full name and country and password. And of course, there will be further information about what is your business and how you are aware as your address and how you are locating or what are the products of your shop that you want to align the stripe gateway with your shop. Of course all of it, It's simple information. You don't have to get so much time when registering. It's just like email, full name, and some information about your business that you can fill them easily. After that, you can log in and you will have like some dashboard. Of course, there is also some authentication. You need to provide your phone number so they can send you some code. It's for more security. So I got the code on my phone, so I am going to put it. And then I am getting to be logged in to my account. So after that, we have like the way to dashboard. And in the dashboard you can know how are you handling the payments of your shop. So for example, I have some payment done before and I have some, for example, payment which can be, for example, live and payments which can be with test, with test mode, which you are we going to work with. This one, you just need to turn on the test mode. Test mode, as you see, I have here some payments so I can place, There's as much as I can to deploy my application or develop my application and work with the stripe. So make sure that you have the test mode turned on. And we are going to continue in the next lecture how we connect using the API. And also we are going to create like for example, the Developer Tools, which is like for creating the API keys, as we will see later. Also, don't forget to go to the documentation of stripe. So you can't write Stripe developer docs. And in the documentation you will see the information which I am going to talk about in the next lectures. I'm going to attach all of those links in this lecture. 182. Installing Required Libraries: The documentation of stripes support all programming languages which we need for our payment gateway. To get started with the documentation we can click on Get Started. And here we have multiple operations for payments. One of them which we are going to do is accept online payments because there are also some subscription invoicing and tax handling which we will not cover in this course. We need just to do accept online payment or one payment. So if you click on Accept online payment, you will have a full example how to implement the payment or application. For here we have HTML react, and Next JS as a front end and also fall back end. All programming languages include node. So the problem here that we don't have an example for Angular. So if the programming language of the front end is not listed here, you can click here, don't code, get help from our partners. So when you click on it, you will have some recommendation from stripe, which is called SGX stripe. And you extract is a library. We can use it with Angular to build the payment gateway in the front end. So as you see here, if you type Angular and then you will see this NC stripe. It's sort of commended by Stripe website. So we can get started with this NC stripe by get started here. And then it would get us to the Git repository of MDX stripe. But for better documentation view, you can see also docs site. So there is documentation for MDX stripe, which I am also going to add that the link with this lecture. So when we click on docs and then you will see this introduction. We will see how to install the library, and then we are going to use the services of this library. So let's start first to install the library and gx tribe and also the stripe, which is originally from stripe. So I will copy this code and then I will go to our project. We will open a new terminal, which I have already. So we can have here, note it's all back and we can open a new one. We select a bash, and then it will open for us a new terminal. Of course, you can use any terminal you want. But for me I use, for example, zed as H or Bash. We based the comment here. And if you notice there is dollar sign at the beginning, you just need to remove it. And then we are going to install to library NC stripe and the stripe JS. So when you press enter, it will be added to the libraries or to the backend JSON, where we have installing or adding our libraries for development. So if we check here our dependencies, we will see that we have two libraries. One of them is stripe and the other one is SGX stripe. So there is also a documentation for this library we can use to build our payment. I'm going in this course with the simplest one. Of course that there are multiple option weekend do. But I will choose the one which is exactly for our shop. 183. Checkout Payment Flow: It's better always to explain the flow, how we are going to implement the payment. So when I am going to code now, you can understand what I am doing. First of all, as you see in this diagram, that the user is going to click on the button, which is called Place Order has, we have it in the front end. And then we are going to create something called Create check out session. And this request is going to be handled in the backend after we are sending the order items to the back end. And based on that, this is going to calculate the total price of the order. And then it's going to create something called session ID. And this session ID is coming from sprite API, which we are going to use in the back-end. And after we create the session ID, we are going to redirect the user to a successful page, like a thank you page or to a fail page. Like we couldn't create the session ID because for example, internet connection or he has some network issue. But now we are assuming that we are going to create a session ID success. So we are going to send that they direct info to the user in the front end. And the front end application will read direct to the payment page. The payment page would be provided by stripe. It will have some specific form so you can put your card number and then some, another detail which we are going to see. And we will use some test card data, so we will not use real payment. We will use some desk guard, as we will see later. And then after handling the payment through the front and after redirecting to API or to the payment page from Stripe, we are going to have redirection to assign Q page which we have created before or to a failure page. So when we read directed to the Thank You page, we will create a success message and we recreate the order with a pending status. But when it's created as or if there is failure in the payment, then we will redirect the user to a failed page and we will create the order as a failed status. So we need to keep the track of every order which is created, if it's access or if it's failed. So the customer or the user or the owner of the e-shop can know what are the problems can happens in his ego. 184. Creating Checkout Session API: Let's implement now this diagram with coding. So first of all, we click on place holder, which we implemented already in the front end. And then we are going to create a check-out session. But the tick out session required some API, which is called Create check out session API. And we are going to send the order items to that API. So going back to the back-end application which we created before with NodeJS, I will go to the Orders page. And then in the orders routers, if you remember, we have created multiple APIs and one of them, this one, which is boasting and order. But now we need before posting and order, we need to ask for a check-out session. So for that, we need to have a router as well. And this router will have a post request. And we would call this API as a check-out session or create check out session. So in that way, we will have the API ready with a request and the response as we did always with our APIs. So I will have here request and then a response. And based on that, we have returned the callback which we are going to use. So the Create Session check out, as you see, we said that we are going to send the order items. So I will create here a constant call it order items. And this order items, we are going to receive them from the request dot body. So in that way, we will be able to handle the order items and get the product ID and build our session. There is example on the documentation, how we are growing to create a payment for that, we need to install first a library which is called Stripe. And we are going to use this strive to create our session token. So I will open here a new terminal. I am going to install stripe. So I'm going to have NPM install stripe. That's it. So this is dry. We are going to use it in our API here to generate the session. So I will define here a constant which is called Stripe. And this drive, it's going to require the stripe which we have installed before. So you have to make sure that you have stripe install in your libraries, as you see here, we have it already. And for that, we need to provide the key, that test key which we have created before. I showed you that how we get the key. But I again, I can show it for you. So we go again to our dashboard, how we were creating our payments and how we created a Stripe account. If you go to developers, you will get here something called API keys. And this here you will have publishable key where you can use for, for example, using or creating a payments in your application. In our case, in creating the API, we don't need the publishable key, but we need that secret key. So you have to make a reveal secret key and then you copy it. And you have to make sure that you are in the test mode. And again, you go to the code and after require stripe, you place another call which will hold the key itself. So we have here our test key. Please try to use your own key to not try to use the same one. So you can have results in your account. So I have here that Stripe account, I have here the key. And then I'm going to create the session. How we can create the session. So if you remember, we have created the order. So now we can use a striped library to create our session. So I will define here a constant in our API. I will call it as session. And this session will have a weight function like we are going to wait until we get some response from Stripe dot check out. Exactly like this. It's called strive to check out. And then you have to say sessions with S. And then you have to say Create. And with this Create, it's a method where you can pass an object and this object will have some specific parameters. So we have first to define that we have something called payment method types. And then we have to say that types of payment. Now we are going to use the guard like MasterCard or Visa card. Again, we need to have the line items, but line items must be formatted in a specific way. We can say like we can define our own line items. So we can define here, we can say cost line items. And as we will see later, I will show you how we are going to define it. So I would use here line items, array. We need to pass add weld some option which is called mode. And the mode is payment. So we can say to create a session of payment. And then we have something called success URL. So why we have this success URL? I will explain that later. But for now, we can put the URL localhost and then 4200. The 4200 port is used in our angular application in the front end. So if you have a different port, then you have to use it. But for me, I'm going to use the 4200 for my front end application as you see here. So after the payment, I will get to read directed to application again, which is, for example, pass, I say success, which is our thank you page, if you remember. And then we have something called cancel URL. And with this cancel URL, you will be able to redirect the user to a failure page if he is not able to pay. So we can have instead of this, we can have like some page, we can call it, for example, error. So we can create this page in the front end. And after that we have the session here. We are going to send back to the user, to the front end, as we saw in our diagram, that I will send the session ID and read direct NFO. So in this way, I have to send back to the front end session ID so I can redirect To session or payment page or the page where we I am going to put my card data. So I would say here, Let's bonds that JSON and then we will put as ID. We can put session, which we got here, dot ID. So in that way, because this session or this check-out session would return for me as Asian and it has a member which is called ID. I can get then the session ID. Now we have one issue left, which is the line items. Now the line items must be mapped in a specific way. So if we go to the documentation of Stripe and see, for example, accept a payment example which is striped documentation. We will see in the Node.JS, there is like some example we can use. And this example, as you remember, we have put payment method types and there is line items. Line items is array, which have a specific array of objects. And this object has Bryce data, currency, and product data, et cetera. So we put all of this information, but we didn't create this one. So for that, we need to build this array of that object where it has price data, currency, product data, and then unit amount. If you remember, we have a line item or order item which has only product ID, and then we have as well the quantity. So in that way, we need to create as well this object in that way, it's something like mapping. Again, we will read map, the other item to have this shape. So exactly how we did before with the posting and older, if you remember, we read the order items, we looped over them. Then we got the product detail after that to get the price of every product and the name of it, and then to calculate the total price. But here we are going to do it again, but in the front, like for example, in different way. So first of all, I am going to check if I am really getting an order items from the front end. So if there is no order items from the front and then sent directly and error, I will say here return a response and then status we can say, and it will be 400. And then we send like an error, for example, to the user. Check out session cannot be created, check the order items. So we can, in this way have some error message in the console for us. After that, we are going to check if there is really order items. We will loop over them and map line items based on what we saw on the documentation. So exactly as we did before with the order items we were creating like or looping over them to get the product detail because we need the product detail like the name. And also we have the unit amount, which is the price. So in that way we need to have a detail of the product. And for that, if you remember, we were looping but creating a promise, all we will get an array of products or line items which are passed through the order ID or the order items. So I will go here and then again loop to order item. So we will say u, that line items will have, promise that all again, if you remember, I explained all of those steps. So promise that all handled for me the order items where I can return multiple order items or multiple products by looping on order items. So he always say, or their item dot map. And then we will return or really shape this array. Which has only product ID and the quantity to another shape which will have the shape which is defined in our array or in the documentation of Stripe. So at the end we will have return of that object as an array. So first of all, we need to have map. And if you remember, because we are getting the data of our products from the database, we need to put async, so we need to wait sometimes for every product to come and then we can continue our loop or our mapping if I have multiple order items. So after that, we have the order items sheet here should be ordered item like one, because I am looping now one by one. And I will define here a product. And this product will have, will hold the data of the product detail where we are going to get the order items. So caused product away. And then we will use the product model if you have it, like if you import it. So the product model must be used. As you see here, we don't have product model, we need to import it. So after order items, I will have here like cost, import for me, product model. And then we will say require from the models where we defined our product model, if you remember before in the backend session. So we can now use the product model. So I will say here product dot, and then we will say find by ID because we are going to get the order or the product by ID. And then here, the ID which is passed is coming from the front end or other items, dot ID or dot-product. If you remember, we have mapped the front end to say that the other items contain the product and also the quantity that product will hold, the product ID. Okay, The goal of the mapping now to reshape the order items array to another shape which we'll call line items. So here I will have a return. So I will return and U-shape, which will be this one exactly. So we can copy it and go again to our code. And we say return for me object, which is called price data. Currency is dollar and product data. The name will be not the shirt, but it will be the product ID or the product name. If you remember, we were calling the product and it has field called name. And as well, the unit amount here is 2 thousand or it's calculated by sense. So you need to have also that sense, surprise. So we can have here product dot price and multiplied by 100 because every $1 is $0.100. And the quantity in that case will be that quantity which is coming by the order item. So I will have here order item, item, not Items and here also item or items to avoid the issue. So here we will have something called a quantity. So after that, we can pass laws line items as well to these line items because now we have a new shape of that array. But here you have to remember always, I made it by bought bows to not forget, await, because await here we are returning a promise. So we need to wait until all of this finish and we will get the line items because here we have a product which is coming from the database and it has a weight as well. So let's go back to our terminal to see if we have some issues. As you see here, we have some problem. It says invalid, short head property intializer. So we have here some issue with the name. So we need to have here not equal but colon, so in that way, okay, We don't have any issue and the database connection is ready. And we can now call this API, which is called creates a check-out session to get the check-out session from the back end. 185. Creating Frontend Checkout Session Service: Let's go back now to the front and the front end where we are handling our orders. So we are going to place an order and be redirected to a payment paid, as we explained in the diagram before. So first of all, we need to create a service which is requesting the check-out session token. So for that, we are not going to place an order when I click on Place Order. But I'm going to call a service where it will give me back the session ID so I can really direct the user to the payment first. And then based on the payment, if it's success or not, I created the order based on the status if it's bending or it's failed. So first of all, if we go again to our libraries, we had created an order is library. And in the orders library we have a services and we have special service for cards and we have also for the orders. So in the order service, I'm going to create a service where it will also read direct me to the payment page after getting the session ID. Do that, we can do a Create. For example, we can give a new method name. We can call it a check out creating out session. And in that way, the check-out session will ask for order items. Order items, because we need to send them to the backend, as we saw before to calculate that all the price and also the detail of the pavement. So we have here or the items array, it would be sent to the service, and then it will return an HTTP request, exactly how we did before with the other services, like as you see here on the top. And the request will be post request. So we will post a request data. And where do we have same URL which we have based it before of the orders. And then some path which we have specified previously, like create check-out session of the API. So we have here create check out session. This is our API, how we defined in the back and before. And the send data with the post request will be the order items which we passed in the function. So we can have here or the items that we are parsing them here. So let's save and see if this arrow is, is really creating for me session ID and we don't have any problem in the back-end. Let's try and test that. I will go first to see if we have some errors. Sometimes you have like the order item model get imported as a relative path. But, or for example, the earliest path, as we saw with any x. But it's better if we are in the same library to use a relative path is. So I use here, I am going to change it to be like this models and order item. Like I am reaching the file order item used the relative bus. Now I want, when I click on Place Order button, I will get a session ID. We can use it like to put it in the console log for now. So it will be the work in the checkout page, checkout page component where I am creating or placing the order. So place order function, which will be executed when I'm clicking on that button as we saw before, which how we created. So now I am going to have placed the order. And then placing the order will not be creating an order, but it will call the service, which is Create check out session. So instead of this, we can comment out this for now. Just for now, and then we are going back to it when we will need it. So I would say year this order service and then I would get created out session and we will pass the order items. So we can say here, this the order items because we have collected them from the local storage as you see here before. So now after that I'm creating the local storage or the, sorry, the joke out session or calling that service. I will get a session and we can print it in the log. So I will say here, console log directly and we would check out or print this session. So let's save that and go again to our application. And then we will open the console. So now I am going to try to place an order. So let's say OK, place order. I'm not getting anything in the console. So let's check the Network tab where we are sending requests from the our application. So as you see here, there is a request send, but it has no content. So it came back without any content. So that's sure. We have, for example, that in the back end, some error. Let's check again our back-end code. So I will go here and check the back end. We will see that console of the backend that we have an error, as I told you, it says a year that receive unknown parameter cancel URL. So I have here a typo. That's why I want you to always to be sure to have the typos, right? So it will not, do not have any typos in their code. So here I have to put, not cancel like this. I have to put it like this. We save again. We check if our application is running. So it's restarting due to changes. Okay, Database connection is ready. So now I will try to place an order again. So let's refresh and then remove all the console. And again put the Console tab and then we place it. Okay, We have a request and if we check the preview, nice, I have the session ID. So as you see here, I get an ID, which is a session ID which I sent from the backend. And we have now the session ID. Now we need to redirect the user to the payment page. To do that, we have multiple ways to do it. First, we need to use a stripe service, something called Stripe service. So first of all, we need to go to the constructor here and import stripe service from Stripe. So I will say here private stripe service. And then it will be called Stripe service. And this stripe service will be imported from nx dry. Because if you remember, we have installed nx stripe library. So I am going to use it here. So I will say Import and then Stripe service, exactly how I have it here typed. And then from we would call it the library, which is called SGX stripe, which we installed before. Okay, now we are able to use the stripes service, okay, So after I am getting the session or the session ID, then I can use that token or that session ID to redirect the user to the payment page. So simply, I have to do here this stripe service and then read direct to check out. Then I have to use an object session ID, like this is session ID. It's already defined as you've seen here. And this session ID will come from this session which I have created. And I got inside it an ID, because if you remember, we have an object and inside it ID. So I have it exactly the same way. Session dot ID. If you get error here, this is because of the Taipings. So its better always to refine or define your typings based on what the service are you using? For example, create checkout page, if you remember, we have used it to return some data. And those data we can say that it's going to return for me type any. So I can say here, the post request will have a session and this session will have type any. So we can put it as well, like observable here because it's going to return for me observable from type any. So in that way, I will not have that error where it's not returning because this session is unknown for me. Or you can type it. So you can say I need to have like the type return type will be ID, which will have type string. So in that way, if you go again here, you will see that the error is this appeared and you have a defined because you have the ID already defined. And also here you need to fix some problem, which is the expected type, which is returned by the request. So I will say year, the return type will be object, which has ID and the string, because here I have ID and a string. So those typing scripts, they are in or like, for example, tricks, you have to do them using TypeScript. So you have to make sure always that you have a typing valid. You don't have any mistakes or mistyping between the functions and services. So after that, we need to subscribe to this redirect to check out. So I have to say here, subscribe as well, and then I need to find UC as you see it. It's returning for me stripe error, this error. I'm going to subscribe to it and check if I get an error when the user is not able to pay or if they user is not able to reach the payment page due to, for example, network or connection, internet connection error. But as you see here, it's very bad to have Subscribe inside subscribe, like nesting subscribe in general. Our x js and also in Angular is very bad behavior, so forth that we can do another way that we can call this services after returning a specific type of this create check-out session, like we change the output of this session and then we can use it again in a different way. So I'm going here to the order service. I'm going okay to have all of this return. I have HTTP post request. Let's remove this typings for now that it turned die peaks. We don't need them. As I explained to you, we need directly to go and change the return type from this post. You know, it's returning for me the session and inside it ID. But now I want to do something before I subscribe to it, how we can do that. So if you know that there is something called pipe, and this pipe is like a pipe where you are changing the return data from an observable or from a service. So for example, we have returned here a session and Session.get IID. But no, I want to do something else before I return this session ID, of course, using that session ID. So I will go here and pipe. I would say, okay, change for me the return value somehow or before a machining it to the user or to the subscriber, change it and then send it to the subscriber. So I would say here something called a switch map. And this switch map, it mean like I am going to switch that, that how it's looked like, which return to another shape. It's exactly like map. We are doing with the array, like we are having an array. We map over it to change that array somehow to another data entries to change the, the shape of it. So this switch map is imported from our x js. So you have to make sure that you have this switch map imported from our x j as operators, as you see here. So now I'm going to change that. Like the output of the subscription, like I have getting the session ID. So I'm expecting to get the session ID here. So I will have here session. And the type of that session. It's exactly the same type which we have defined before. So not observable, but it will have the type ID and a string. So we need to remove that. And then say here that I have this session. It will contain id which has type string. So this will be a callback function is changing the emission from that observable or from that subscription. So for that, we will have again a return, like return for this function, another shape of the session. So we will have here return this dot stripe service. So here we will call stripe service not in the component. So I am going to remove all of this and we will call it or use it here. So in the service, so we are not going to use it in the component itself. So let's copy or GOT this part and go to the constructor of the service. And I will say here that, okay, I need to call the stripe service. And as well you can use auto import directly by pressing Control dot and you will have nx stripe important. And now we will say that this dot stripe service and then read direct to check out using the session ID which is returned from the pipe. So I will say here, direct to check out, and then I will open an object and tell me that session ID is session which is returned dot ID. Why I'm getting here dot ID because I define the expected type returning from that service, which is created out session. So I have here the expected type here. So if you check this method, it's returning observable of error. So in that way, I am returning not the session ID, I am returning and switching the behavior of this post request to another observable. So here I will have observable of error. So as you see, it's automatically changed. It has the return type observable error, stripe error. So now I am able to use that method. And here automatically it will redirect me to a checkout page using the session ID, which is returned from the back-end. So now I will go here and I will say directly subscribe to this service create checkout page. And this subscription will return for me only error. So I will use that just to know if the user has an issue with the connection or not. So I will say here, if. There is some error. Then we can say like console log error in redirect to payment. So just like this, we can have it in that way. And here we have some problems, so we just need to remove all of those. So we have now, right? So service create check-out session. I have subscribed and then I will get redirected to that page. And here in the service, it's already done in this way. Okay, Now let's try that and see if our service is working fine and we have a redirection. So I will go again to the cart and then I will go to see that I have some error. This says that order service drive service, no provider for Stripe service. So we need to provide the stripe service. But before of that, we have to say something in configuration for that service. Because if we go to the documentation of MDX stripe and see some step which is called installation. There is something next which is called setup application. And sit up application requires you to import NGINX stripe Module 4 root and you put the publishable key, so not the secret key from Stripe, but you have to put the publishable key. So we need to import that part. So we need to have import NX stripe module. So where in the application level. So I have here and you shop, I will go to the app module. And then here in the imports of the module, I'm going to import my module which is called MDX stripe module from NC stripe. And then I'm going to use the MDX stripe module and say for root. And in the four route, you are asked to have publishable key. So in that way, you need to use the publishable key from your data. So as you see here, we have publishable key and secret key. So I will click on this to get copied, and then I will put my publishable key as a string here. So let's save and then see our application if it still has the error. So I'm going again to the guard. As you see, we are not having the error anymore because MDX stripe module has already provided the service for us, so we don't need to provide it manually. That means we can be able to use that one or that service, which is called Stripe service and directly in any module in our application. So now I'm going to click on check out and then place order. And you will see we got three directed to another page which will have the payment. And as you see here, I have the prices which are returned from the items which I built before, if you remember in the back-end because I send the order items to the backend. And in that way, I will be able to put my card data and place a payment. Let's try that. So accepting a payment you need to use some test data. So in the documentation of Stripe, that is a payment and there is example which I showed you called accepts a payment. And here there is a guards where our fake like you can just use them and then you can place a payment. So for example, I'm going to use this one. So we go again to the shop. I would place my e-mail here and also I will put like the number of the card or you can put any date here. So I will put here five, twenty one, twenty one, say 25, and some number and also name. We can just put any name and then drag Country of the payment and then you can pay. And after that, if you notice that after successful payment, you are going to be redirected to a successful page. But if we go to our admin application, we don't have any placed order. So we cannot track the orders where we have placed them from the back end because if you remember, we have canceled placing the order service here. In the next lecture, we will see how we are going to place order. We have successful payment and send it to the back end and saving it in the database. But after, before that, sorry, I need to show you how you can see the payments directly in your dashboard in stripe. So as you see here, I have here a payment which I made using this description key and also this email. And you can also click on it and see more details about from which location and also what are the items of that product and everything which is passed to the back end, how we successfully created it. 186. Placing Order After Successful Payment: So in the previous lecture, we saw that we were able to handle the payment and also put our card data and press Bay. And then we got three directed to a thank you page, which we created in our application. But we are missing the part which is creating the order. So we are not creating the order actually in the database. So when I go to the Admin application and go to the orders, of course, I would like to remind you that also you need to add the app module of the admin to add the MDX stripe module. Because maybe you will need as well to handle some payment in the admin panel. And also the application won't work because we used the stripe service in order service and the application will not work without it. I mean, the Admin application. So now we have all of this information. As you see, I'm not placing any order. I don't have my order placed after I made the payment. So for that, we need to place the order in the database as well. Where in the thank-you page. I mean, after really successful payment, not when I'm clicking here on Place Order. When I place the order, I pay and go back to the thank you page in Thank You page, I am going to have the order created. So going back to the check out page, if you remember, we have created an order object. And these ordered object, we're containing the information about the user or about the input or the user, or about exactly the same information which comes from the user who enter the information in the form. So for that, we need to use the order service, but we're not here in but in the thank you page. So I will go here to the Thank You page. I would create again the order and place it here. So in the thank you page, we don't have that information. We don't have after we are getting redirected to the payment page, which is directly outside of our application and go back to the thank you page. We would use the ordered data. I mean, those information, we are going to lose them. So we need somehow to cash them in. For example, in our application, we can say the easiest way is the local storage. I can cache all of those information in the local storage of my application, and then I can use them again in the thank you page to place the order. So for that, I'm going to create two services. First service is called cash order. For example, in our application, which will be located in their services and order service. So I will say here, after create the checkout token, I would create a service which is called cash order or for example, cash order data. So in that way, I will pass order which has died or there as well. And this diode will use the local storage, or this service will use the local storage to cache the order data. So I will say here simply local storage dot set item. And we will give a name to this item like ordered data. And this order data will be passed the order itself or the object which will be passed from the front end or from the component of checkout page. But here we need like a string. So we can't say JSON dot stringify, like we would add it as a string and we will say, okay, stringify this order. Okay, So after caching the ordered data, so we can then retrieve them in the thank you page from the local storage and use them to create the order. So here I am going. After placing the order, when the user click on the button, Place Order, I collect all the order information. And then I will use this dot Order Service vault cash or the data, and I will pass that order. So in this way, I am caching it in the local storage. So we don't need this service now. We need it in the thank you page. I mean, creation of the order, actual order will be done. The thank you. Page. So let's go again and got this part or remove it totally and go again to our thank you page. So everything is fine until now, but creation of the check-out session should be done after I collect the information and cash the order data. Otherwise, I will be redirected to the payment page and I will lose the order data. So it's better to move this part to be at the end after we cache the order data. So let's make sure that we have really the information are cached. So I need as well to save the service. So everything is working fine. Nice. So let's place the order and check our application and local storage. Session storage, I would take the local storage. So in the local storage we have the cart and also we have the token. So when I place or when I press on place order, I must have also the we can say the ordered data. Okay, I will click on it. I have ordered that as you see, but now I lost it totally because I was really directed to another domain, which is called checkout strive.com. So now here I will put my information and the guard and then I will place the order. So now I will be redirected to a thank you page. So there Thank You. Page will redirect me to the application where I have localhost 4200 port. So when I click OK, press. So here in that moment I need to place the order, so localhost 4200, and then I will have exactly the order data which I need so I can retrieve them in the Thank You page and place my order. This what we will see in the next lecture. 187. Placing Order in Thank you Page: So going back to the thank you page component, we will see that we have empty component. It has only like Thank you for shopping with us. We have received your order, but before displaying this information, we need to place the order. So first of all, we have, if you remember, we remove the placing of the order service from here. So we are just caching the order data. So we need to do another service which is not caching or the data, but getting the order data. So we can have another service we can call it like for example, retrieve or get or the, or get cached order data. Get gashed. Like to not have confusion between good order and get like order which is in the local storage. So I will say here, just get item and this get item, I will not only use it like this, so we can have only the key get item is requiring us only the key which is ordered data. And this service should return for me an order. So I would say here, the return type is order. So in that way, we need to have as well a return type which is ordered. So we have to put here return. But these get item is returning for us as string. So in that way, we need to do JSON.parse. So we are parsing from string to adjacent or two object which will have our order. So after that, we are getting the JSON.parse as order and we get that order. Of course, this method doesn't need any parameter, so we just use getCacheDir order, return order from the local storage after parsing it. So going back again to our thank you page, components. So let's close all of those. We don't need them. Okay, we save this one. Go again to our thank you page. We need to implement again on G on in it. So implement in it. And then we need to call on in it and g on any method. And in India on init method, I am going to retrieve the order data using the service, so private or the service. And then we call orders service or sorry, not order module or the service and order service will come from the service which we have created here. So we have to remove this like aliased path. Again, I don't know why I have it like this, but you can always fix it manually. I would have e-services and then order service. So in NGOs in it, I'm going to use or call that service. So I would say here, constant, we can say order that. And this order that will be equal to this dot or their service dot get gashed ordered data. So we have getCacheDir ordered data here. So let's do a console log of ordered data to be sure that we are really getting the right data from the order and the cached order and repeat our payment method again. So I will go again to our application, go again to the card, check out. Then I will place the order and I will be redirected to the payment. I will put my payment data. And let's check if we have really the order data. So we have them because we cannot see them, we it goes now we add another page. So I will pay now and I will be redirected to a thank you page now. So okay. We got three directed. We have the order data in the local storage, and we have also the orders item. So in that way, I have the ordered data in the thank you page. I have all my information, my address, and all of those information which are cached and send from the check out page component. So now we are able to place the order. So we can say here directly, this order service though, create order. And this create order will ask for order data because we are passing an order to these data and then subscribe. And then I can get the results like notification or something like to display for the user. We don't need. In that case, we have to do it behind the scene because he already got this notification that he's ordered got to place successfully mud on success. We need to have one thing which is removing the cart items, like initialize it again, if you remember, we did that before and as well, we can, for example, do a redirect to the homepage after five seconds. But we can have, give this back to the show button where the user can go back to the shop again. So after subscribe, I will have a method of success like a callback, and then I will use a card service again here, if you remember, we need to use the card service. So guard service. And then guard service again here. So we need like weekend call it directly as a service, but not from aliased, but from a relative path to not have the issue again. So here I have the card service, and I would say here, after this axis, these dot guard service dot empty their cart. We don't need the car to be full anymore. So let's go back again, try our application. Okay, Now we have empty cards because I refreshed the thank you page. So let's place now the author. So I will remove, I will close the console to have it more clear to see. I will place or add to cart this item and also this item. So now we will go to the car 2. We have two items and I am going now to do a check out. So my total price is $2200. And I have those information in my order. And now I'm going to click on place the order. I will be redirected to the payment page. I will put again in formation of the payment. As I told you, you can as well use some other types of cards. So as you see here in the documentation, there are guards which is always successful payment, like a test. This is 3D secure. Authentication must complete it for a successful payment. And also there is this always fail. So it says insufficient funds. And in this way you can use this guard to test your shop more or inefficient way. So have we have these now the one which is called test, which has successful always. And it's detected as a Visa card that I will place my order €2200. I have two items, as you see here. All this corruption is coming exactly how we implemented before. So I replace PE. Now I will get redirected to the shop. Okay. The car that gets updated because it got mt going back again to the admin panel to see if my order got placed. So we need to do to refresh again. As you see here, we have my order. I have my order placed. I can view it and see all the data of that order as you see here. So we are successfully placed the order in the right way so I can then change it to delivered or failed or bending is depend on the state of my shop and administration of my e-shop. Also, after the successful of placing an order, It's better as well to remove the cached order, which is in the local storage from the local storage. So far that we can also remove that order data because we don't need them anymore. So it's not nice to have the ordered data always in my local storage. So first of all, we can create another service which is called Create or remove the cached ordered data. So I would go to the order service. It will be something like remove, cached or the data. And in that way it will not return anything because it's void. We will just say local storage, dot remove item, and we have to specify the item name. The item name in our case was order that. So now I can call this method which is called remove cached order in the successful after placement of the order, and remove the order item from the ordered data. So we can have here this dot, like for example, car order service dot, remove the cached or the data as well. So in this way, I remove empty the guard and also remove the cached order data. But now we have a very, very dangerous bug. What if a person like was able to go to sexes page? So for example, I can do like this in the URL. I can go to success bait, okay. But I don't have any order and I am placing empty orders to my, he is placing empty orders to my data base. So in that way, this is a very dangerous problem. In that way, we need to fix it. So a security thing can be resolved by getting the session ID which we created for the payment. And make sure that really the user made a payment when he got to this page and validate their payment and say, okay, you are now able to place the order to the database. So we don't allow any any placing of the order call until we got the successful information from the user that he really paid and he really have a session ID to place the order. This what we are going to see in the next lecture. 188. Linting Project with NX Lint: Alright, in this lecture, we are going to do the linting for our project. If you remember, I have always some errors in my code that I have, like they are mentioned in red sometimes, and sometimes we have some warnings like when they are mentioned in yellow. So I kept those errors because I want to show you how we can fix them for all the project. So we have some comments which are provided from NX, which will help us to do linting for our project or for our own workspace here. So that's why during the course you are seeing sometimes I am ignoring those errors because I want to show you how to find out and fix all of those mistakes when we are going to do the linting. That's why we have in every project something called ES lint. So the ES lint configuration, which are mentioned here, they are rules which we have them for all the project or the repository to fix for us the problems which can be in TypeScript or in HTML, or in JavaScript, or in the JSON files. So in this way, we assured that we are delivered into production the right project without any problems or any mistakes. If we go to the package JSON file, which is here, we see that we have already scripts and those scripts we can run them to do some functions. I will start with the Linde. Linde is what we need for now, we need to figure out what the errors and mistakes we have done in our code based on ES leaned rules and fixes. So to do that, we can just go to the console. We can go to a new terminal like for example, we can close all of this. We have, for example, yeah, this terminal for example. So we have now we can say clean or clear. So it will clear the interface for me. So I have here that then Manila. I will run the command which is called MPM run lint inside my project. So as you see, I have NPM run length, so I am going to run this command, so it will be returned in x workspace length. So this comment actually is an annex command which will be executed beside the NG Lint, which is for also for lengthening the code. So let's run this command and see what errors we will have here. So it's running now. Now lending into shop, it will end in project by project like for example, we have two application, admin and any sharp, and it has also libraries. So all of them, They are projects. Okay? So we have here, for example, first error, which is saying that homepage, unexpected empty constructor lifecycle method should not be empty. Unexpected empty method in June in it. So to go there directly, you can just say cmd and click with a mouse. Or you can control and click on the mouse following those. So we go there. Okay, It took us directly to that component. As you see, that is rule in Eastland that I cannot have empty functions, so it's better to delete them. I don't need as well the constructor. So we can also delete the implementation of energy on in it. And also we delete this library. So now we have a clean component without any issues here. So let's check as well the other errors. So we have finished this one homepage. We have here as well error. So what it says, this electrode should be prefixed with one of prefixes, blue bits. So if you remember, in the application, we have created this with any shop. So the selector should be blue bits. Now we want to keep it with NDI shop because we are in MD shop application. So we need to go to the ETS leaned configuration, not that the global one, but the one which is inside the project. So we have global one which will be applied for all the workspace or their repositories or the libraries and applications. And we have also inside every application, we have something specific for ES lint, which override first the global one we extended and then we do and adjust hours. So here we have in the initial application we have this net attribute should be prefixed with a blue bits. Now we want to prefix it with energy shop. So in that case, we will not have that error anymore. So when we go to the footer, we have to check that. Okay, we still have error again with a constructor and g on any 20 to remove them. So it's better as well to keep our components clean without any problems. So as you see here, we've got error on the homepage as well. We need to replace that. With NG shop. So we say NG shop as a prefixed. So let's check another errors as well. So I will go here to Footer. Ok, we fix the footer header. We need to fix the header as well. So we go again here, we will see that we used cart service, but are we called cartels, but we didn't use it. We have to delete it. We need as well to clean up and geon in it and the constructor. So ES lint has a lot of rules. You can add them to your code. So for example, you don't want to have empty functions. You can go to the documentation of ES lint. As you see here. I am on the formal website of ES lane.org. So Eastland has a lot of properties and rules you can configure for your application. For example, the codes should be double, not single. For example, we have here sometimes using single quotes, but you can configure it to give you double-quotes. So there are rules always coming with this Eastland. And then I think NX already when you created this project, it comes always with some specific and like rules which are predefined already in an X. So you don't need to adjust it so much. So you just do. The next thing which I showed you about prefixing the component and the directives. So if you go to the User Guide and then you go to a rules, you will see there are a lot of rules and they are described here, all of them. So for example here, this allow unnecessary semi-colons. So it's always showing you that when semicolon is not necessary, so it will give you error when you enable this one and you don't have a semicolon. So of course there are a lot of roles. You can see them go one-by-one to them. And then you will find out that they are really beneficial for you when you are building your project. And you don't allow developers to post any code or commit any code without fixing all of those issues or the rules which you put for your project. So going back to our Eastland, again, we want to fix other issues. So we have here header, we fixed it. We have here at messages, and we have some issues here. So one of the issues in the messengers, the selector should be prefixed with one of these prefixes. So we need as well to fix that one which is here, we need to have any sharp so we fixed that already. We added the NG shop prefix to the ES lint, fine, so we will not have any errors. So let's run again the command we can say clear and then run lint. And we see if we are getting a new errors again, so to be sure that we are fixing the right arrows. Okay, last mistake we have here is as well that app component must be prefixed with like candy shop. So we have here should be always and you shop for component. So now we have everything is limited but only for ND shop application because it's the primary application which we created when we created endings. So let's link as well the admin application. So I will run here a comment, also MPM run lint but for admin application. So you can specify the admin. So it will run for you also the linting for the admin project. So in that way, also we will get some errors. We need to fix it. So for example, we have some warnings that we used any here. So as you see, we have like some warning that we are using the any. You can also disable this rule because sometimes you need to specify like any, as we saw previously. So we can search for disabling this error. So we can go unexpected any specify different type. So you can't surge in their roles here. And if you don't find anything, you can also use the search tool here. So when you cannot find anything, the best way is to use Google. So if we go here, unexpected any specify and you can say Disable. So we go to Google, check that disabled TypeScript, Eastland plug-in role. So as you see in the stack overflow, we have Google the error and there is some solution. He said, just add this rule so we can copy this one and go to our Eastland file. It's better to put it on the global one because it will be applied for all the project. So we have also those rules. So we can put that rule, for example, here. So it will be applied on all files, mostly T, SDS, x, and JavaScript. So we can add this rule as well here. So we can. Go, as you see here, we have no empty function and also no explicit any. So we save that and go again and run our command. We can say clear here again. And then in npm run lint admin. So as you see, we are still getting this error. That all warning, we can say unexpected any. This is because when we go to the, again to the rules, we put this rule here. So it should be not here. It must be in that like the extension of TypeScript library. So you can add this rule here, which will be applied on TypeScript roles. So we need to move this one and as well this one, and put it inside the rules which we have for the TypeScript. As you see TypeScript, then here it would be prefix TypeScript. So all of this information, you have to be careful with it and you can add your write rules to make them works. So let's save again and try to run our command. So I will go again to my command line here. And we can't say clear. And then we can go npm, run lint admin. Again. I'm showing you slowly step-by-step to know how to fix those issues and warnings. So as you see, we don't have this error anymore. So we don't have the warning or which is saying that any is like not prefer to be used. So we have only those errors in the admin application. So let's fix them. So here it says that the NG, or for example, here in this application, NG onDestroy must be implemented because here I don't have implements on this drawing. We have to call also on destroy. So this is one of the errors. We have also another error here as well. We need to have to implement the onDestroy. So we didn't implement that. So you need to import it and implemented as well what errors we have, we have in the product list, we fixed, we have as well in the user's list. So we need to fix that as well. I will have here on destroy another error, which is the same we did previously. Ngos in it must not be empty. So we can just deleted the lead, the implementation on NGOs in it. We don't need anymore and also the input of energy on it. The same thing goes to the sidebar. We fix this error as well. So in that way, you do all the same for all libraries. And so now I finished with the admin. Then you want to do for the library, which is called, for example UI. So you just go here, MPM Linde and you say UI. So in that way, it will link the library you, so you must specify always the name of the library. So as you see, we have error in the banner and on and it must not be empty. So we have here as well, we need to remove the implementation of it. So we save everything. And we go to the application to check if everything is working fine. So then we will be sure that we don't have any errors in our application. And as you see here, I got an error and you show proof did not match any of elements. So we can go to the selector here. We can check why we have this issue. So in the application and you shop if we go to like index, It's asking blue bits root because this app module which we created or app component, we change this NG show proved it was blue bits root. So in the index HTML of the application and you shop, you just need to rename this because this is the entry point for our application. So we go here, replies and reload the application. Everything is working fine. So that's it for fixing the linting issues. As I told you, just run NPM or mpm run lint and you specify the project name and it will solve for you or show you the errors after what you specified in the ES lint based on the ALS lean roots or rules which we have specified there. So for that, I am going to fix all of this lens errors for all libraries, which will be the same. I'm not going to do it like in front of you to not take so much time. And I will add that the code of the project at the end of this section. And I just want to remind you that when you fix all of those issues, for example, I fixed the orders at the end, you will get all files past linting. So in that way you don't have any errors. 189. NX Migrate Updating The Project to Latest Version : Alright, in this section we are going to talk about updates of Angular version and NX library. So you know that always Angular providing the new versions every four months or every six months. And as well in X is following that to always to keep interact with Angular. So for example, I have worked in this course with Angular 11. And then an update came up, which is angular 12. So we are going to update our project to Angular 12. Now, the great thing with Angular or NX novel, It's providing you with a tool for upgrading. You don't have to do anything. You don't have to do that manually and find out in back a JSON, what are libraries you used and then update them. Man, who already know NX is providing you with all of those things. But first, we need to check our changes. So first of all, I would like to install a program which is called GitHub Desktop. It's application. You can download it from desktop.gov dot com. You can install it for Mac OS and Windows. After installation of this, like the GitHub desktop, you can connect your project to it and see the changes which are done in the project when you have dot git repository. So when we go here to our application or to the console or two, they're like the File Explorer. We will see that we have always a file which is called the gate. You cannot see it here. But if you go to the Finder or to the Windows Explorer, you will see a folder which is called kid. That mean this project is connected to a good project or connected to a Git repository by default. And x is providing this kid and it's connected somehow, do a Git repository. So what you need to do is just maybe you can remove this part or you can keep it to track your changes. So for me now, I am going to keep it. But if you don't have this duplicate file, I'm going to show you how to create a new one. So first of all, I go to GitHub Desktop, which I have installed. As you see here. I have all my projects which I did before. And now we can start to do the following. First, we need to create a new repository from hard disk. So you can, if you don't have this dot git file, you can click on this and then you can specify the folder you are going to implement your project. For example, I have, my project is here, I will click on open, but it says that this directory appear to have a Git repository because I have dot get file as I showed you here. So for that, we don't have to use this option. Otherwise you can use it by creating a repository name and also it will initialize for you new file. So in that case, we go to add an existing repository from a hard drive because we have that already. We have that dot git folder. So I'm going to navigate to my project, to the workspace which I have created. And like open this project that the workspace where that dot get folder is there. So we open it and we say Add repository. And as you see here, I will see all the changes was I have done from the time I have installed in x and till now so far that I want you to click on the commit. You can write a commit message so we can get all of this like commited and confirmed. So you can't say like finishing. We can because we can we can say that we've finished the course or the shop. So we can say finishing the e-shop. So that's it. So then you can say commit to master. Now we don't have any changes. So, but when I go to my file or in the File Explorer in the editor, I will see that when I do change. So let's do here change, for example, save it, go again, and we will see that we got, and this change is here. It was 11, now it's 12. So for that, I want to do that because we are going to upgrade our project. So in that case, we will be able to see what changes are done. One, what did for me for updating my project? So to update the project, we can go to the browser. I'm going to send you a link, or you have a link which is attached with this lecture. It's showing their documentation of updating an X on the NX normal website. So we need to use the terminal for that. So it's very easy and very simple, which is very great to do with n-x. That's why I encourage people to do the projects of angular width NX because it's providing you with the tools which are really great for updating and migrating your project. Of course, you can use as well NG, update. But it will be partly updating. It will not update the other libraries like for example, NDR x, or for example, if you are using TypeScript, etc. So for that we are going to open the terminal and use this comment. So we go here, open the terminal again of our project as we see previously. So we can go to this node here we are. You can stop the project is better. So it's better to stop this one. And I'm going to stop as well the admin panel application. So here we are going to paste the comment of the terminals NX migrate latest. So when we run this command, we will see that NX start to do something which is updating the package JSON, so it's better to close it and also create a file which is called migration. This will take awhile. It's about from five to ten minutes. I am going to skip our speed up this video. And you will, I will come back to you after this is ready. So as you see now that the migration is ready. So the package JSON, he said, make sure packages and changes make sense and then run npm install. Let's check our package Jason. We will see that, okay, everything got updated to version 12, as you see here. So we have as well angular and everything got updated to the latest version of Angular. So in that way, we get updated our packages and libraries and all dependencies easily. Now we are going to check the update or how we can install those updates. He said, make sure package JSON changes, make sense, and then run npm install. But also you can check the changes by checking the GitHub and you see all of those changes which are done here. And also it created a migration file which will be used for the migration. So let's run the npm install again. So we can say npm install in our project. And it will install all the updated libraries. Again. Also, it will take some while. And I'm going to make this video fast. Okay, Now, after MPM install, as we see here, that it installed and compiled all the library and everything got successfully. So if we go again to check our changes is only the package.json, which is a temporary file to confirm all the libraries and their dependencies and their links and tokens. So for now, we are going to execute the latest command after this update. So if we scroll up to the instructions, again, we see that here npm installed and after that, we have to do ONNX migrate around migrations. So here we are going to run this command and then it will update our project. And we can run it again and we see if it got updated. So here we go again to the common line. I copy that one. I see here like based of their command. And then I run that migration as well. It will take awhile, but I'm going to speed up the video. Nice as you see here, the big gradient has finished. It did a lot of things like remove some deprecated things and also update were poor workers, migration activated routes, snapshot or updates which are done or on Angular in this new version. So the NX did that for me. So let's now run the project and see if we are really doing. Everything is fine. So I will say in x serve and you shop, and in the other terminal, I want to run as well the admin application. So we go here, we run those two applications to see if everything is working fine. During that, we can check also our good. As you see, a lot of changes happens. So my advice to you, you have to check always work changes are done, especially if you've updated some rules on ES lean for example, especially if you have like some applications where you have some, did some core adjustments. So you need always to check all of those changes. And then you can migrate and start your application or merge or the code which has got updated to your project. So I'm not going to speak in detail about every update which happened here, but it's mostly happening. I like on configuration of configuration files of the project like ES lint, like testing, tools, like just, and also the environment variables which we have created previously, and also the poly fields, etc. So all of these files get updated, also the NX JSON. So a lot of things can NX do for you without having an effort to do that manually, which is so great. You don't have to care about all of this may be myths, some library, you, maybe you missed some important update. So NX do all of that for you, which is thanks, big, thanks for this team who is developing all of this library and keep it on track for latest updates of Angular. So as we see here that we have compiled successfully the project of any shop and as well the admin. So let's go to our browser and check if we have everything is fine. So first I go to the engine shop. So here I need to refresh. So we have here the Refresh. Okay, it seems that everything is working fine. As you see the product page, addict product, Add to Cart. Nice. All of it is working fine. The checkout page. Perfect. So we don't have any issues on the admin or front end application. Let's go to the admin panel application. So I go to the admin as well. Let's refresh again as well. Okay. We have products, we have categories, all of them working fine. We have placed some orders and also users. Everything is perfect. We didn't have any issue. After that. You can create a message. You can call it like core, update or upgrade, you can say. And then you can commit to master. And all of those changes will be pushed and committed to your repository. All of what you have to do is push that to a repository which you have connected to. You see, it's very easy. It took us like about 15 minutes just to do upgrade to the latest libraries of our project. 190. Installing Heroku and Prepare Git: Okay, In this section we are going to deploy our backend or our Web API to Heroku. Heroku is one of the tools which is used to deploy the project or web APIs. And they can be public and we can use them in your projects. So you will not have your API based only on localhost 3000 as we saw, but we are going to put it on some URL and we can connect our front end applications to it. The first step we have to do, we have to go to a website called Heroku.com and then we are asked to be locked in. Of course, if you are a few don't have account here, you can as well sign up. The signing up is very simple. You just provide FirstName, lastname, email address. And what is your role? Country? And as well, you have to put some Brian money development language. We have to put NodeJS in our case and you have to verify that you are not a spam and then you can get an account. After you log in, you are going to see a dashboard like this. So this dashboard, we need to create an application which we are going to make it public for our API. So first of all, you need to have create a new app. And this creation of a new app, you can give any name for your application. In my case, I would give it a name like e-shop, back end for example. And maybe this name can not be available, so you need to specify some specific name. Maybe you can give like any random suffix. For example, you can put your last name. For example, I will put my last name or my company name. I will see, I would say like a blue bits. So in that case, I will have e-shop back and blue bits. And then you choose your region is better to use the closest region where it is closer for your target customers. So it's better for me in this case, I am living in Europe. So I will put Europe and then you have to click on create an app. So we have now created an obligation. There are some instruction we have to do first. First we need to download and install Heroku CLI. Let's go to this link and check it. So in this link you can see multiple options for installing Heroku. So for example, you have macOS way, you can use comment if you have Homebrew and also if you have Windows, you can install an installer. And also for open TO that way, which I like always to use is using NPM, NPM global installed. So you can do npm install dash global, Heroku. So let's go to Paris and do that. So I will go here and open my terminal. I will use Control J button as we saw previously. And then I will say npm installed minus g. So in this way, I will install Heroku Domain device public, so I can use Heroku commands in my machine. But the first I need to do is maybe we need to have a permissions. So the permissions, maybe it will not allow you to install public or globally. You need to prefix this comment with sudo. So as you see here, I am not r. I don't have permissions to do that, so I need to prefix this command with sudo. So we can say sudo nmap, but in Windows, I think you will not have any problem. And then it will ask me for my password. And then I will put the password and it will get installed successfully. Now, as you see, it got installed, we have now Heroku command. So you can, for example, put Heroku like this and you would get a command like options that you have, some options you can use for your Heroku comments. So go back to our browser. After installation, we go back to our application again and we have to make good edit. And as well, we have to connect our Heroku project or our back-end project to Heroku git. But first of all, the most important thing because before we do this step, you have of course, to create a gitignore file. So for example, in Heroku, I am not going to deploy this end file. This m file contain my connection string to database is my secret and also API URL. I am not going to push that to Heroku git repository. So in this way, we need to add a file which is called git ignore. So when I use a good comment of Heroku, then it will not push those files which I specify. So also, you don't have to push node modules. Monod modules come normally a very huge file, almost 200 megabytes, because we are installing libraries and their dependencies. You don't have to use Node modules as well. So creating get ignored file, It's very simple. You just have to create a file on the root of the project. So you have to say git ignore before doing any step which is mentioned there. So first, you need to ignore node modules folder. So we say slash node underscore modules. And as well we need to ignore the m-file and also another development files like prettier RC, as you see here, we have this file so we can ignore it as well. So in that case, we have, we are, we are ready for connecting our project to Heroku repository. So we go back to the instructions again and we have to say get in it. Because if we don't have initialized our project previously as we saw that we don't have a good, We didn't connect it to any good. So in that case, we need to say get any, okay, After you do get in it, you will see that there is a file created in this repository which is going or called like dot kid. And if you want to see it, you can go here to the backend folder and you will see that this folder and got created. So the next instruction we need to connect Heroku git remote. But first we need to use Heroku login. So let's first look into Heroku. So I will use Heroku login and then it will ask me, do you want to open the browser and you can login then. So we can't say yes, we can press any key and then it will open automatically the browser. So as you see here, I have it another page. It's saying look into Heroku CLI. I will say look in and then logged in because I am previously logged in on the same browser. So when you go back to the terminal, it will know that you have already connected and then you can use Heroku commands, as mentioned in the documentation. After that, we need to connect our Heroku or our project to Heroku git repository. So we need to use this command, all of these commands, you can use them as you see, say Heroku, git remote, and then add E sharp back and blue bits. So it's exactly the same name of the application. So let's do that. And then we based this comment here. And then, as we will see that, okay, the Git repository is set to this path. So now when we are going to deploy our project or upload our code to handle cool, then Heroku will get or read all their files and the code which we have uploaded from this path. In the next lecture, we are going to see how we can create as well a production database. We don't have to use the same database as we see because maybe this database we can differentiate between development and production. As we will see in the next lecture. 191. Optional Creating Production Database: Okay, in this lecture we are going to talk about creating a production database. So when you are making a development or when you do some application, normally you have a spatial database for you, for just development and testing things and making a progress for your application. But after deploying the project to alive, then you have to create a production database. In this course, this is optional for you to create live database, production database or not. So in this section or in this lecture, we are going to do that. If you remember, we have installed MongoDB Compass and this MongoDB Compass application, we can be able to create databases and also we can as well import and export data to it. So in our course we were using this database, which is called e-shop database. Now we are going to create a new one. We can call it E sharp as well, database. And it would be a production broad. So we can have that and we can create the first collection, which will be called, for example, categories. And then we make, create for the database, and the database gets created. So as you see here, but we have only one table. So if you remember, I attached for you at the beginning of the course, some files, you can use them like as default data. It's like the data which we are inserting do the database. It's like seeding. So we can use also the seeding that as well here. So I will do that quickly. So how to import data using a compass? You just have to go here, click on categories, for example, on the collection name. And then you can say import data. And then you browse to the file where I gave you. So I gave you, for example, categories or the items and other tables. So for that, you can use for these categories and you have to specify here that you have JSON. And now we are making importing. And this import gotten completed. And we will see our data is located here. So we will do the same for all the tables. I'm going to do that quickly in front of you. So I created here a new table. I call it user, or users. And these users, I am going to import that data as well. So we have to do the same for all other tables. So now my database production is full. So we are going to use this database, but we're only for their product application or that developed application on Heroku local development, we are still using the issue of database. So how we can make that dynamically, like when I deploy ISA to the application uses database. But when I am developing, I want to say to the application, okay, use this database. So it's pretty simple. We are going to configure that environment variables which are preferred for Heroku because we are going to use these variables and we use them inside the application. And on development, we can keep, for example, this connection string. But on production we are going to have another connection string. But here as you see that environment file is not deployed because we added to git ignore. So this will not be in the deployment on Heroku because Heroku will not know that we have environment file here. 192. Setting Development and Product Environment Variables: Okay, now how we can say to the application to use that database of production, not the database of development. First of all, if you remember, we added the m-file and in the end file we were using it for connecting to the database which we have created in MongoDB Atlas. So the connection string is stored in the m-file as you see here, and we talked about that previously. So now we are going to have a connection string different for production. So in that case, okay, we are using this connection string here in process connections to make. But as I told you that when we are going to deploy this application, this m-file, prettier, IC and Node module, they will not be uploaded to the server. So from where deployed application will know which connection string to use. Because in that case when I deploy, it will not know which connection string to use because it will be undefined here. And then we will have a connection error. So for that, let's change first everything which we have, like two or in our app.js, everything we need to change to be in production. For example, this name, I'm going to use a database but abroad, not this one. So we need to change that as well. We have also to use some, another variable, which we can call it dB name, for example. And we can give this DB name in the file. So we can, after that was one line, we can say DP name. And then for local, I will have to use this e-shop database. But in production we are going to use a different one. Okay, What else? So the application as well is using a specific port. So when you start the application in production, as you see here, when we go to the browser to our application and we use, we say, for example, open the app here on the top. Then we will have a new app. As you see here, we have the link, but it doesn't contain any port or like for example, 3000 or something. Because before we had like local host like this and 3000. So we don't have the board here. So how we can also make the board dynamic. So we need to do that as well because in the production it will use a different port. So as well here we have to define a variable. We can give it like a constant and we say port. And this port will come as well from environment variables. And it will be called port. If there is no port, then use 3000. So just in case if this part doesn't come or it comes with undefined. So then we use this board here. And in my file I can define that port. So we can say as well here, use the port, we can say port will be 3000. But remember, this is only for local development. We don't have for that for production. Production will replace it with another port. But the key word for that it will be bought like this. So Heroku will find or create a port on its own. Normally, it's port 80, which is the default port for the HTTP. Ok, now we have one problem. So how the production with no connection string variable. So how we can create that. So we go again to the browser where we have created our application. And then we will find on the top something called activity or settings. And in their settings you will find a reveal config vars. So those are the conflict vars which will be used in the production. So in that case, I need to say to my application here, use the connection string, but we're production one. So I will go again to the browser and then create a new key connection string will be what it will be. The connection is staying the same but with different database. So I will use the same one. And then I will say that not use e-shop database, but each of that obeys abroad. And as well, we need as well to create another thing which is called DP name. We are going to use that name sharp, that the base, so here as well, E-sharp, that obeys broad as well. So in that case, the application will know that there is a connection string and he would read it from here. So we don't have to worry about that. So it's better as well to add all the environment variables to the connection because otherwise our application will fail. What we have to use here, API URL, which will be the same thing which we had there. It will be api slash v1 and we are adding it secret. The same. It should be also the same capital letters or small letters because it's case sensitive. And we will have here the secret or you can use another secret. So when I deploy my application, then it will search for process. But our local error is not deployed because we have it in the good ignore. So it will not be on the server so that Heroku will not know from work to get it. He will go to the conflict vars and then read those values. So in this case, we have different database from production and a database for the local development. In the next lecture, we are going to see how we can use that and how we can deploy the application to the server. 193. Deploy the App and Test It: Now let's go back to the instruction of deploying the application. So here if we go to the application again and we click on Deploy, and we will see again our instruction. So we did already that connection and we have deployed or make the link between the application and the Git repository of Heroku. Now we are going to execute those comments. First of all, we need to add the code to the good, so we need to commit it. So if you don't know what is it, It's like you are giving information about, like what code you are committing to your repository. So when I do change, then I say, okay, I changed this one, I remove that. So I would say in the commit message that removing the error handler. So in that way you keep track about your changes on the project. So here we can do that as well with Heroku. So we have to make git add dot and then git commit dash am, make it better or any message. So first of all, let's do the good. It means this that we are adding all the files of the project to the Git repository to prepare them for uploading to the server. And then after that, we have to do the git commit and then dash m. And then you can specify a message. So for example, deploy first, die. So we can as well add this commit message. After that, we need to push the code to the cetera. We are how we do that with this common git push heroku master. So I will go to the terminal and then paste this command here. And then it's going to upload all the information or all the code which I specified, except the files or the files and folders which I specified in git ignore. So in that case, we will have all our files of development are there. So as you see here, it's dart, do deploy the application, the files finished, it, start to building it. And now it's showing all the progress installing libraries. It does as well npm install for installation the packages which we used for our application. And then it will have Node modules, but on the server, not this one. So after that it will compress the application for faster usage. And you have also to remember to upload the images which are in the upload folder so we can see the images as well in the, in the server. So otherwise, if you don't have those images which I attached for you as well, because they are in the database as well, the links to those message or images. You need to upload them as well to your server. So that deployment finished, verifying deploy, done. Okay, Let's go back to the browser and go to the application and refresh here. Nice. We have message, the user is not authorized. That's great because if you remember, we have authorized our API. So if you remember in the routes or in the helpers, we said JWT that we are going to exclude some routes from authentication, for example, in getting a products or getting a categories. So let's try to get a products in the browser. So I will say here exactly if you remember how we were doing with local host and 3000 and then I put API v1, and then I put products for example. So this is like a get request when you try it, Okay, We got all the data from our database. You can't try that as well as Postman, if you remember, we have we were working with the postman a lot and we were trying our API in Postman. So here I will open a new tab for a new GET request, and then I will put this link. So the link of my application API, v1 product. So it will be exactly how I'm doing it like from local host. So you see that all of these information are stored and we are using the production database. We are not using the database which we had for local. So to prove that, Let's make a change in the database using compass. So I will go to my application, I will go on to the production database. I will click on this and I will open the products. And I will go to the one where it start with, I remember as mol, something like that. So here the small, you see here the small and this is. So let's change that. We can say change this sentence. We go to the, so we click on the small here and we can say, for example, abroad. So we can make this bigger and say production. So we can't add this word production here. So after we update, and then we go to Postman, and then we click on Send. Okay, we have here production. So this is proof that I am using the broad database, but on my local host, Let's try to run application on local. So we can say npm start as we were running the application locally, okay, The localhost 3000, everything is fine. Now we go to GET request, but on the local host. So we have here, for example, localhost 3000 API products. And then if we call it, we will see that we are calling the database, which is in the local host. And if we check it, this database, I will go here. And I will check this issue of database. Go to products. I will have a lot of dummy products which we were using during the development. So in that case, we are differentiating every time I deployed to my application thumb thing, can you then it will use a database of their production. For example, I'm going to change something here. I'm going to add a console log. What example console log. Like using, we are using. For example, you can put additional and then you can use the DB name here. So when I save, okay, on my local, I will say we are using e-shop database, but we need to deploy that. So here, our local, local host, we have e-shop database, as we know for development. But if we deploy this, we would get, we are using the issue of database brought tea or product. So in this way, how we can push changes, again, we need to put git add and then we add a message. So for example, comments, we can say change, and then we press enter, and then we use again push common. So git, push heroku master, it will be deployed again. So as you see here, it's deploying again. The same process as we saw in the first step. Now it's finished deployment. How we can see that, for example, this message which we are using, like the database, you, I mean how we can see the console log or the errors which we see in the development. To see that you can go easy Two more here, and you can check here a view logs. So when you click on it, you will see all the logs like you are developing locally. So we say here, we are using e-shop database abroad. So that very great thing and exactly how we were having the application on local and as well, it will make like monitoring for our API. So when I call this API, then I go to the logs. I will see that, okay, we have information Get API v1 products and some other information about the request and return and how long it took. But if we go to the database, we need, for example, to check one image. So I will go here and I will go to the database and I have products. We will have a problem with the images. So if you remember, we have uploaded some images with our E-sharp. So when I go here, I will see that in the product, they still have this localhost 3000. Unfortunately, this is not possible to replace it. So you need to replace all of those strings which are related to the local host. You need to replace them annually with the link which is provided for your application. So in that case, I'm going to here to my application and then copy this part which is from here to.com. So I will copy all of this. And then I will go to the campus again and replace from HTTP to localhost. Also the port is not necessary and then I will add update or update this part here. So we click on Update and then it will get updated. So when I go now to the application and paste the URL of the image, then I will be able to see the image successfully. Otherwise, all the images, unfortunately, they are still on localhost 3000. So for that, based on your name of your application, you need to replace all of this for the database. Of course, after we use this database, for example, in some front end or when we are, you're going to use Postman, for example, when I am going to post a product using this API URL, it will upload the image based on that URL, so it will be stored in the database like that. But because we were using this database in development, you need to do that manually. Because as well, we were using when we are posting a product. If you remember, if we go to post the product and in the post product we were doing like the image using the host. I get the host current host and then put the rest here to store the image path. So the host will be taken from the host which you are using and calling the API from. So in that case, you don't have to worry about the links which we want to upload for the uploaded files. So now we have a fully functional API on the server. The application got deployed. Of course, if you want to remove this Heroku.com and create your own domain, it's not for free. You have to pay for that. And of course, you can be able to have it under your own domain. So in the front end application or any front-end application, when you are going to deploy their front end application, not their Web API. You can say that for my application in the front end in production, use this API URL for all like the application. And then when your application got deployed, it will connect to this API and grab the data from there. 194. Preparing Git and Github Pages: When we we're deploying the backend, I told you to install application, which is called GitHub Desktop. I will put again the link with this lecture to see where the installation of this application. Github is providing with very great tool for deploying applications, which they are containing JavaScript, CSS and HTML. And you can deploy your applications there and you can see them in the browser. So you can have a domain and then you can see your application published on the browser. So we are going in this course to show how we can deploy the application to GitHub Pages. And if you want to see other ways, like if you want to see how we can deploy that via FTP to our own domain. Also, I can make a video on the course. Just grab me a message if you want me to do that. So first of all, we are going to have this GitHub Pages publication. So for that, we need to connect our current repository, our current project which we have created with Git, GitHub desktop application for connecting to your repository. Because we are going to create repository on our GitHub account. So first of all, you need to make clone a repository from internet. So this one will ask you for assigning into your account on your GitHub. So to do that, you just need to click on Sign in. And then it will ask you to open the browser where you have signed in already on GitHub on the browser. So when you click continue as a browser, and then it will show up for me open GitHub Desktop app. And then when you click on Open GitHub Desktop app, I will be connected to my repositories, which I am signing in on the browser. And then I will have them here so I can clone them or do anything with them. But when you create a project of Angular with NX, the project comes by default. As you see here are the project files which we were working like here, Apps, lips or all of this. And we have here the applications. As you see, we have a dot git file and this dot get folder, sorry, we have to remove it because it's connected to another repository which is created by an X. So far that it's better to move this folder. And also this for I want to mention that this folder can be hidden on Mac system by default. So what you need to do is just press Command and Shift and dot, and then it will give you the ability to see them. So I will see Command Shift and dot, and as you see here, I am showing and hiding them. On Windows. You will see the folder clear and you will see it, and you will be able to delete it directly. But for security is on, Mac is hiding those files which are starting with a dot. So let's delete the dot get folder, which is created already by an x. And I will click Move to win. Of course, if you are connected, your project is connected to some repository. You don't have to do this step and you don't have to remove it from files. Now we move back to GitHub desktop application to create a new repository, but from the hard drive. So what I have to do here is just create a new repository. And then I will give it a name of the same name of the folder where that code source is there. So if I go here one up level, I see that I have here blue bits. And in blue bits I have the source files which I worked and created with n-x for creating my Angular application. So far that we go one level up, like in the way that we see the folder of their source. And then we click on open. And then here we have to put the same name of the folder, which containing the source code. So in my case here, I will say a blue bits and then I will click on create a repository. So in that case, I will have the existing repository, which I have already. And it will be initialized with a GitHub or GitHub folder. So as you see here, we have the Git folder is back again, but initialized locally. We didn't connect it yet to our repository on GitHub. So how we can connect that to our GitHub repository? First of all, you need to click on this button. You say Publish repository. Of course, you are already logged into your account on GitHub, on GitHub desktop. And as well, we are going to create a repository for that. So first of all, you need to give it a name. So it's not necessary here you have freedom to give the name which you want. For example, I would create e-shop on there like this. And then it's always when you want to use GitHub pages, you must not keep this code private. You have to make it as a public. To make it it's private. And with GitHub pages, you have to pay. But for that, it's for free. You can just make it as a public and then you click on Publish repository. So in that case, after you are sure that the dot get folder is went back, It's like X created here, not here. So you need to know that it's really inside the source code of your application. So you need to have this dot get folder before you create a repository. Okay, I am going to my GitHub account to be sure that if it's really, the repository is created. So as you see here, if I go to repositories, I have my repository which is created here, initialized with the things which I have by default created by an x documentation. So as you see here, we have all the files and the source files here. Okay, So what we need to do next is building the application and then publish it to GitHub Pages. And this, what we are going to see in the next lecture. For now, we are ready. We are just need to publish the build of the applications like the engine shop and the admin to our GitHub Pages. 195. Building Frontend Apps: Okay, now we have published our repository to GitHub. Now we need to build the application and it will be, or we will be able to see the changes and we can access the website of our issue. So in this way, we have to go to that code. And if you remember, we were opening the project, which is front end project. And as you see, we go here to the root. We don't have to do anything. Let's close all the command or the terminals which are not needed. Now we open a new terminal. Again, the Build mean that I want to build my application. I don't have to upload all of these files. I want the files which angular giving me to be publishable and they can be used in production. So I don't have to upload all of those source files, files and see how my application is working there. Because otherwise I'm uploading the source files. No, angular has a property which is giving you the ability to build the application which will compress all the files. In some few files, your project, all of it will be in those files as we will see later. So if we go to the package JSON, we will see in the script multiple scripts. So as you see that we have build script, which is saying mg built. But if you remember, we said that Angular or NX is built over angular somehow. So you can do the same comments with an x, like the same how you do with energy or angular comments. So far that building any application, if you have an installed, you just say NX build and then you specify the application which you want to use. Example, I want admin or I want and you shop for now. I want n G-sharp. So we can't say build Angie, shop in that way. So when you press Enter, the application will get billed and it will be specified in some folder is called the East. So in this dist folder, in the apps, you will see your application here. So as you see that build finished and we have only few files in the dist folder. So we don't have all the project source and this folder which we are going to upload to our GitHub. Or you can upload it to your server. Then it can be seen. Or you can see the application which we were building already and you can browse it on the website, on public. But if we want to deploy this project to GitHub Pages, GitHub Pages has some conditions we have to follow. First of all, we do the same thing. We do NX build any shop, but we need to specify some folder which is called output bath. And here we in this output path, you specify some specific path which GitHub likes, which is called docs. And then there is a keyword which is called Bayes HRF. And here we specify HRF or the link which will be generated in the index file, as you see here. Because here it will say base H ref is slash. But we need our base HRF to be the same name of the project which we have created on GitHub, the same name of the repository. If you remember, I have that repository name which is called e-shop. So we have to put the same name because GitHub doesn't see any other name, only the name of the repository. So we have to say here, slash, it's very important to put slash. Don't forget it. You have to say e-shop, the same name exactly of the repository and then another slash. So in that case, we will build our application under those conditions. So let's press Enter and see what it's going to build. Nice, that build finished. But of course not on the dist folder, it will be on that docs folder, as you see here, Tooele be exactly the same build which we have in the dist folder, but it will be in another folder as well. And the base H ref will be E-sharp as we specified in the comment. So those are the basic conditions you have to do to build your application. Of course, we are not finished. We are building now the development environment. We are not building their production. But I just want to show you step-by-step to be clear for you more and more. In the next lecture, we will see how to build or to deploy all of this project or those files to be able that we can browse the website which we created for N D sharp. 196. Deploying Frontend Apps to Github Pages: Okay, now after that, we have created the deployment in dogs folder and we are going to deploy that to the server, often GitHub pages. So how we can do that? First of all, I will go to GitHub Desktop. Again, as you see here, we have multiple files created recently. It's better always to create a new branch on GitHub, which will be like the name of the branch where you are going to always deploy your application to GitHub Pages. So we can say this. Brian can be GH and then we can say pages like this. And then we create a new branch. And then we click on create a branch. So we switch that brand. But here we have to say bring my changes to GitHub Pages because we have created this build. So we need also to move those files, the new files, as you see here, all of them in you. We need to move them as well too. Then you branch. So I say blink my changes to pages. So when we can go and click Switch branch, they will be all moved here. After that, the step is to publish the branch. We have to put this branch on GitHub page and also to our GitHub repository. So now everything is published. But first we need to commit this message. So we need to comment those files as well. We need to say that, okay, those files are new. We need to commit them and push them to the server. So we have to say to GitHub. So for that we can create a message. We can say GitHub Pages, predict bear, for example. And then we put all of those we can say commit due to the branch GH Pages. It's commited. And then we need to push again. So we push again our changes which we have created here. Now we don't have any changes to file. Let's go again to our GitHub page. And I go to the repository which I have created, which is called E sharp. So remember you go to the same repository and after that, we go to Settings, which is located here inside the repository. And then we click on Settings and answer things. You will see like multiple options. One of them is pages. And by default, the application will be published mud on the root folder, we need to give the specific folder. We need to give the files which we have created by the build, which are inside docs. We don't need to build all of this. This is wrong because to not work. But for that, we need to specify a folder. I will just give it a dorks. It will appear here. So I will say give me the docs folder and then Save. And as you see, it says your side published at this link. When you click on this link, we will see that we have some default page, which was the ReadMe. It takes some time because we need to await sometime when you are switching between the folders. So you have to wait a little bit until it got deployed. So after some time it will get deployed. And as well, you can check that domain. So as you see here, it got deployed. So nice. So we have all of this link and we have our end. You shop here. But there is a problem that is no data. There is no connection to database. And if you check here, the console inside, we would get a lot of errors. What are of those errors? That's saying that localhost 3000. So we are still on local host. The back end, it is still connecting to the local host, asking for categories and asking for products. So we need to change this link, localhost 3000 to our Heroku application, which we have created. And this application will be E-sharp back and blue bits Heroku app. And here we can access the APIs as we saw in the build of the back-end. So how we can fix that. So as you see here that it's saying your site is published. So always when you do some changes, you need to wait a little bit until to see the changes which are published here. So it takes a little bit of time. So now, after we have published, we need to change this link. So if you remember, in application when we were creating the application, we had environments folder. And I told you that we have two types of environments where we are going to use. One is for production, and here we were placing our API URL and one for local development. And we put four in that time for both, the same, just in case that we are going to build the production. But now we came to that moment. We need to replace. The link which is created for local host here. But on environment prod file, we need to change it to our Heroku link. So here I will replace http localhost 3000 with the link which I had from Heroku application. So we will have this one and this will be my production. So when we save that, it will be saved for all our applications. We need to build the project again. But here, after building the project again, we need to use a flag which is called broad. Like build, broad action. I need the production beyond. I don't want the normal build, the development beyond because here we have steel, the development built. We don't have the production one. As you see, we have here undo on in it. And all of source code is available here because this is development, build is not production. And the bundle size of this, it's very big because it's not compressed. So that production is grown bone pressing for me all the files. And it will be minified and it will be faster, especially for weak internet connections. So for that, we need to flag our command here with a broad, we don't have to use an expelled in a job. Only what we need also to flag it with abroad. It's exactly the same comment. So after that, we run the command. And as you see that NX start to run any shop build production. You see the Gorman is changed. We have now the production and it's going to use the environment, the files. So now our build is done. And as you see here, if we go to docs, we have a new files and they are always some hashing for preventing their cash. And as well, we have the index HTML got updated and as well the previous files where it got deleted. So for that we need to push those files. So let's go again to our GitHub Desktop after we made all of those changes. And then as you see, there are multiple changes done. Some files got deleted, which are from the old build, and we have created a new file. So we need to create a new message. We can give it a name like change to production build. So in this case we will have the change to production build and we push it to GH Pages, and then we push that code here. Sometimes you get this message that you need to fetch. The remote changes. So you just say pull again and then you can just push again. So because sometimes GitHub is adding some variables or some files based on the build with GitHub Pages. So after that, we have deployed everything. We go again to our GitHub Pages and we refresh. We need to wait awhile because here is saying your site is ready to be published. We have to wait for awhile until it gets published to the domain here. Okay, it says here that my website got published. So I go again to our candy shop, refresh. Okay, we still have this problem. We still don't see even the files got published as you see here in the source, we still have that problem. So we need somehow to solve this issue. So as you see, if you remember that we were using in Angular decent file for every project, for example, I have Admin application. I was seeing when you want to build the application just to replace the files which are called environment Ts with environment broad dot ds, UC. We are replacing those files. And those files, if you remember, we have edited them. One is for production and one is for development. But the case happened only for the admin application. We need as well to do the same for the NG shop application. So I need to go to and you shop application. I will scroll up here. We have N D sharp application. And then it's still using the old configuration because we didn't update them. So I made this mistake by, by purpose just to show you that if you don't have because I got a lot of questions about that previously. So you just be sure that you are replacing this, the old one. If you go back to the environment variables lecture, you need to be sure that you also not using the application specific environment, but you use the one which is public and shared. So we have this one here. And then we need to run the build comment again. So we have to be careful that we have to have this as abroad and then run the comment of production. So here they're built finished. Again, we need to commit the changes, which we have none again. So afforded that, we need, again, we have to make a commit message. We can say change files, so we can say here. And then we commit to GitHub Pages. We push, and we have to wait again for the deployment of our application. So when I go to GitHub Pages, refresh and I will see that it's going to be built. It will change this to green when the build is ready. Okay, as you see here, the application got deployed. Let's go again to the link of our ND shop online on GitHub pages. We refresh, we see that we don't get any error. Finally, so we go here, we close the console, and here is our application. So if we go again to the back end or to their network again and refresh, we will see that our network is asking from here or cooling. So we have here the Heroku thing up. So from that API, we are consuming our data. So this is how it's very nice. Now, we have all the application is functioning. I have Add to Cart, Add to Cart. I go to my cart. And as you see, the speed is very great. It's like I am running the project on local. It's very fast and consuming very good and forming very good. So in this way, we build the application to GitHub pages so you can send this link to anyone you want to visit for your application. So the question is, I want also to build the Admin application, how I can build it. So we need to build the application of the NDI shop and also the application of the admin panel, which we have created previously. Unfortunately, that GitHub Pages is linked only with one repository. So we can, we cannot create here multiple pages under one repository. So for that, you need to create another repository, which you can call it E-sharp admin. And in that case, you can be able to deploy your changes there. Or you can manage your deployment in a way that the GitHub is going to use the buffers which are deployed from your environment. You don't have to deploy all the code, all the source code. You can just push the code which is generated by dogs. And this, what we can see in the next lecture, I am going to do it in front of you quickly. 197. Building Multiple APP's, Create Scripts: Okay, in this lecture we are going to make a bill for multiple applications. So if you want first that you don't have to upload your source code to GitHub. You can only upload the build, production of your project folder that as I told you, we are going to create two repositories for one is ND shop and one for the admin panel application. So, but first, we need to specify a path which is not inside the repository which I have created inside our, like our source code, we are making it outside of our source code. So we can specify the path in the comment like this. We can go one step up like this. So we can say go out of the current folder, which is now blue bits, that organization the source file and create an application which is called NG shop for example. So we can create this one as N G sharp. And we can base bath, which can be also NG shop. So in that case, we have to be sure to create a repository exactly with this name. Remember that? So we press Enter and our application is going to build itself until the build finish. You see here that I am inside my organization folder. So I need to go one step up. Like outside of our repository, you don't have to put it inside the same of that repository. So after the bill got finished, we need as well to go to our folders here as we see, and go one step up. And we will see that we have N D sharp here. So I have now my file productions are here. So I don't need to have our upload the source code. So this one will be, are going to create a repository for it. So we can use GitHub Pages for deploying this one. So how we can do that? Again, we will do the same steps which we did previously. We are going not to use this repository, but we will use a new one. We will say create a new repository. So we click on create a new repository. And this repository name will be exactly the same name of our folder. So we have here N D sharp, as I told you previously, and where we have to choose the path, it will be exactly on the same route here. So in one step up of our source file where it's deployed so I can't see the folder. I don't enter inside. No, I can't see the folder itself here. So I click Open, same name here, I click Create Repository. And in that case, we will have our repository created. And then we just need to say Publish repository. We keep the same name. And as well, we say Publish repository, but we need to make it public. In that case, I will show you that if I go now to my GitHub account, I will not have the source code in that category. So I can keep my previous code of the source like this one which we created for the e-shop. We can keep this one as a private. You don't have to put it in public, but a new repository which is created, as you see here we go to repositories. And then I will have N D sharp here. So as you see, I have only those source files here. I don't sorry, the production files. We will not have the source code here and it's public. So I don't care because they are hashed and they are minimized as you see here, which is not easy for normal or the users to fetch out my source code again. So in this way, I go to the sitting and then I'm going to pages. And then we will say the source will be like Directory, you can say main, and then the root itself. So you don't have to use docs folder, you can say route because we build directly on the root of that project. So you just need to specify the path and as well the branch. So I keep it on the main branch because we have only one brand, of course you can create another plant, but in this case we don't need because we have only the production files. And after that, we wait until their website is published. We say, okay, your site is published. I go again here to the website and I will see it produced previously. And here the path which is ND shop. So I can go back to our repository, which I had for the end you shop and I can close it, I can make it private. So we have sodium for the previous test which we did before. So the E sharp, I am going to make it as a private so you can't go again to Settings. You can say that here security or manage access. And then you put your password again. I have here confirm password. And then I will change the access repository not to be public, but I want to put it as a private. I will go here to change repository visibility. I will put it as a private. And then I understand this change. We just copy this part. So in that case, nobody will see my For example, the source code, because I have already repository for the public or the production code which is published for published page or GitHub pages. So let's do the same again for the admin application. So first of all, we need to use again the same comment, but not with NDI shop. We are going to make it with the Admin application. But let me show you a trick. It's not necessarily always to do this command. Always, always. We can do a weight like we can save this comment in package JSON inside my project. Like we can create a new build for here. So we can say, for example, I create a new script in the package JSON. I say, for example, build broad, for example, in that way, like admin. So we can say admin panel, admin panel application. And the comment for that will be exactly the comment which we used here. But we need to replace that with admin and as well here with admin as well. And I say NX build the Admin application, not the product or application. The same thing we can do as well for our M built off a N D shop itself. So you don't have to save this comment somehow. You can just say, brought build a proud admin all beard abroad. The application which is N G sharp for example. So in that case you don't have to write all of these lines aren't a comment. So we fix that. We picked here another comma. We save everything. And now I am going to run the command which I have for like the production built for the admin. So how we can do that? I just say npm run and I specify the command which I want to run. I will say build, but odd. And then admin. And then we will see that it's going to execute this comment, which is so great for me. So after that, the application got built, but the admin one. So let's go again to our GitHub desktop and create a new repository. The same steps which we did with the NDI shop. So I will go here. I will see all my repositories. This one contain my source code, this contain the NG shop, but the production bill. And I'm going to add another one for the admin production build. So here we have to create another name, admin, exactly the same names, how we build them previously. Check the path. I think it's built already. We have here the admin build. And again, we go to create the repository. And we see that our repository got created. We publish the repository and then we need to make it as public. We don't have to keep it as a private. So then we create or publish the repository which we want. And then we go to our GitHub account and go to our repositories. We will see the admin repository again here. So I will click on it. I will see that built for that. I will go for the settings, I will go to the pages. And then on the pages I will choose the main branch and then the root folder. And then I will click on Save. After that, the website is getting ready for to be built. And then we will check it in the admin application when it gets ready. So the site is published at this link, we click on it. Okay, We have the admin and everything is fine. Let's try to login. I will have here my credentials. So we have here my password, I click on Submit. Nice, I have here the admin, exactly how we have it in our application when we were developing it. And everything is working perfectly and smoothly. So this is all about the production build. If you want me to make for you the application to run on custom server using FTP. I think this is will be easy for you. If you want me to do a video, you can send me a message or you can add some question in QA. And I am going to add a video for the FTP upload so you can see how we can build our application on custom server, not on GitHub Pages. I'm going as well to attach this file package JSON, how it got updated with those comments. So you can use those comments as well to build your application.