angular - Rätt sätt att hantera Observables för Async Pipe-rendering


Jag försöker hämta information från ett Observable-objekt, men jag kan inte lista ut hur man gör det på rätt sätt. Till exempel detta, Dog API

det bör returnera ett JSON-objekt

{
    "message": "https://images.dog.ceo/breeds/setter-english/n02100735_10064.jpg",
    "status": "success"
}

för sådana har jag en tjänstefunktion

  getRandomImage(): Observable<Random> {
    return this.client.get<Random>(`https://dog.ceo/api/breeds/image/random`)
  }

men när jag försöker rendera det i HTML

<div>
  <p *ngIf=" random$ | async">{{ random$.message }}</p>
</div>

Jag får ett felmeddelande

Property 'message' does not exist on type 'Observable<Random>'

kan också någon vänligen förklara för mig på ett enkelt sätt vad den här funktionen gör

getListFacts(length: number, limit: number) : Observable<facts[]> {
    return this.client
        .get<{ data: facts[] }>(`https://catfact.ninja/factsmax_length=${length}&limit=${limit}`)
        .pipe(map(({ data }) => data));
}

Typ, jag säger åt det att returnera Observable av Array av Facts, med en get-förfrågan som borde returnera ett objekt som innehåller en array med facts som heter data, vad gör då pipe map?

Tack

Jag försöker använda Observables med Async Pipe för renderering. men jag kan inte riktigt förstå hur man korrekt skriver funktioner för att hämta observables för korrekt renderering

Svar #1

Det största problemet är att du direkt försöker komma åt observablen random$, när du i själva verket vill komma åt objektet som sänds ut av den observablen. För att uppnå det du vill kan du lägga till as randomImage i din HTML-kod och sedan komma åt randomImage.

Jag skapade ett fungerande exempel:

Först TS-filen:

random$: Observable<RandomImage>;

constructor(private client: HttpClient) {
    this.random$ = this.client.get<RandomImage>(`https://dog.ceo/api/breeds/image/random`);
}

Sedan HTML-koden:

<p *ngIf="random$ | async as randomImage">{{ randomImage.message }}</p>

Angående din fråga om map-operatorn

Följande kod hämtar dataarrayen inbäddad i ett objekt. Du använder sedan map-operatorn för att extrahera arrayen från objektet, så att endast arrayen utan wrapper-objektet returneras:

getListFacts(length: number, limit: number) : Observable<facts[]> {
    return this.client
        .get<{ data: facts[] }>(`https://catfact.ninja/factsmax_length=${length}&limit=${limit}`)
        .pipe(map(({ data }) => data));
}

Relaterade artiklar