5

My service called "getList" returns a list of items. I want to loop through the list of items and format the date. Then return the formatted array.

My current attempt doesnt return the items in the array because I use flatMap in order to loop the items in map.

I'm using angular6 and rxjs.

My attempt:

this.list$ = this.service.getList()
      .pipe(
        flatMap(response => response.items),
        map(item => {
          item.date = moment(item.date).format('YYYY-MM-DD').toString();
          return item;
        })
      );
4
  • u can format the date using pipe in template itself Commented Sep 4, 2018 at 16:21
  • @mohammedsameen can you show me an example? Commented Sep 4, 2018 at 16:26
  • 1
    something like: {{list$ | async | date:'yyyy-MM-dd'}} angular.io/api/common/DatePipe Commented Sep 4, 2018 at 16:33
  • 1
    worked thank you. would be nice to no how to do it using RXJS though Commented Sep 5, 2018 at 9:00

3 Answers 3

7

You can simply add toArray() at the end of your pipe

this.list$ = this.service.getList()
.pipe(
    mergeMap(response => response.items),
    map(item => {
        item.date = moment(item.date).format('YYYY-MM-DD').toString();
        return item;
    }),
    toArray()
)

What is probably better though is to restructure a bit your code, use the Observable map operator instead of flatMap (a.k.a. mergeMap) and inside it use the Array map method to do the formatting. In other words something like

pipe(
    map(response => response.items.map(item => {
        item.date = moment(item.date).format('YYYY-MM-DD').toString();
        return item;
    }))
)

The second approach avoids the unfolding of the Array (which in the first solution you do using flatMap) and the subsequent recreation of the Array, or at least confines this logic into the map method of Array

Sign up to request clarification or add additional context in comments.

Comments

0
@Pipe({
    name: 'dateFormat'
})
export class DateFormat implements PipeTransform {
    transform(value: any, args: string[]): any {
        if (value) {
            var date = value instanceof Date ? value : new Date(value);
            return DateFormatter.format(date, 'pt', 'YYYY-MM-DD');
        }
    }
}

Use the above pipe(custome pipe) in your template

{{ date | dateFormat}}

1 Comment

don't want a custom pipe solution. They are very slow as well
0
const formatItem = item => {
  item.date = moment(item.date).format('YYYY-MM-DD').toString();
  return item;
};

this.list$ = this.service.getList()
  .pipe(
    flatMap(response => from(response.items.map(formatItem))), // returns Observable<items> from array of items
    // flatMap merges back the observables into one
    toArray()
  );

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.