1

I've just tried to use a simple date pipe in my angular2 app:

Registered: {{user.registered | date:'shortDate'}}

The error I get is:

Invalid argument '2016-03-28T07:25:40.824Z' for pipe 'DatePipe' in [{{user && user.registered | date:'shortDate' }} in UserDialog@16:57]

I do have a User model (minimal here) shared between this component and some others:

export class User { public registered: Date; }

I get the user data as JSON from backend, and it's a ISO 8601: 2016-03-28T07:26:01.202Z.

When I use my own custom pipe, it works (example bellow).

import {Pipe, PipeTransform} from 'angular2/core';
/**
 * The default ISO Date is not parseable by ts compiler or some such.
*/
@Pipe({ name: 'betterDate' })
export class BetterDatePipe implements PipeTransform {

  transform(date: number): string {

    let d = new Date(date);
    return d.toLocaleDateString();
  }
}

The name, BetterDatePipe is obviously a pun at me writing better angular2 code then the inventors ;)

Zlatko
  • 18,936
  • 14
  • 70
  • 123

3 Answers3

2

Instead of re-implementing the pipe, you may write an intermediary one, transforming the component's string value into date first:

string-to-date.pipe.ts:

import {Pipe, PipeTransform} from '@angular/core';
/**
 * Pipe to transform a string to a date
 */
@Pipe({name: 'stringToDate'})
export class StringToDatePipe implements PipeTransform {
    /**
     * Constructor
     */
    constructor() {
    }
    /**
     * Transform a date that is passed as string into a date
     * @param value The date passed as string
     * @returns {Date} The Date object
     */
    transform(value: string): Date {
        return new Date(value);
    }
}

Component

import {StringToDatePipe} from './string-to-date.pipe';
@Component({
    ...
    pipes: [StringToDatePipe],
    ...
})

Template

Registered: {{user.registered | stringToDate | date:'shortDate'}}
Dani
  • 2,602
  • 2
  • 23
  • 27
  • A tiny bit cleaner, but with an extra pipe. Anyway, I've gotten used to my solution and it works. Thanks for the suggestion though. Still doesn't answer the original question of angular pipe that can on its own consume a string representation of ISO 8601 date. – Zlatko Jul 12 '16 at 09:53
2

I see merits in both, but the OP's code somewhat limiting: it always returns the same date format all the time, you're ultimately going to write another Pipe to change that format anyway.

The second method sounds a whole lot more manageable: however, a few things, the pipes isn't something you include in the @Component, you'd have to refer that in the app.module.ts as both an import statement:

import { StringToDatePipe } from './???/string-to-date.pipe'

as well as needing to include it in the @NGModule({... further down the page under declarations.

From there, you can use the Custom Pipe, and then moving onto using Angular's Date Pipe

Wonderboy
  • 134
  • 3
1

The argument is obviously a string, not a Date. You need to convert it to Date before passing it to the pipe. JSON doesn't support type Date.

user.registered = new Date(json.registered);

or similar depending on how you get the user object.

See also Converting string to date in js

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Hmm. Where would that go, in the User class constructor or something? I get an array of users by json (angular2/http, then `response.json()` - so I don't know what to do exactly to convert these. – Zlatko Mar 29 '16 at 21:13
  • 1
    See here http://stackoverflow.com/questions/36868856/asp-net-webapi-datetimeoffset-serialize-to-json-javascript-angular2 – iwhp Apr 26 '16 at 20:36