Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

516
Vistas
Angular: how to handle Observables and use result in different methods

I'm having troubles to understand how I should work with Observables to meet my requirements. As an example, lets say that I have an application and for internationalization, I'm using REST service with all the labels and translations. Some labels can change based on performed actions on the page. And I'm not sure how to retrieve data from the service and use it in different methods.

Let's look at this pseudo-code:

labels: KeyValuePair[];
userDetails: UserDetails;
displayedColumns: string[];

// services below generated thanks to ng-swagger-gen
constructor(
   labelService: LabelService, 
   userService: UserService
){}

ngOnInit() {
   this.userService.get().subscribe(
      (userData) => {
        this.userDetails = userData; 
        console.log(userData);
      },
      (error) => {
        this.errorMessage = error;
      }
    );

   this.labelService.get(this.userDetails.getLanguage()).subscribe(
      (labelsResponse) => {
        this.labels = labelsResponse; // use the labels in HTML template
        console.log(labelsResponse);
      },
      (error) => {
        this.errorMessage = error;
      }
    );

   this.retrieveTableColumns();
}

retrieveTableColumns() {
   this.displayedColumns = this.labels.filter(/* filter columns */);
}

executeMethods() { // method executed from HTML template
   this.doSomethingWithUserDetails();
   this.doSomethingWithLabels();
}

doSomethingWithUserDetails() {
   // 1. do differnet things and use it in HTML template
   // 2. check one of properties and based on this 
   this.setColumns();
}

setColumns() { // columns used in mat-table
    if (this.userDetails.allowedForAction) {
        this.displayedColumns = this.columnsDef.concat(['action']);
        this.hiddenColumns.push(this.displayedColumns.length);
    } else {
        this.displayedColumns = this.columnsDef;
    }
}

doSomethingWithLabels() {
   // do some magic using retrieved labels
}

For generating web client service, I've used ng-swagger-gen.

How to handle the Observables to achieve this? So to be able to use data in different places. I've heard about converting it with .toPromise and use async await, but I've also heard that this is antipattern... So not sure what to do here... I'm working with Angular 9 if it matters.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Basics

You just keep the response as an observable:

labels$ = this.labelService.get(this.userDetails.getLanguage())

And in the Html you use an async pipe:

*ngFor="let label of labels$ | async"

If you want to transform the data in your typescript, you use ´.pipe()´ on the observable and create a new one:

newLabels$ = labels$.pipe(
    map(labels => labels.filter(label => label.id > 5)),
    // Or whatever you want to filter, sorry no inspiration
    tap(labels => console.log(labels)),
    // more pipes ...
)

You can create you own functions to be used in these pipes.

You can also just write a function taking whatever object is inside the observable as parameter and just use the function in your html:

*ngFor="let label of labelsSortedByName((labels$ | async)!)"

I'm using an ngFor as example because it's used a lot, but you can use it anywhere. Basically try to not subscribe in you code, just use async pipes. You'll have lots of fun learning about higher order observables, combining multiple observables together.

Merging Observables

Example:

first$ = of("en") // An observable representing the result of your first request

second(lang: string): Observable<string> { // Request requiring a string argument
  return of(lang + " language")
}

result$ = this.first$.pipe( // The resulting observable of the second request
  mergeMap(r => {
    return this.second(r)
  })
)

In template:

{{ result$ | async }}  <!-- Result: 'en language' -->

In this example first$ and second() are just mocks of your requests. I realize your second request does something else than just concatenating strings, but the idea is the same. It takes an argument of the type held by the first Observable and a new Observable is returned.

Here is a Stackblitz for you to play with.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda