I have an Angular 2 application. A service is requests data from an api that returns the results like the following:
{ "data":[ {"id":1,"timestamp":"2016-04-17T19:52:53.4510935+01:00","sourceDatabaseServer":"127.0.0.1","sourceDatabaseName":"Database1","targetDatabaseServer":"192.168.99.101","targetDatabaseName":"Database2"}, {"id":2,"timestamp":"2016-04-17T19:52:53.4510935+01:00","sourceDatabaseServer":"127.0.0.2","sourceDatabaseName":"Database3","targetDatabaseServer":"192.168.99.102","targetDatabaseName":"Database4"}, {"id":3,"timestamp":"2016-04-17T19:52:53.4510935+01:00","sourceDatabaseServer":"127.0.0.3","sourceDatabaseName":"Database5","targetDatabaseServer":"192.168.99.103","targetDatabaseName":"Database6"} ] }
My Angular 2 service looks like this (I've cut the error handling for brevity as we're on the happy path here):
getList() : Observable<SomeModel[]> { return this._http.get(this._getListUrl).map(this.extractData); } private extractData(res: Response) { return res.json().data || {}; }
and my component like this:
results: SomeModel[]; errorMessage: string; ngOnInit() { this._someService.getList() .subscribe( results => this.results = results, error => this.errorMessage = <any>error); }
and my model like this:
export class SomeModel { constructor( public id: number, public timestamp: Date, public sourceDatabaseServer: string, public sourceDatabaseName: string, public targetDatabaseServer: string, public targetDatabaseName: string ) { } }
Everything looked like it was working however when I tried to display timestamp using the DatePipe like so {{item.timestamp | date:'short'}}
the application blows up with the following error message:
Invalid argument '2016-04-17T19:40:38.2424240+01:00' for pipe 'DatePipe' in [{{result.timestamp | date:'short'}}
After some investigation I believe that timestamp is not actually being converted to the Date
type but is instead just being set a string
. I'm guessing this is becuase the Date
type isn't known at the time Response.json()
is called? or am I missing something else entirely? Is there a fix or work around for this?
I would map the string field to a date one:
getList() : Observable<SomeModel[]> { return this._http.get(this._getListUrl).map(this.extractData); } private extractData(res: Response) { var data = res.json().data || []; data.forEach((d) => { d.timestamp = new Date(d.timestamp); }); return data; }
The date
pipe only accepts Date
values not string values.
See How to get Date object from json Response in typescript for how to convert dates in JSON.
Alternatively you can create your own string-to-date conversion pipe
@Pipe({name: 'toDate'}) export class StringToDate implements PipeTransform { transform(value, [exponent]) : number { if(value) { return new Date(value); } } }
and then use it like
{{item.timestamp |toDate | date:'short'}}
Hint: don't forget to add the pipe to pipes: [StringToDate]
on the @Component(...)
decorater where you want to use it.
See also
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With