Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

523
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda