Home > OS >  Angular/RxJS type error when mapping observable
Angular/RxJS type error when mapping observable

Time:03-24

I am getting the following error when trying to map a resposne from my api

Argument of type 'OperatorFunction<{ results: CustomerShipment[]; },{ title: string; start: Date; }[]>' 
is not assignable to parameter of type 'OperatorFunction<CustomerShipment[], {title:string; start: Date;}[]>'. 
Type '{ results: CustomerShipment[]; }' is missing the following properties from type 'CustomerShipment[]':
length, pop, push, concat, and 26 more.

API which returns a JSON array of objects with the following schema… I use Angular-Calendar v0.28.28

{
    "0": {
        "customerId": 1234,
        "customer": "test",
        "items": [
           id: 123,
           tssNumber: "1234567"
           containerNumber: "e.g.",
           appointmentTime: "23/03/2022 12:00 p.m."
        ]
    }
}

An angular calendar event has the following required properties: start: Date, title: string. I am trying to map the response from my API to the CalendarEvent object :

events$: Observable<CalendarEvent<{ results: CustomerShipment }>[]>;

ngAfterViewInit(): void 
{
   this.fetchCustomers(formatDate(this.viewDate, 'yyyy-MM-dd', 'en'));
}

fetchData(day: string): void {
let params = new HttpParams();
params = params.append('userid', this.getUserId());
params = params.append('date', day);
 this.events$ = this.calendarService.getDailyCalendarShipments(params)
   .pipe(
      map(({ results }: { results: CustomerShipment[] }) => {
        return results.map((result: CustomerShipment) => {
          return {
            title: result.customer,
            start: new Date()
          };
        });
   }));
}

then in the HTML component

<div >
  <div #scrollContainer  *ngIf="events$ | async; else loader; let events">
    <app-day-view-scheduler (eventTimesChanged)="eventTimesChanged($event)"
                            (userChanged)="userChanged($event)"
                            [events]="events"
                            [headers]="headers"
                            [viewDate]="viewDate">
    </app-day-view-scheduler>
  </div>
</div>

I can do this without using the Observable, but I want to use the angular async pipe.

I'm using the following example: https://mattlewis92.github.io/angular-calendar/#/async-events

CodePudding user response:

getDailyCalendarShipments returning array of type CustomerShipment

Used from to emit data in sequence and mergeMap to subscribe this

inside map creating your event of type { results: CustomerShipment }

toArray creating { results: CustomerShipment }[]

this.events$ = this.calendarService.getDailyCalendarShipments(params).pipe(
  mergeMap(({ results }: { results: CustomerShipment[] }) => {
    return from(results);
  }),
  map((result: CustomerShipment) => {
    return {
      title: result.customer,
      start: new Date(),
    };
  }),
  toArray()
);

CodePudding user response:

You need either to change the type of the events$ Observable to be Observable<CalendarEvent<CustomerShipment>[]>, or change the map operator output to be CalendarEvent<{ results: CustomerShipment }>[] like the following:

this.events$ = this.calendarService.getDailyCalendarShipments(params).pipe(
  map(({ results }: { results: CustomerShipment[] }) => ({
    results: results.map((result: CustomerShipment) => ({
      title: result.customer,
      start: new Date(),
    })),
  }))
);
  • Related