Angular with PHP & MYSQL to display products list & paging
In the third part of Angular tutorials, you learn to create Angular component and service to display products list from API endpoints, filter products by name and do pagination.
product/product.component.css
Finally, add products route to app-routing.module.ts file.
Angular Tutorial: Upload Form with Files
Execute command below to create produce service in services folder. The product service is used to count products with search text and retrieve product list with search text and a range of specified start and limit parameters from API endpoints. The APIs requires a token to authenticate. So, you need to add the token to the request headers.
ang14-client>ng generate service services/product
services/product.service.ts
import { Injectable } from '@angular/core'; import { HttpClient} from '@angular/common/http'; import { Observable } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; import { HttpHeaders } from '@angular/common/http'; import { AuthService } from '../services/auth.service'; import {api_url_root} from "../app.constants"; import {Router } from '@angular/router'; @Injectable({ providedIn: 'root' }) export class ProductService { constructor(
private router: Router,
private http:HttpClient,
private authservice: AuthService
)
{ this.token=this.authservice.getToken(); }
public products!:any; token:any; baseUrl:string=api_url_root+"api/"; public getDataCount(search: any): Observable<any>{ let headers = new HttpHeaders() .set('Content-Type', 'application/json') .set('Authorization', this.token || '{}'); let url=search?this.baseUrl+"products/count/"+search:this.baseUrl+"products/count"; return this.http.get(url,{'headers':headers}) .pipe( map((response) => { let jsonObj=JSON.parse(JSON.stringify(response)); console.log("data=",jsonObj.data); return(jsonObj.data); }), catchError((err) => { console.error(err); throw err; } ) ) } public getDataLimit(search: string, start:number,limit:number): Observable<any>{ let headers = new HttpHeaders() .set('Content-Type', 'application/json') .set('Authorization', this.token || '{}'); let url=search?this.baseUrl+"products/"+start+"/"+limit+"/"+search: this.baseUrl+"products/"+start+"/"+limit; return this.http.get(url,{'headers':headers}) .pipe( map((response) => { console.log("products list=",response); let jsonObj=JSON.parse(JSON.stringify(response)); return(jsonObj); }), catchError((err) => { console.error(err); throw err; } ) ) } }
Run the following command to create product component.
ang14-client>ng generate component product
product/product.component.ts
import { Component, OnInit } from '@angular/core'; import { ProductService } from '../services/product.service'; import { HttpClient } from '@angular/common/http'; import { ActivatedRoute, Router } from '@angular/router'; import { AuthService } from '../services/auth.service'; @Component({ selector: 'app-product', templateUrl: './product.component.html', styleUrls: ['./product.component.css'], }) export class ProductComponent implements OnInit { products?:any=[]; constructor(private authService: AuthService,private route: ActivatedRoute,private router: Router,private productService:ProductService,private http: HttpClient) { }
start_: number = 0; limit_: number = 3;
total_rows: number = 0;prev_total_rows=0;
public getProductsCount() { this.products=this.productService!.getDataCount(this.search) .subscribe({ next:(response) => { this.total_rows=response; this.prev_total_rows=this.total_rows; }, error: (e) => { console.error('Request failed with error'+e) }, complete: () => { console.error('Request completed') } }); } public getProductsLimit() { this.products=this.productService!.getDataLimit(this.search,this.start_,this.limit_) .subscribe( { next: (response) => { if(response.status===200){ this.products = response.data; if(this.search!='') this.total_rows=this.products.length; // reset total_rows to number of rows matched else this.total_rows=this.prev_total_rows; // restore total_rows } else if(response.status===401){ this.router.navigateByUrl("/login"); } }, error: (e) => { console.error('Request failed with error'+e) }, complete: () => console.info('request complete') } ); } ngOnInit(): void { if(this.authService.isLoggedin()){ this.getProductsLimit(); this.getProductsCount(); } else{ this.router.navigateByUrl("/login"); } } dataset?:any=[]; search: string = ""; public searchByName(){ this.start_=0; // reset start this.getProductsLimit(); } public moveNext = () =>{ if(this.total_rows-this.start_>=this.limit_ && this.total_rows>this.limit_) { this.start_+=this.limit_; this.getProductsLimit(); } } public movePrev = () =>{ if(this.start_-this.limit_>=0 && this.total_rows>this.limit_) { this.start_-=this.limit_; this.getProductsLimit(); } } public canmoveNext(){ return (this.total_rows-this.start_>this.limit_ && this.total_rows>this.limit_) ; } public canmovePrev(){ return (this.start_-this.limit_>=0 && this.total_rows>this.limit_) } }
product/produtct.component.html
<div class="product-list"> <div class="form-group row"> <div class="col-sm-5"> <input type="text" [(ngModel)]="search" placeholder="search" class="form-control" name="search" /> </div><div class="col-sm-2"> <button class="btn btn-primary" type="button" (click)="searchByName()"><span class="material-icons-outlined">search</span></button> </div> <div style="float: right; margin-right: 20px;"> <button class="btn btn-primary" type="button" (click)="addProduct()"><span class="material-icons-outlined">add</span></button> </div> </div> <div><h2><span class="material-icons-outlined plisth">view_list</span> Products List</h2></div> <div class='table-responsive'> <table class='table'> <thead> <tr> <th>ID</th> <th>Name</th> <th>Description</th> <th>Slug</th> <th>Price</th> <th>Category</th> <th>Sub Category</th> <th>Image</th> </tr> </thead> <tbody> <tr *ngFor="let product of products;"> <td>{{product.id}}</td> <td>{{product.name}}</td> <td>{{product.description}}</td> <td>{{product.slug}}</td> <td>{{product.price}}</td> <td>{{product.category}}</td> <td>{{product.subcategory}}</td> <td><img width="50" height="50" src="http://localhost:81/angphp_demo/download.php?fname={{product.thumbnail}}" /></td> <td><a [routerLink]="['/product',product.id]"><span class="material-icons-outlined">edit_note</span></a></td> <td><a [routerLink]="['/products',product.id]"><span class="material-icons-outlined acdelete">delete_forever</span></a></td> </tr> </tbody> </table> <span style="margin-right: 10px;" *ngIf="canmoveNext()"> <button class="btn btn-primary" type="button" (click)="moveNext()">></button> </span> <span *ngIf="canmovePrev()"> <button class="btn btn-primary" type="button" (click)="movePrev()"><</button> </span> </div> </div>
@import 'material-icons/iconfont/outlined.css';
.material-icons-outlined{
display: inline-flex;
vertical-align: middle;
}
.row{
padding-left: 20% !important;
}
.plisth{
font-size: 40px;
}
.acdelete{
color:red;
}
.product-list{
padding-left: 15%;
}
import { ProductComponent } from './product/product.component';
const routes: Routes = [
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'products', component: ProductComponent },
];
Save the project. Log into the app, you should see a list of products, be able to search products by name, and do pagination when the number of products are greater than 3.
Angular Tutorial: Upload Form with Files
Comments
Post a Comment