1

I am trying to implement the routing in my app. My goal is simple: after clicking on one of the rows of my table, the app should show the specific details of the selected row (speedway rider in this case).

I'm stuck on the point where the path after click works correctly, but the page returns no data with the following information in the console:

ERROR TypeError: Cannot read property 'id' of undefined

I have a feeling that I almost there, but after hours of combinations I decided to ask for help. More code below, I would be grateful for any ideas :)

service.ts

  getRider(id) : Observable<Rider> {
    return this._http
      .get("http://node.gurustats.usermd.net:60519/pgee2020" + `/${id}`)
      .map(result => (this.result = result.json().data));
  }

subpage.ts

import { Component, OnInit } from "@angular/core";
import { Rider } from "../interfaces/rider";
import { SpeedwayService } from "../../speedway.service";
import { ActivatedRoute } from "@angular/router";

@Component({
  selector: "gs-zawpgee2020",
  templateUrl: "./zawpgee2020.component.html",
  styleUrls: ["./zawpgee2020.component.less"]
})
export class ZawPgee2020Component implements OnInit {
  rider: Rider;

  constructor(
    private _speedwayService: SpeedwayService,
    private route: ActivatedRoute){}

ngOnInit() {
  this.loadZaw();  
}

loadZaw() {
  const id = +this.route.snapshot.params['id'];
  this._speedwayService.getRider(id).subscribe((rider) => {
    this.rider = rider;
})}}

subpage.html

<gs-header>
  <p logo><img src="assets/logo PGEE.jpg" /></p>
  <p levels>HISTORIA MECZÓW - {{ rider.id }}</p>

</gs-header>

data structure (server.js)

// 20210312220521
// http://node.gurustats.usermd.net:60519/pgee2020

{
  "status": 200,
  "message": null,
  "data": [
    {
      "_id": "604a882ed87fdb0482536fc9",
      "MSC": 3,
      "ZAWODNIK": "Bartosz Zmarzlik",
      "KLUB": "Gorzów",
      "SREDNIA": 2.43,
      "id": 103
...

[routerlink] & path: "pgee20/:id" are also coded

4
  • Try using paramMap instead this.route.paramMap.get('id'). According to Angular params will be deprecated. angular.io/guide/… Maybe it already has? Commented Mar 12, 2021 at 21:40
  • I tried, but I got the message: Property 'get' does not exist on type Observable<ParamMap> Commented Mar 12, 2021 at 22:00
  • Ah sorry, was going based off my head, probably need to add snapshot so like this.route.snapshot.paramMap.get('id'); Commented Mar 12, 2021 at 22:14
  • @penleychan The params in this.route.snapshot.params['id'] is the params property of ActivatedRouteSnapshot class. The linked documentation is about params property of ActivatedRoute class. Commented Mar 12, 2021 at 23:40

2 Answers 2

1

http://node.gurustats.usermd.net:60519/pgee2020/[id-of-some-rider] is not giving you the data of a single rider. That is why the rider variable in your component remains undefined.

http://node.gurustats.usermd.net:60519/pgee2020 gives you data in the following shape -

{"status":200,"message":null,"data":[{rider1-data}, {rider1-data}, ...]}

and you can get the data of a specific rider by applying filter on the data array. Also, the response you receive is not really of Rider type. Therefore, you need to change the return type of your service method to Observable<any>.

Change your service method to -

getRider(id) : Observable<any> {
    return this._http
        .get<any>("http://node.gurustats.usermd.net:60519/pgee2020")
        .map(result => result.data.filter(p=> p.id == id)[0]);
}

or, to -

getRider(id) : Observable<any> {
    return this._http
        .get<any>("http://node.gurustats.usermd.net:60519/pgee2020")
        .pipe(
            map(result => result.data.filter(p=> p.id == id)[0])
      );
}

depending on your rxjs version.

Also, in your HTML, use *ngIf to check if rider has a value before accessing its properties -

<gs-header>
    <p logo><img src="assets/logo PGEE.jpg" /></p>
    <div *ngIf="rider">
        <p levels>HISTORIA MECZÓW - {{ rider.id }}</p>
    </div>
</gs-header>
Sign up to request clarification or add additional context in comments.

10 Comments

Thank you for the answer, I understand the source of the issue. However, I tried both of the proposed solutions and I received the error each time. The first one: Property 'data' does not exist on type 'Response'. The second one: Cannot find name 'map'. Did you mean 'Map'?
I imported {map} from rxjs/operators and the second output has changed. I have two problems now. Argument expression expected. Property 'data' does not exist on type 'Response'. rxjs version is 5.5.6
@Rafineria Change Observable<Rider> to Observable<any> because the response you receive is really not a Rider type. I'll update it in the answer.
Thank you for quick response. Unfortunately, errors remain the same.
@Rafineria What is your Angular version?
|
0

As mentioned in comments above, params will be deprecated. So recommend changing the flow to this equivalent code which combined with other answers may solve your problem.

loadZaw() {
    this.route.paramMap.pipe(
        switchMap(routeParaMap => { 
            const id = +routeParaMap.get('id');
            return this._speedwayService.getRider(id);
        }),
        take(1)
    ).subscribe((rider) => {
        this.rider = rider;
    });
}

2 Comments

The params that OP is using is the property of ActivatedRouteSnapshot class, and it has not been a subject of deprecation.
You're right atiyar,there's no deprecation in the OP's code, my mistake. Though I don't see anything changed in your proposed edit.

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.