Tengo una función llamada "getData" que debe ejecutarse para mostrar cierta información. Quiero que se ejecute automáticamente, pero por el momento solo muestra los datos después de hacer clic en un botón que activa la función; consulte (componente.html):

<button (click)="getData()">Fetch Data</button>

Ya intenté insertar la función en ngOnInit () en el archivo component.ts:

ngOnInit(){
    this.getData()
  }

E intenté cargar en el archivo component.html:

<p onload="getData();">component works!</p>

... ambos no condujeron al resultado necesario

Así es como se ve el código (básicamente obtengo los datos de una llamada a la API y selecciono un elemento con una determinada identificación).

/*some code*/
export class DetailComponent implements OnInit {
  public data: any = []
  public selected: any = []
  constructor(
    public http: HttpClient, 
    public route: ActivatedRoute) { }

  getData(){
    const person_id = this.route.snapshot.paramMap.get('person_id');
    const url ='http://localhost:4000/api/allpeople';
    this.http.get(url).subscribe(data => this.data = data);
    this.selected=this.data.find(item=>
      {
        if(item['person_id']===person_id)
          {
            return true;
          }
        return false;
      });
    console.log(person_id, this.selected);
    return this.selected;
  }

  ngOnInit(){
    this.getData()
  }

Componente.html

<h1>{{selected.title}}</h1>
{{selected.person_id}}

Al cargar la página, la consola registra el siguiente error "No se puede leer la propiedad 'título' de indefinido" y el mensaje de error se refiere a esta línea: <h1>{{selected.title}}</h1>

Pero cuando hago clic en el botón, registra los datos como se supone que debe hacerlo.

¿Cómo puedo dejar que esto suceda automáticamente?

1
user11962606 28 oct. 2019 a las 17:34

3 respuestas

La mejor respuesta

ngOnInit() es el lugar correcto, cuando desea llamar al método onload. Si los datos son asíncronos, 'seleccionado' aún puede ser indefinido cuando se representa la plantilla. Para evitar el error, puede ajustar el bloque con una condición como lo hizo @Flignats o simplemente agregar un ? como

  <h1>{{selected?.title}}</h1>
  {{selected?.person_id}}

?. deja de evaluar cuando selected es null o undefined.

Estás asignando los datos fuera de la suscripción. Debería ser así:

getData(){
...
this.http.get(url).subscribe(data => {
  this.data = data;
  this.selected=this.data.find(item=>
    {
      if(item['person_id']===person_id)
        {
          return true;
        }
      return false;
    });
    console.log(person_id, this.selected);
  });
}
0
riorudo 28 oct. 2019 a las 15:21

Use $scope y llame a una función al comienzo de su controlador, como este

$scope.init = function () {
   $scope.title = "title";
   $scope.person_id = 2;
};

$scope.init();

El controlador se carga automáticamente con la página, y el $ scope en este caso puede hacer lo que desee ($ scope.init () se llama automáticamente si no lo ajusta en otras funciones)

0
alesssz 28 oct. 2019 a las 14:42

Error "No se puede leer la propiedad 'título' de indefinido"

Esto se debe a que cuando la expresión se ejecuta en la plantilla, en ese momento los datos no se han cargado y no están definidos.

Vuelva a colocar la llamada en ngOnInit() y ajuste la expresión en una declaración ngIf.

<ng-container *ngIf="selected">
  <h1>{{selected.title}}</h1>
  {{selected.person_id}}
</ng-container>
3
Flignats 28 oct. 2019 a las 14:41