Angular RXHJ mappe plusieurs propriétés d'objet

Oct 23 2020

Mon service renvoie un objet avec des événements et des propriétés de comptage. En ce moment, je dois faire deux demandes. Premier pour obtenir les événements et deuxième pour obtenir le nombre d'événements. Je voudrais utiliser Observables dans le composant et le tuyau asynchrone dans le modèle. Je sais comment y parvenir en m'abonnant au service dans le composant, mais j'aimerais comprendre comment mapper les deux événements et compter sur des observables avec une seule demande. Quel opérateur RxJs dois-je utiliser?

import { Component, OnInit } from '@angular/core';
import { Event } from '../event.model';
import { Observable } from 'rxjs';
import { EventsService } from '../events.service';
import { first, map, take } from 'rxjs/operators';

@Component({
selector: 'app-events-list',
templateUrl: './events-list.component.html',
styleUrls: ['./events-list.component.css']
})
export class EventsListComponent implements OnInit {

events: Event[];
a$: Observable<Event[]>; total$: Observable<number>;
pageSize: number = 100;
currentPage: number = 1;

constructor(private eventsService: EventsService) { }

ngOnInit(): void {

this.a$ = this.eventsService.getEvents(this.pageSize, this.currentPage).pipe( map(results => results.events) ); this.total$ = this.eventsService.getEvents(this.pageSize, this.currentPage).pipe(
  map(results => results.count)
);

 }

 }

Réponses

2 MichaelD Oct 23 2020 at 15:38

Il semble que la réponse soit déjà un objet contenant les propriétés eventset count. Vous pouvez donc initialiser une seule variable (par exemple events$) dans le contrôleur et l'utiliser dans le modèle avec asyncpipe.

Vous pouvez également utiliser ng-containertag avec *ngIfla asconstruction de pour réutiliser les émissions de l'observable. Les ng-containerne contribuent pas aux balises supplémentaires et sont commentées dans le DOM généré.

Essayez ce qui suit

Manette

export class EventsListComponent implements OnInit {
  events: Event[];
  events$: Observable<any>;
  pageSize: number = 100;
  currentPage: number = 1;

  constructor(private eventsService: EventsService) { }

  ngOnInit(): void {
    this.events$ = this.eventsService.getEvents(this.pageSize, this.currentPage);
  }
}

Modèle

<ng-container *ngIf="(events$ | async) as events">
  Event: {{ events?.events | json }}
  Count: {{ events?.count }}
  
  <sample-comp [sampleInput]="events?.events"></sample-comp>
</ng-container>

J'ai utilisé un opérateur de navigation sécurisé ?.pour éviter toute undefinederreur et un jsontuyau pour rendre l' events.eventsobjet.

1 MoxxiManagarm Oct 23 2020 at 16:27

Alternativement à la solution de Michael D, vous pouvez le faire

const events$ = this.eventsService.getEvents(this.pageSize, this.currentPage).pipe( shareReplay(1), ); this.a$ = events$.pipe( map(results => results.events) ); this.total$ = events$.pipe(
  map(results => results.count)
);