angularroutesangular2-routingangular2-router

Angular 2 Routing with parameter undefined


I'm trying to create a route in Angular 2 that takes me to data of a json file, depending on the id. For instance I have 10001.json, 10002.json, 10003.json, etc...

People should be able to get to their patientfile by typing in that particular id as an url, but so far that's not working. I'm actually getting :

GET http://localhost:4200/assets/backend/patienten/undefined.json 404 (Not Found)

This is my patientcomponent:

import { Component, OnInit } from '@angular/core';
import {PatientService} from "../patient.service";
import {Patient} from "../models";
import {ActivatedRoute, Params} from "@angular/router";
import 'rxjs/add/operator/switchMap';

@Component({
  selector: 'app-patient',
  templateUrl: './patient.component.html',
  styleUrls: ['./patient.component.sass']
})
export class PatientComponent implements OnInit {

  patient:Patient[];
  id:any;

  errorMessage:string;

  constructor(private patientService:PatientService, private route: ActivatedRoute) { }

  ngOnInit():void {
    this.getData();
    this.id = this.route.params['id'];
    this.patientService.getPatient(this.id)
      .subscribe(patient => this.patient = patient);

  }

  getData() {
    this.patientService.getPatient(this.id)
      .subscribe(
        data => {
          this.patient = data;
          console.log(this.patient);
        }, error => this.errorMessage = <any> error);


  }
}

This is the routing, very basic:

import {Routes} from "@angular/router";
import {AfdelingComponent} from "./afdeling/afdeling.component";
import {PatientComponent} from "./patient/patient.component";



export const routes: Routes = [
  {path: '', component: AfdelingComponent},
  {path: 'patient/:id', component: PatientComponent}

];

And the service:

import { Injectable } from '@angular/core';
import {Http, RequestOptions, Response, Headers} from '@angular/http';
import {Observable} from "rxjs";
import {Patient} from "./models";

@Injectable()
export class PatientService {
  private patientUrl = "/assets/backend/patienten/";
  constructor(private http: Http) { }

  getPatient(id:any): Observable<Patient[]>{
    return this.http.get(this.patientUrl + id + '.json' )
        .map(this.extractData)
        .catch(this.handleError);
  }


  private extractData(res: Response) {
    let body = res.json();
    return body || { };
  }

  private handleError(error: any): Promise<any> {
    console.error('An error occurred', error);
    return Promise.reject(error.message || error);
  }

  addPatient(afdelingsNaam: string, afdeling: any): Observable<Patient> {
    let body = JSON.stringify({"afdelingsNaam": afdelingsNaam, afdeling: afdeling});
    let headers = new Headers({'Content-Type': 'application/json'});
    let options = new RequestOptions({headers: headers});
    return this.http.post(this.patientUrl, body, options)
      .map(res => <Patient> res.json())
      .catch(this.handleError)
  }
}

Solution

  • The problem is that you call getData before this.id is populated. Just change places

    ngOnInit():void {
      this.id = this.route.params['id'];
      this.getData();
      this.patientService.getPatient(this.id)
        .subscribe(patient => this.patient = patient);
    
      }
    

    Edited: route.params is an Observable, so you need to use it like:

    this.sub = this.route.params.subscribe(params => {
       this.id = +params['id']; // (+) converts string 'id' to a number
    
       // In a real app: dispatch action to load the details here.
    });