0

I have a small problem. I want to pass data from my products, to my single product page. So I have a products page with 10-15 products to display with title of the product, small description, picture and a button for more info. When I click on that button I want to be redirected to that product page. So it says localhost:4200/product/productTitle1 and its picture, description and title can be used on that page like {{ title }}.

So I have products component.html

<div *ngFor="let product of productList.products" class="col-sm">
 <div class="card mt-5" style="width: 20rem;">
  <div class="card-body">
    <h4 class="card-title">{{ product.title }}</h4>
    <h6 class="card-subtitle mb-2 text-muted">{{ product.subtitle }}</h6>
    <img [src]="product.imageUrl" class="card-text img-fluid">{{ product.cardText }}<br>
    <a [routerLink]="['/product', product.title]" class="card-link btn btn-outline-primary btn-sm mt-3">More info</a>
    <a href="#" class="card-link btn btn-info btn-sm mt-3">Add to cart</a>
  </div>
</div>

with routerLink that shows product title in the link and redirect me to his product info page

[routerLink]="['/product', product.title]

and here is single product.component.ts

export class ProductComponent implements OnInit{
  title: string;
  subtitle: string;
  cardText: string;

constructor(
  private productList: ProductService, 
  private route: ActivatedRoute) { }

ngOnInit() {
  let params = this.route.snapshot.paramMap;
  this.title  = params.get('title');
  this.subtitle  = params.get('subtitle');
  this.cardText = params.get('cardText');
 }
}

and product.service.ts that contain all product informations.

@Injectable()
export class ProductService {
  products: any[] = [
{
  id: 1,
  title: 'Some title',
  subtitle: 'Some subtitle',
  imageUrl: './assets/images/main-image.jpg',
  cardText: 'Some descriptive text'
},
{
  id: 2,
  title: 'Some title about second product',
  subtitle: 'Some subtitle 2',
  imageUrl: './assets/images/prod-cop.png',
  cardText: 'Some text'
}, ...

The thing is that I can't see any information about that product on single product page except the {{ title }}. But I noticed that if I type like this routerLink =['/product', product] I can access all the information with snapshot but the link will contain all the information as well, which looks bad. I am still beginner in Angular so I need your help.

3 Answers 3

1

As you already have a service you do not have to pass the data from route. just get the product id from route parameters and find the product from your product service

export class ProductComponent implements OnInit{
 product: any;

constructor(
  private productList: ProductService, 
  private route: ActivatedRoute) { }

ngOnInit() {
  const productId = route.snapshot.params['productId'];
  this.product = this.prodcutList.products.find((product)=>{
   return product.id === productId
   });
 }
}

now generate the link

 <a [routerLink]="['/product']" [queryParams]="{productId: product.id}">More info</a>

your ProductComponent HTML template can now use the product object

Sign up to request clarification or add additional context in comments.

14 Comments

Thanks for answer! But I am getting 2 syntax errors. Property 'find' does not exist on type 'ProductService' and product: Product.
Sorry there was a typo find is a function on array. fixed the answer
Yeap, the find() is fixed! But product: Product still gives an error. "Cannot find name 'Product'."
For some reason when I use {{ product.title }} at my template with your code it gives a error ERROR TypeError: Cannot read property 'title' of undefined
Thanks but it still gives me a "Cannot read property title of undefined". When I print "this.product" it also gives me undefined
|
0

You need to pass id in the url [routerLink]="['/product', product.id] and you add a new method on you service like getProductById(id) by calling it in your single product page

Comments

0

If you want to hide the information shown in route, you can use skipLocationChange flag as below

this.router.navigateByUrl("/product/"+id,{skipLocationChange:true});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.