en mi proyecto, estoy obteniendo datos de una API (entidades de viaje). Este es mi modelo:
//Trip.model.ts export class Trip{ created_at?:Date; updated_at?:Date; .... bunch of fields } En mi componente, estoy obteniendo los datos y asignándolos a la variable de viajes . Sin embargo, cuando trato de acceder a cualquiera de los elementos en la matriz de viajes , aparece 'indefinido'. Tampoco puedo recorrerlo, probé tanto forEach como for...in/of .
Intenté usar una interfaz en lugar de una clase, pero no tuve suerte. ¿Cómo puedo recorrer esa matriz de objetos para usar los datos que contiene?
Código del componente:
userName:string=''; trips:Trip[]=[]; moment:any=moment; usersData:any={}; constructor(private auth: AuthService, private storage: LocalStorageService, private translate: TranslateService, private tripService: TripService){} ngOnInit(): void { console.log(this.translate.currentLang) this.userName=localStorage.getItem('username')!; this.fetchTrips(); this.fetchPics(); } fetchTrips() { this.tripService.getTrips().subscribe({ next: data => { data[0].data.forEach((value) => { let trip: Trip = plainToInstance(Trip,value); this.trips.push(trip); }); }, error: error => { console.log(error); } }); } //fetchPics because I want to extract //user's profile pics' urls from the trips array fetchPics(){ console.log(this.trips); console.log(this.trips[0]); this.trips.forEach((trip)=>{ console.log(trip); }); }método de servicio getTrips:
getTrips(){ return this.http.get<any>(Api.API+Endpoints.TRIP); }Esto es lo que muestra cuando yo
console.log(this.trips)después de la asignación.
Datos de la API:
Imágenes recortadas para hacerlas más legibles.
Está tratando de obtener acceso al valor de this.trips antes de tener sus datos en él. Esto sucede porque obtiene esos datos de forma asincrónica, justo dentro de la suscripción de this.tripService.getTrips()
Entonces, para resolver su problema, solo necesita mover esta invocación:
this.fetchPics();dentro del método de suscripción de fetchTrips(), así:
fetchTrips() { this.tripService.getTrips().subscribe({ next: data => { data[0].data.forEach((value) => { let trip: Trip = plainToInstance(Trip,value); this.trips.push(trip); this.fetchPics(); }); }, error: error => { console.log(error); } }); }Esto sucede porque JS es asíncrono. está realizando una solicitud http aquí, que puede tomar algún tiempo para obtener datos del servidor. supongamos que puede tomar 1 minuto hasta que el compilador no detenga su proceso de ejecución. En ese 1 minuto de tiempo ejecutará las siguientes declaraciones. Debido a eso , su método fetchpics() se está ejecutando antes de que se complete la ejecución de fetchtrips() . Para superar esto, podemos usar async, esperar como se muestra a continuación.
async fetchTrips() { this.tripService.getTrips().subscribe({ next: data => await { data[0].data.forEach((value) => { let trip: Trip = plainToInstance(Trip,value); this.trips.push(trip); }); }, error: error => { console.log(error); } });}
La función fetchPics() ejecuta antes de que finalice la llamada a getTrips . Debe llamar al método solo después de que finalice su llamada HTTP y después de completar correctamente su matriz de trips .
fetchTrips() { this.tripService.getTrips().subscribe({ next: data => { //Populate your trips array data[0].data.forEach((value) => { let trip: Trip = plainToInstance(Trip,value); this.trips.push(trip); }); // this is where you need to call this.fetchPics(); }, error: error => { console.log(error); } }); }