0

I follow Angular tutorial from documentation, and it came to routing. This is a trial example application, and main differece is that my example is integrated with ASP.NET Core 2.2 web app and Angular components are displayed in .cshtml view.

Please note, that I use Angular components selectors in my ASP.NET Core views like this in index.cshtml, where all Angular views are rendered in there:

Index View

<current-time></current-time>
<app-top-bar></app-top-bar>
<app-product-list></app-product-list>

All was displayed fine, until I was trying to add routing to ProductListComponent in product-list.component.html:

    <h2>Products</h2>

<div *ngFor="let product of products">

  <h3>
    <a [title]="product.name + ' details'" [routerLink]="['/products', product.productId]">
      {{ product.name }}
    </a>
  </h3>

  <p *ngIf="product.description">
    Description: {{ product.description }}
  </p>

  <button (click)="share()">
    Share
  </button>

  <app-product-alerts [product]="product"
                      (notify)="onNotify()">
  </app-product-alerts>

</div>

And the ProductListComponent is declared in app.module.ts as follows:

import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { APP_BASE_HREF } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';

import { CurrentTimeComponent } from './current-time/current-time.component';
import { TopBarComponent } from './top-bar/top-bar.component';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductAlertsComponent } from './product-alerts/product-alerts.component';
import { ProductDetailsComponent } from './product-details/product-details.component';

@NgModule({
  declarations: [
    CurrentTimeComponent,
    TopBarComponent,
    ProductListComponent,
    ProductAlertsComponent,
    ProductDetailsComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule,
    RouterModule.forRoot([
      { path: '', component: ProductListComponent },
      { path: 'products/:productId', component: ProductDetailsComponent },
    ])
  ],
  exports: [
    CurrentTimeComponent,
    TopBarComponent,
    ProductListComponent
  ],
  providers: [{ provide: APP_BASE_HREF, useValue: '/' }], //for ASP.NET Core
})
export class AppModule {
  constructor(private injector: Injector) {
  }

  ngDoBootstrap() {
    customElements.define('current-time', createCustomElement(CurrentTimeComponent, { injector: this.injector }));
    customElements.define('app-top-bar', createCustomElement(TopBarComponent, { injector: this.injector }));
    customElements.define('app-product-list', createCustomElement(ProductListComponent, { injector: this.injector }));
  }
}

According to the tutorial, when hovering mouse pointer over product in product-list view, I should receive anchor path: http://localhost:59119/products/1, but instead of this I have: http://localhost:59119/products/undefined.

Another thing is that when navigating my browser to http://localhost:59119/products/1 i receive 404.

Please note, that in my app.module.ts I have no bootstrap: [ AppComponent]. I assumed, that if Angular views are displayed by .cshtml views, I do not need this. Does it change anything? I start to suspect that yes.

Anyway, is there any way to make my navigation to the product details working?

product-details.component.ts:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { products } from '../products';

@Component({
  selector: 'app-product-details',
  templateUrl: './product-details.component.html',
  styleUrls: ['./product-details.component.css']
})
export class ProductDetailsComponent implements OnInit {
  product;

  constructor(
    private route: ActivatedRoute,
  ) { }

  ngOnInit() {
    this.route.paramMap.subscribe(params => {
      this.product = products[+params.get('productId')];
    });
  }

}

productc.ts:

export const products = [
  {
    productId: 1,
    name: 'Phone XL',
    price: 799,
    description: 'A large phone with one of the best screens'
  },
  {
    productId: 2,
    name: 'Phone Mini',
    price: 699,
    description: 'A great phone with one of the best cameras'
  },
  {
    productId: 3,
    name: 'Phone Standard',
    price: 299,
    description: ''
  }
];

product-list.component.ts:

import { Component, OnInit } from '@angular/core';

import { products } from '../products';

@Component({
  selector: 'app-product-list',
  templateUrl: './product-list.component.html',
  styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit {
  products = products;

  share() {
    window.alert('The product has been shared!');
  }

  onNotify() {
    window.alert('You will be notified when the product goes on sale');
  }

  constructor() { }

  ngOnInit() {
  }
}
5
  • For the second question, it appears that product.productId doesn't exist. Can you post product-list.component.ts in your question? Commented Jul 21, 2020 at 19:01
  • 1
    @bakunet, you can not do it in this way. Your main.app.module has a bootstrap tag. This is the component you need in your index.chtml (the selector of this component) Commented Jul 21, 2020 at 19:09
  • @Eliseo I added to app.module.ts bootstrap: [ProductListComponent], and same result. Commented Jul 21, 2020 at 19:14
  • Ill try to play with this kind of routing, we will see... stackoverflow.com/a/49414757/12603542 Commented Jul 21, 2020 at 19:33
  • @Eliseo Allright, I noticed now, that my approach was completly wrong. Actually, instead of using single components in my ASP app, I should use maybe several Angular apps, and make routing inside of them. I see, that the way I wanted to do it, is not supported, or lets say it differently, I was doing it wrong :) Commented Jul 21, 2020 at 20:14

1 Answer 1

1

For the First question which you have asked in getting undefined

http://localhost:59119/products/undefined

for this you have to update you html -

<div *ngFor="let product of products">

  <h3>
    <a [title]="product.name + ' details'" [routerLink]="['/products', productId]">
      {{ product.name }}
    </a>
  </h3>(...)

</div>

here productId is not defined that's why you are getting an error.

for the second question in which you are getting a 404 because here

  { path: 'products/:productId', component: ProductDetailsComponent },

as you can see for that path ProductDetailsComponent is defined for that route and angular doesn't route to cshtml files.

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

10 Comments

Ad 1) if products are iterated with <div *ngFor="let product of products">, the ID is not specified implicit in TS? Ad 2) Should not it be routed inside of SPA, somehow?
productId was not defined anywhere in your code.can you check the object of product if the id is coming there and use that id in html like product.id.
I just updated question body with products collection definition in products.ts. Actually there is no productId, but when added, I have the same result.
if there is no productid how you gonna route using that id?
In html you have to use product.productId in router link
|

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.