Issue
Here is my routes in app.module.ts file
Look at the {path: 'category/:id/:maxPrice', component: ProductListComponent},
/** Define the routes */
const routes: Routes = [
{path: 'selling/:id', component: ProductUpdateComponent, canActivate: [OktaAuthGuard]},
{path: 'selling', component: SellingComponent, canActivate: [OktaAuthGuard]},
{path: 'sell-item', component: SellItemComponent, canActivate: [OktaAuthGuard]},
{path: 'help', component: HelpComponent},
{path: 'contact-us', component: ContactUsComponent},
{path: 'about-us', component: AboutUsComponent},
{path: 'login/callback', component: OktaCallbackComponent},
{path: 'login', component: LoginComponent},
{path: 'orders-history', component: OrdersHistoryComponent, canActivate: [OktaAuthGuard]},
{path: 'members', component: MembersPageComponent, canActivate: [OktaAuthGuard]},
{path: 'checkout', component: CheckoutComponent, canActivate: [OktaAuthGuard]},
{path: 'cart-details', component: CartDetailsComponent},
{path: 'products/:id', component: ProductDetailsComponent},
{path: 'search/:keyword', component: ProductListComponent},
{path: 'category/:id', component: ProductListComponent},
{path: 'category/:id/:condition', component: ProductListComponent},
{path: 'category/:id/:maxPrice', component: ProductListComponent},
{path: 'category', component: ProductListComponent},
{path: 'products', component: ProductListComponent},
{path: '', redirectTo: '/products', pathMatch: 'full'},
{path: '**', redirectTo: '/products', pathMatch: 'full'}
];
This is the function where i am passing categoryId and maxPrice param value:
- const url is the router url
- this.currentCategories = categoryId
- this.sliderValue = maxPrice
/**
*
*/
onPriceSliderChange() {
this.resetConditionFilter();
console.log("Slider Value: " + this.sliderValue);
const url = `/category/${this.currentCategories}/${this.sliderValue}`;
console.log("slider url: " + url);
this.router.navigateByUrl(url);
}
This is the function where i am trying to receive the categoryId and maxPrice param value that has been passed from onPriceSliderChange() function:
I get the categoryId but maxPrice value is missing
/**
* Get list of products by product category id through productService
* And store the data to products list
* Support Pagination
*/
handleListProducts() {
// check if "id" parameter is available for category id
const hasCategoryId: boolean = this.route.snapshot.paramMap.has('id');
// check if "condition" parameter is available for product condition
const hasCondition: boolean = this.route.snapshot.paramMap.has('condition');
// check if 'maxPrice' parameter is available for max price selected from price range slider
//const hasMaxPrice: boolean = this.route.snapshot.paramMap.has('maxPrice');
const hasMaxPrice: boolean = this.route.snapshot.paramMap.has('maxPrice');
// debugging
console.log("category id: " + hasCategoryId);
console.log("max price: " + hasMaxPrice);
// if Id is available
if (hasCategoryId) {
// get the "id" param string. convert string to a number using the "+" symbol
this.currentCategoryId = +this.route.snapshot.paramMap.get('id');
}
// check if condition is available
if (hasCondition) {
// get the "condition" param string.
this.condition = this.route.snapshot.paramMap.get('condition');
}
// check if max price is available
if (hasMaxPrice) {
// get the "maxPrice" param string.
this.maxPrice = +this.route.snapshot.paramMap.get('maxPrice');
console.log("category id: " + this.currentCategoryId);
console.log("max price: " + this.maxPrice);
}
//
// Check if we have a different category than previous
// Note: Angular will reuse a component if it is currently being viewed
//
// if we have a different category id than previous
// then set thePageNumber back to 1
if (this.previousCategoryId != this.currentCategoryId) {
this.thePageNumber = 1;
}
this.previousCategoryId = this.currentCategoryId;
// Angular Pagination component: pages are 1 based
// Spring Data REST: pages are 0 based
if (hasCategoryId && hasCondition) {
this.productService.getProductsByCondition(this.condition,
this.currentCategoryId,
this.thePageNumber - 1,
this.thePageSize)
.subscribe(this.processResult());
} else if (hasCategoryId && hasMaxPrice) {
console.log("id: " + this.currentCategoryId + "price: " + this.maxPrice);
this.productService.getProductByPriceRange(this.currentCategoryId,
0,
this.maxPrice,
this.thePageNumber - 1,
this.thePageSize)
.subscribe(this.processResult());
} else {
// Now get the products for the given category "id"
this.productService.getProductListPaginate(this.thePageNumber - 1,
this.thePageSize,
this.currentCategoryId)
.subscribe(this.processResult());
}
}
My Components:
This is the ProductCategoryMenuComponent where I am sending the maxPrice value from:
import { Options } from '@angular-slider/ngx-slider';
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ProductCategory } from 'src/app/common/product-category';
import { ProductService } from 'src/app/services/product.service';
@Component({
selector: 'app-product-category-menu',
templateUrl: './product-category-menu.component.html',
styleUrls: ['./product-category-menu.component.css']
})
export class ProductCategoryMenuComponent implements OnInit {
// list of product category to display on category menu
productCategories: ProductCategory[];
currentCategories: number = 1;
sliderValue: number = 500;
options: Options = {
floor: 0,
ceil: 500
};
constructor(private productService: ProductService,
private router: Router,) { }
ngOnInit(): void {
this.listProductCategories();
}
/**
* get list of product categories
*/
listProductCategories() {
this.productService.getProductCategories().subscribe(
data => {
this.productCategories = data; // set data to productCategories array
}
);
}
/**
* Get current categories
* @param categoryId
*/
getCurrentCategories(categoryId: number) {
this.currentCategories = categoryId;
// reset condition and price filter when catgory is changed
this.resetConditionFilter();
this.resetPriceSlider();
}
/**
*
*/
resetConditionFilter() {
// reset product condition radio button
const newElement = document.getElementById("new") as HTMLInputElement;
newElement.checked = false;
const usedElement = document.getElementById("used") as HTMLInputElement;
usedElement.checked = false;
}
/**
*
*/
resetPriceSlider() {
this.sliderValue = 500;
}
/**
*
* @param condition
*/
onCondition(condition: string) {
if(condition === 'New') {
const url = `/category/${this.currentCategories}/New`;
this.router.navigateByUrl(url);
} else if (condition === 'Used') {
const url = `/category/${this.currentCategories}/Used`;
this.router.navigateByUrl(url);
}
}
/**
*
*/
onPriceSliderChange() {
this.resetConditionFilter();
console.log("Slider Value: " + this.sliderValue);
const url = `/category/${this.currentCategories}/${this.sliderValue}`;
console.log("slider url: " + url);
this.router.navigateByUrl(url);
}
}
This is ProductListComponent where I am trying to get the maxPrice param value:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { CartItem } from 'src/app/common/cart-item';
import { Product } from 'src/app/common/product';
import { CartService } from 'src/app/services/cart.service';
import { ProductService } from 'src/app/services/product.service';
/**
*
*
*
*/
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit {
products: Product[] = []; // products list
currentCategoryId: number = 1; // current category Id
previousCategoryId: number = 1; // previous category Id
searchMode: boolean = false; // search mode to see if any search has been done.
condition: string;
maxPrice: number;
// New properties for pagination
thePageNumber: number = 1;
thePageSize: number = 12;
theTotalElements: number = 0;
previousKeyword: string = null;
constructor(private productService: ProductService,
private route: ActivatedRoute,
private cartService: CartService) { }
ngOnInit(): void {
this.route.paramMap.subscribe(() => {
this.listProducts();
});
}
/**
* Get list of products by product category id through productService
* And store the data to products list
*/
listProducts() {
// check to see if any parameter has been passed from searchComponent
this.searchMode = this.route.snapshot.paramMap.has('keyword');
// check if searchmode is true
// If true then handle search products
// else return products list
if(this.searchMode) {
this.handleSearchProducts();
} else {
this.handleListProducts();
}
// after reloading the component move to top of the page.
window.scrollTo(0,0);
}
/**
* get list of products based on search keyword
*/
handleSearchProducts() {
// get the keyword that has been passed by searchComponent
const theKeyword: string = this.route.snapshot.paramMap.get('keyword');
// if we have a different keyword than previous
// then set thePageNumber to 1
if (this.previousKeyword != theKeyword) {
this.thePageNumber = 1;
}
this.previousKeyword = theKeyword;
console.log(`keyword=${theKeyword}, thePageNumber=${this.thePageNumber}`);
// now search for the products using keyword
this.productService.searchProductListPaginate(this.thePageNumber - 1,
this.thePageSize,
theKeyword).subscribe(this.processResult());
}
/**
* Get list of products by product category id through productService
* And store the data to products list
* Support Pagination
*/
handleListProducts() {
// check if "id" parameter is available for category id
const hasCategoryId: boolean = this.route.snapshot.paramMap.has('id');
// check if "condition" parameter is available for product condition
const hasCondition: boolean = this.route.snapshot.paramMap.has('condition');
// check if 'maxPrice' parameter is available for max price selected from price range slider
//const hasMaxPrice: boolean = this.route.snapshot.paramMap.has('maxPrice');
const hasMaxPrice: boolean = this.route.snapshot.paramMap.has('maxPrice');
// debugging
console.log("category id: " + hasCategoryId);
console.log("max price: " + hasMaxPrice);
// if Id is available
if (hasCategoryId) {
// get the "id" param string. convert string to a number using the "+" symbol
this.currentCategoryId = +this.route.snapshot.paramMap.get('id');
}
// check if condition is available
if (hasCondition) {
// get the "condition" param string.
this.condition = this.route.snapshot.paramMap.get('condition');
}
// check if max price is available
if (hasMaxPrice) {
// get the "maxPrice" param string.
this.maxPrice = +this.route.snapshot.paramMap.get('maxPrice');
console.log("category id: " + this.currentCategoryId);
console.log("max price: " + this.maxPrice);
}
//
// Check if we have a different category than previous
// Note: Angular will reuse a component if it is currently being viewed
//
// if we have a different category id than previous
// then set thePageNumber back to 1
if (this.previousCategoryId != this.currentCategoryId) {
this.thePageNumber = 1;
}
this.previousCategoryId = this.currentCategoryId;
// Angular Pagination component: pages are 1 based
// Spring Data REST: pages are 0 based
if (hasCategoryId && hasCondition) {
this.productService.getProductsByCondition(this.condition,
this.currentCategoryId,
this.thePageNumber - 1,
this.thePageSize)
.subscribe(this.processResult());
} else if (hasCategoryId && hasMaxPrice) {
console.log("id: " + this.currentCategoryId + "price: " + this.maxPrice);
this.productService.getProductByPriceRange(this.currentCategoryId,
0,
this.maxPrice,
this.thePageNumber - 1,
this.thePageSize)
.subscribe(this.processResult());
} else {
// Now get the products for the given category "id"
this.productService.getProductListPaginate(this.thePageNumber - 1,
this.thePageSize,
this.currentCategoryId)
.subscribe(this.processResult());
}
}
/**
* Map data from JSON response to property defined in this class and assign data to their properties
*/
processResult() {
return data => {
this.products = data._embedded.products;
this.thePageNumber = data.page.number + 1; // Spring Data rest page are 0 based & Angular page are 1 based.
this.thePageSize = data.page.size;
this.theTotalElements = data.page.totalElements;
}
}
/**
* Update the page size selected by user
* @param pageSize
*/
updatePageSize(pageSize: number) {
this.thePageSize = pageSize;
this.thePageNumber = 1;
this.listProducts();
}
/**
*
* @param product
*/
addToCart(product: Product) {
console.log(`Adding to cart: + ${product.name}, ${product.unitPrice}`);
//
const theCartItem = new CartItem(product);
this.cartService.addToCart(theCartItem);
}
}
Solution
using router navigate, can pass values from one component to another as below
while passing values from onPriceSliderChange
this.router.navigate(['/category', { id: categoryId, maxPrice:maxPriceValue}]);
in ngOnIt at receiver
ngOnInit() {
this._route.params.subscribe((params) => {
this.currentCategoryId = params['id'];
this.maxPrice = params['maxPrice']);
})