Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pipe / map an Observable in Angular

A nested object is showing up as [object Object] so I'm trying to cast it via pipe and map but I'm not getting any where. I've tried the models as classes and interfaces but no help. Can someone tell me what I'm doing wrong? Thanks.

The function:

  getClients(customerId: number): Observable<Client[]> {
    let clientUrl = 'SOME_URL';
    return this.http.get<Client[]>(clientUrl)
      .pipe(map(client: Client) => client.address as Address);
  }

The models:

import { Address } from './address.model';

export class Client{
  id: number;
  name: string;
  accountNumber: string;
  addressId: number;
  phoneNumber: string;
  address: Address;
}


export class Address{
  id: number;
  name: string;
  addressLine1: string;
  addressLine2: string;
  city: string;
  postalCode: string;
}

I'm getting the error: Error TS2345 (TS) Argument of type 'Address' is not assignable to parameter of type 'OperatorFunction<{}, Client[]>'.

like image 856
Tong Avatar asked Jan 08 '19 03:01

Tong


People also ask

How do you put a map inside a pipe?

To use map first we need to import it from the rxjs/operators library. Next, create an observable from array of numbers as shown below. srcArray = from([1, 2, 3, 4]); Use the pipe method to and invoke the map method.

What does pipe map do in Angular?

The pipe method of the Angular Observable is used to chain multiple operators together. We can use the pipe as a standalone method, which helps us to reuse it at multiple places or as an instance method.

Does pipe return observable?

A Pipeable Operator is a function that takes an Observable as its input and returns another Observable.

What is RxJS pipe in Angular?

You can use pipes to link operators together. Pipes let you combine multiple functions into a single function. The pipe() function takes as its arguments the functions you want to combine, and returns a new function that, when executed, runs the composed functions in sequence.


2 Answers

1) remove the piping part from your getClients() method

2) do the pipe-map before subscribing to getClients() or create another method, that will do only the piping part with the observable returned from getClients()

mapToAddress(): Observable<Address[]> {
  this.getClients.pipe(
    map((clients: Client[]) => clients.map(client => client.address))
  )
}

This is important to understand: when you call .map() method inside .pipe(), you're not getting a single client in this case, you get the whole clients array, pushed to Observable. Because you map the values, that are stored in the Observable - the values of type: < Client[] >.

Your pipe-map would work on some Observable, that emits a single client of type < Client >, not an array.

like image 53
Dasha Ermolova Avatar answered Sep 24 '22 17:09

Dasha Ermolova


The problem is here:

getClients(customerId: number): Observable<Client[]> {

you requested the function to return in form of observable (array of client) but actually you are returning Observable of Address.

.pipe(map(client: Client) => client.address as Address);

That's why the function is throwing this error. Replace Observable<Client[]> with Observable<Address[]>

like image 24
Akshay Rajput Avatar answered Sep 26 '22 17:09

Akshay Rajput