Búsqueda de sitios web

javascript - Obtener datos al cargar el Componente


Tengo un componente que necesita mostrar los datos en la cuadrícula al cargar el componente/página y cuando se hace clic en un botón del componente padre, necesita actualizar la cuadrícula con nuevos datos. Mi componente es como sigue

export class TjlShipdateFilterComponent implements DoCheck {

  tljShipDate: ShipDateFilterModel[];

  constructor(private psService: ProjectShipmentService) {
  }

 ngDoCheck() {
 // this data is from the service, trying to get it on Page load
  }

@Input() filter: ShipDateFilterModel[];
//Load or refresh the data from parent when the button clicked from parent component 
ngOnChanges(changes: SimpleChanges) {
}

El ngOnChanges funciona bien, obtiene los datos del componente padre y los muestra cuando se hace clic en el botón desde el componente padre. Pero al cargar la página/componente, la cuadrícula no muestra nada y dice que this.psService.tDate; no está definido.

A continuación se muestra el servicio donde obtengo el tDate

export class ProjectShipmentService {
   ......    
  constructor(service: DataService, private activatedRoute: ActivatedRoute) {
      service.get<ShipDateFilterModel[]>(this.entityUrl).subscribe(x => this.tDate = x);
   }

No estoy seguro de qué me estoy perdiendo aquí. ¿Cómo puedo lograr este escenario?

Respuesta #1

Sucedió porque cuando se carga el componente, la solicitud en tu servicio puede no haberse completado y los datos pueden no haberse devuelto aún, por eso tDate es undefined. Intenta suscribirte a él dentro de tu componente, también usa ngOnInit() en lugar de ngDoCheck().

A su servicio:

tDate: Observable<ShipDateFilterModel[]>

constructor(service: DataService, private activatedRoute: ActivatedRoute) {
    ...
    this.tDate = service.get<ShipDateFilterModel[]>(this.entityUrl)
}

En tu componente:

export class TjlShipdateFilterComponent implements OnInit, OnChanges {

  tljShipDate: ShipDateFilterModel[];

  constructor(private psService: ProjectShipmentService) {
  }

  ngOnInit() {
  // this data is from the service, trying to get it on Page load
    this.psService.tDate.subsribe(x => this.tljShipDate = x);
  }

  @Input() filter: ShipDateFilterModel[];
  //Load or refresh the data from parent when the button clicked from parent component 
  ngOnChanges(changes: SimpleChanges) {
  if (changes.filter && changes.filter.currentValue)
   {     
     this.tljShipDate = this.filter;
  }
 }
}

Respuesta #2

Tienes un par de opciones aquí. NgOnInit se ejecutará cuando se cree el componente, antes de que se renderice. Esta es la forma más común de cargar datos en la inicialización del componente. Si necesitas los datos incluso antes de que se inicialice el componente, entonces puede que necesites utilizar un Resolver. Aquí hay un ejemplo:

import { Injectable } from '@angular/core'
import { HttpService } from 'services/http.service'
import { Resolve } from '@angular/router'
import { ActivatedRouteSnapshot } from '@angular/router'

@Injectable()
export class DataResolver implements Resolve<any> { 
    constructor(private http: HttpService) { }
    resolve(route: ActivatedRouteSnapshot) {
        return this.http.getData(route.params.id);
    }
}

Luego, en tu configuración de rutas:

{
    path: 'data/:id',
    component: DataComponent,
    resolve: { data: DataResolver }
}

La inclusión del ActivatedRouteSnapshot es opcional, solo lo necesitas si estás usando datos de la ruta, como parámetros.

Editar: Mirando tu ejemplo más de cerca, ¿es posible que el ngDoCheck se esté ejecutando antes de que lo haga la suscripción de psService?