Home > Blockchain >  RxJS/Angular error when mapping sub-array in observables
RxJS/Angular error when mapping sub-array in observables

Time:03-25

This post is related to an earlier post I made: Angular/RxJS type error when mapping observable

The CustomerShipment is a model which represents the JSON response, and has another class for the items array called CustomerShipmentItems. The calendarService.getDailyCalendarShipments(params) is returning CustomerShipment[]. I have issues when I try to access a sub array inside CustomerShipment. Each CustomerShipment can contain an array of items (CustomerShipmentItems[]). I want to map that array of items into the return result. Which should be of type CalendarEvent. But when I do a separate map for it, there is once again an error:

events$: Observable<CalendarEvent[]>;

this.events$ = this.calendarService.getDailyCalendarShipments(params).pipe(
 mergeMap((results, index) => {
   return from(results);
 }),
 map((result: CustomerShipment, index) => {
   result.items.map((e, i) => {
      return {
         title: result.customer,
         start: new Date(Date.parse(e.appointmentTime)),
         meta: {
           header: this.headers[index]
         }
      };
   });
 }), toArray()
);

The schema I am trying to map is:

{
    "0": {
        "customerId": 1234,
        "customer": "test",
        "items": [
           id: 123,
           tssNumber: "1234567"
           containerNumber: "ISO Container Standard",
           appointmentTime: "24/03/2022 12:00 p.m."
        ]
    }
}

Basically, I want to convert the below code into RxJS. I would also appreciate links/references which would give me a better understanding

this.calendarService.getDailyCalendarShipments(params).pipe(
  map((result: CustomerShipment[]) => result.forEach((e, index) => {
    if (this.headers.length !== result.length) {
      this.headers.push({
        id: e.customerId,
        name: e.customer,
        color: colors[index]
      });
    }
    e.items.forEach((item) => {
      if (!this.events.some(el => el.id === item.id)) {
        const itemDate = new Date((Date.parse(item.appointmentTime)));
        this.events.push({
          id: item.id,
          title: item.containerNumber   ' '   item.appointmentTime,
          color: this.headers[index].color,
          start: itemDate,
          meta: {
                header: this.headers[index]
          },
          actions: this.actions,
          allDay: itemDate.getHours() === 0 || itemDate.getHours() === 1
        });
      }
    });
})))

expected response would be an array of the following fields:

{
id: 123,
title: "etc",
start: Date Fri Mar 18 2022 01:00:00 GMT 0100 (Central European Standard Time),
​​allDay: true,
​color: undefined
}, // etc
​​```

CodePudding user response:

Can you try this way

this.events$ = this.calendarService.getDailyCalendarShipments(params).pipe(
    mergeMap((results, index) => {
      return from(results).pipe(map((result: CustomerShipment, index) => {
        result.items.map((e, i) => {
           return {
              title: result.customer,
              start: new Date(Date.parse(e.appointmentTime)),
              meta: {
                header: this.headers[index]
              }
           };
        });
        return result;
      }));
    }),
    
   );

CodePudding user response:

Read This: Comprehensive Guide to Higher-Order RxJs Mapping Operators: switchMap, mergeMap, concatMap (and exhaustMap)

let events$: Observable<CalendarEvent[]>;

this.events$ = this.calendarService.getDailyCalendarShipments(params).pipe(
  mergeMap((results: CustomerShipment[]) => from(results)),
  mergeMap((result: CustomerShipment) => from(result.items)),
  map((item, index) => {
    const itemDate = new Date((Date.parse(item.appointmentTime)));
    return{
      id: item.id,
      title: item.containerNumber   ' '   item.appointmentTime,
      start: itemDate,
      allDay: itemDate.getHours() === 0 || itemDate.getHours() === 1,
      color: undefined
    };
  }),
  toArray()
);
  • Related