1

I'm trying to create an app in Angular but I get a "Type 'null' is not assignable to type 'number' error. The problem is that if I try to correct this error by using the "any" parameter in 'id', then the app does not show me the detail when I click on either panel on the front page.

The desired result would be that if I click on any panel:

Desired result

The app should show me the detail:

Desired result 2

This is my code:

service.ts:

import { Observable, of } from 'rxjs';
import { Ejercicio } from './ejercicio';
import { EJERCICIOS } from './collection-ejercicios';

@Injectable({
  providedIn: 'root'
})
export class EjercicioService {

  constructor() { }

  getEjercicios():Observable<Ejercicio[]>{
    return of(EJERCICIOS);
  }
  getEjercicio(id:number):Observable<Ejercicio>{
    console.log("Id solicitado: "+id);
    return of(EJERCICIOS.find(ejercicio=>ejercicio.id===id)!);
  }

}

ejercicio.component.ts:

import { Ejercicio } from '../ejercicio';
import { EjercicioService } from '../ejercicio.service';


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

  ejercicios!: Ejercicio[];
  ejercicioSeleccionado:Ejercicio | undefined;

  constructor(private ejercicioService: EjercicioService) {
    console.log("---Componente Ejercicios CREADO ---");
  }

    getEjercicios():void {
      this.ejercicioService.getEjercicios().subscribe(ejercicios=>this.ejercicios=ejercicios);
    }
  ngOnInit(): void {
  console.log("---Componente Ejercicios[ngOnInit] ---");
   this.getEjercicios();
  }

  onSelectEjercicio(ejercicio: Ejercicio): void {
    console.log("Ejercicio seleccionado="+ejercicio.id);
    this.ejercicioSeleccionado=ejercicio;
  }
}

ejercicio-detalle.component.ts:

import { Component, Input, OnInit } from '@angular/core';
import { Ejercicio } from '../ejercicio';
import { ActivatedRoute } from '@angular/router';
import { EjercicioService } from '../ejercicio.service';

@Component({
  selector: 'app-ejercicio-detalle',
  templateUrl: './ejercicio-detalle.component.html',
  styleUrls: ['./ejercicio-detalle.component.css']
})
export class EjercicioDetalleComponent implements OnInit {


  ejercicio!: Ejercicio;
  constructor(private route:ActivatedRoute, private ejercicioService: EjercicioService) { }

  ngOnInit(): void {
    this.getEjercicio();
  }
  getEjercicio():void{
    const id=this.route.snapshot.paramMap.get('id');
    this.ejercicioService.getEjercicio(id).subscribe(ejercicio=>this.ejercicio=ejercicio)
  }
}

This is the line where I get the eror message:

Error message

I have managed to remove the error by adding id: any in the ejercicio.service.ts file, but in that case when I compile the application I don't get the desired result (the app does not show me the detail when I click on the front panels).

I would appreciate any help.

Thanks,

Elvis
  • 25
  • 5

1 Answers1

0

Since it's possible that paramMap will not contain id, you must check in your code to ensure that it is actually defined. To fix this particular issue, you'll simply need to do a check that it exists, like so:

getEjercicio(): void {
    const id = this.route.snapshot.paramMap.get('id');
    if (id) { // Add your check here. "id !== null" would work, too.
       const idAsNum = parseInt(id);
       
       // Check if this string is Not a Number.
       // If so, return, we can't continue.
       if (idAsNum === NaN) {
          return;
       }

       this.ejercicioService
          .getEjercicio(idAsNum)
          .subscribe(ejercicio => this.ejercicio = ejercicio)
    }
  }

This may not fix the issue you are seeing with the data not displaying. You may need to use an Angular route listener to make it work as intended.

Chris Gilardi
  • 1,509
  • 14
  • 26
  • Thanks, but the issue persists even if I add that code it's still saying that the argument of type 'string' is not assignable to parameter of type 'number'. Regarding the data not displaying, I have added the router to my app-routing.module.ts file but without success. – Elvis Jun 21 '21 at 19:51
  • @Elvis, sorry about that, I added the code to parse it as a number as well. I'm assuming it is an integer. You could also use the syntax `const idAsNum = +id` to do the conversion. – Chris Gilardi Jun 21 '21 at 19:56
  • 1
    Thank you, Chris. Your code also works now, and also solves the issue with displaying the data on the front page. – Elvis Jun 21 '21 at 20:02