2016-04-17 21 views
17

Ich habe eine Angular 2-Anwendung. Ein Dienst ist fordert Daten von einem api, die die Ergebnisse wie die folgenden zurück:Angular 2 Datum Deserialisierung

{ 
    "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"} 
    ] 
} 

Mein Angular 2 Service sieht wie folgt aus (ich den Fehler geschnitten habe Kürze Handhabung, da wir auf dem Weg sind glücklich hier) :

getList() : Observable<SomeModel[]> { 
    return this._http.get(this._getListUrl).map(this.extractData); 
} 

private extractData(res: Response) { 
    return res.json().data || {}; 
} 

und meine Komponente wie folgt aus:

results: SomeModel[]; 
errorMessage: string; 
ngOnInit() { 
    this._someService.getList() 
     .subscribe(
     results => this.results = results, 
     error => this.errorMessage = <any>error); 
} 

und mein Modell wie folgt aus:

export class SomeModel { 

    constructor(
     public id: number, 
     public timestamp: Date, 
     public sourceDatabaseServer: string, 
     public sourceDatabaseName: string, 
     public targetDatabaseServer: string, 
     public targetDatabaseName: string 
    ) { } 
} 

Alles sah aus wie es funktioniert jedoch, wenn ich Zeitstempel mit dem DatePipe wie so {{item.timestamp | date:'short'}} die Anwendung mit der folgenden Fehlermeldung sprengt anzuzeigen versucht:

Invalid argument '2016-04-17T19:40:38.2424240+01:00' for pipe 'DatePipe' in [{{result.timestamp | date:'short'}} 

Nach einigen Untersuchungen glaube ich, dass Zeitstempel nicht wirklich ist wird in den Date Typ konvertiert, wird aber stattdessen nur auf string gesetzt. Ich schätze das ist, weil der Date Typ nicht zu der Zeit bekannt ist Response.json() heißt? oder vermisse ich etwas ganz anderes? Gibt es dafür eine Lösung?

+1

Wenn Sie tun, um ein '.json()', die nicht einen String verwandeln wird (auch wenn es in einigem Datumsformat ist) zu einem aktuellen Zeitpunkt Objekt. Es wird weiterhin eine Zeichenfolge sein. Sie müssen also 'new Date (herePassTheString) 'eingeben – arg20

+1

Wenn Sie es nur anzeigen, kann das DatePipe in Angular 2 jetzt das ISO-Zeichenfolgenformat verwenden. https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html Ich weiß nicht ob das schon immer so war, aber jetzt ist es soweit. ;) – Derrick

Antwort

18

Ich würde das String-Feld zu einem Datum Karte ein:

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; 
} 
+0

Ja, bester Ansatz ... alles danach ist dann ausgerichtet! Und hier ist für ein alternatives Format :-), 'd.timestamp = new Date (parseInt (d.timestamp.sub (6)));' –

+0

Warum bekomme ich einen Fehler in dieser Zeile: var data = res.json () .data || []; wenn ich versuche diesen Code zu benutzen? "Property-Daten gibt es nicht für Typ Promise " – Aaron

5

Das date Rohr akzeptiert nur Date Werte nicht String-Werte.

Informationen zum Konvertieren von Datumsangaben in JSON finden Sie unter How to get Date object from json Response in typescript.

Alternativ können Sie Ihre eigenen String-to-date Umwandlung Rohr

@Pipe({name: 'toDate'}) 
export class StringToDate implements PipeTransform { 
    transform(value, [exponent]) : number { 
    if(value) { 
     return new Date(value); 
    } 
    } 
} 

erstellen und dann verwenden, wie

{{item.timestamp |toDate | date:'short'}} 

Hinweis: vergessen Sie nicht, um das Rohr zu pipes: [StringToDate] auf der hinzufügen @Component(...) Dekorateur, wo Sie es verwenden möchten.

Siehe

+0

Dies ist eigentlich eine WinkelJS (Winkel 1) Antwort. Angular 2 unterstützt jetzt eine Vielzahl von Formaten, einschließlich des korrekten ISO-String-Formats. https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html – Derrick

+0

Es ist keine AngularJS 1 Antwort (weiß nicht 1.x), aber es ist fast ein Jahr alt und a Seitdem hat sich viel verändert. Ich werde aktualisieren, wenn ich zurück bin. Danke für die Nachricht. –

+0

Ah, Entschuldigung. Du hast Recht. Ich sehe deine @ Pipe jetzt drin. Ich war wirklich verwirrt, da die Dokumente für Winkel 1 die Ref-Links waren. https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html – Derrick

1

JSON keine Datumsangabe nicht liefern auch, so ist es völlig bis zu ist, wie es serialisiert/deserialisiert.

Sie könnten reviver Parameter von JSON.parse verwenden:

this._http.get(this._getListUrl).map(res => JSON.parse(res.text(), this.reviver)); 

reviver(key, value):any 
{ 
    if('timestamp' === key){ 
     //you can use any de-serialization algorithm here 
     return new Date(value); 
    } 
    return value; 
} 
2

Versuchen Sie meinem Beispiel, wenn seine Arbeit für Sie heraus. Und hier ist die Dokumentation für Date und Pipe.

<span>Date : {{announcement.createdAt | date:'EEE, d MMM,y'}}</span> 
<span>Time : {{announcement.createdAt | date:'shortTime'}}</span> 

Ausgang:

Date : Tue, 20 Dec,2016  
Time : 2:22 PM