Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

339
Views
¿Cómo mostrar un Observable de un Observable-Array en Angular?

Tengo un Observable-Array que contiene una lista de preguntas. Me gustaría mostrar mis preguntas una por una, pero no encuentro la manera de hacerlo.

Hasta ahora solo logré mostrarlos todos con un * ngFor en mi html.

Este es mi componente:

 import { Component, OnInit } from '@angular/core'; import { mergeMap, Observable, of, concatAll, Subject, startWith, zip, Subscription } from "rxjs"; import { Question } from "../models/Question"; import { QuestionService } from "../services/question.service"; import { AuthService } from "../services/auth.service"; import { User } from "../models/User"; @Component({ selector: 'app-play', templateUrl: './play.component.html', styleUrls: ['./play.component.css'] }) export class PlayComponent implements OnInit { user_id: Pick<User, "id"> | undefined unanswered_questions$: Observable<Question[]> | undefined question$: Observable<Question> | undefined constructor( private questionService: QuestionService, private authService: AuthService ) { } ngOnInit(): void { this.user_id = this.authService.userId this.unanswered_questions$ = this.getUnansweredQuestions(this.user_id) } getUnansweredQuestions(user_id: Pick<User, "id"> | undefined): Observable<Question[]> { return this.questionService.fetchAllUnansweredQuestions(user_id); } }

Este es mi html:

 <mat-card class="question-card" *ngFor="let question of unanswered_questions$ | async"> <mat-card-header> <div mat-card-avatar class="example-header-image"></div> <mat-card-title>{{question.title}}</mat-card-title> </mat-card-header> <mat-card-content> <h3>{{question.body}}</h3> </mat-card-content> <mat-card-actions> <button mat-button>{{question.answer1}}</button> <button mat-button>{{question.answer2}}</button> <button mat-raised-button color="accent">Skip<mat-icon>skip_next</mat-icon></button> </mat-card-actions> </mat-card>

Encontré esta publicación donde alguien está tratando de hacer básicamente lo mismo. Desafortunadamente, ambas respuestas en esa publicación no funcionan para mí. Pensé que no funcionan debido a que la publicación tiene 4 años y yo uso una versión más nueva de rxjs y angular.

Cualquier ayuda es muy apreciada. ¡Gracias!

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Actualmente, el código "funciona" porque está canalizando su observable al controlador de canalización asíncrona que mantiene la ejecución de ngFor hasta que se resuelva el observable.

Modificaría su código para que se suscriba a lo observable y maneje el resultado resultante. En realidad, primero convertiría a una promesa y la esperaría ya que, en mi opinión, ese estilo es más legible y predecible, especialmente para un evento "uno y listo".

Así que modifique su componente así (NOTA: he dejado fuera las importaciones y el decorador por razones de brevedad):

 export class PlayComponent implements OnInit { user_id: Pick<User, "id"> | undefined; unanswered_questions: Question[]; question$: Observable<Question> | undefined; questionIndex = 0; constructor( private questionService: QuestionService, private authService: AuthService ) { } async ngOnInit(): Promise<void> { this.user_id = this.authService.userId; await this.unanswered_questions = this.getUnansweredQuestions(this.user_id).toPromise(); } getUnansweredQuestions(user_id: Pick<User, "id"> | undefined): Observable<Question[]> { return this.questionService.fetchAllUnansweredQuestions(user_id); } skipQuestion(): void { if (this.questionIndex !== this.getUnansweredQuestions.length) { this.questionIndex++; } } }

Y luego tu HTML:

 <mat-card class="question-card" *ngIf="unanswered_questions"> <mat-card-header> <div mat-card-avatar class="example-header-image"></div> <mat-card-title>{{unanswered_questions[questionIndex].title}}</mat-card-title> </mat-card-header> <mat-card-content> <h3>{{unanswered_questions[questionIndex].body}}</h3> </mat-card-content> <mat-card-actions> <button mat-button>{{unanswered_questions[questionIndex].answer1}}</button> <button mat-button>{{unanswered_questions[questionIndex].answer2}}</button> <button mat-raised-button color="accent" (click)="skipQuestion()">Skip<mat-icon>skip_next</mat-icon></button> </mat-card-actions> </mat-card>

Al agregar ngIf a su matCard, evita la representación hasta que se resuelva el observable.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!