1
votes

I'm familiar with C# Linq, but new to ng2+TypeScript+rxjs development.

In getDetailByDetailId method of below code, how to get First matched item from observable list?

Models

export class Master {
    Id: string;
    SomeProperty: string;
    Details: Detail[];
}    

export class Detail {
    DetailId: string;
    DetailProperty: string;
}

Methods

getMaster(id:string): Observable<Master>{
    return this.http.get(this.webUrl + "/" + id) // web api
        .map(this.extractData)
        .catch(this.handleError);
}

private extractData(res: Response) {
    let body = res.json() as Master[];
    return body || [];
}

getDetails(masterId: string): Observable<Detail[]>{
    return this.getMaster(masterId)
        .map(master => master.Details);
}

getDetailByDetailId(masterId: string, detailId: string): Observable<Detail>{
    return this.getDetails(masterId)
        .first(d => d.DetailId === detailId); // <-- Error occurred
}

getDetailByDetailId method gives following two errors.

Error:(47, 16) TS2322: Type 'Observable<Detail[]>' is not assignable to type 'Observable<Detail>'. Type 'Detail[]' is not assignable to type 'Detail'. Property 'DetailId ' is missing in type 'Detail[]'.

Error:(48, 45) TS2339: Property 'DetailId' does not exist on type 'Detail[]'.

1

1 Answers

3
votes

The problem is that getDetails return an Observable<Detail[]>. So the value being emitted to the first method is a Detail[], not a single Detail. What you can do is flatten the array first with flatMap, then you can call first

getDetailByDetailId(masterId: string, detailId: string): Observable<Detail> {
  return this.getDetails(masterId)
    .flatMap(details => details)
    .first((d: Detail) => d.DetailId === detailId);
}