J'ai une application Angular 2. Un service demande des données à une API qui renvoie les résultats comme suit:
{
"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"}
]
}
Mon service Angular 2 ressemble à ceci (j'ai coupé la gestion des erreurs par souci de brièveté car nous sommes sur la bonne voie ici):
getList() : Observable<SomeModel[]> {
return this._http.get(this._getListUrl).map(this.extractData);
}
private extractData(res: Response) {
return res.json().data || {};
}
et mon composant comme ceci:
results: SomeModel[];
errorMessage: string;
ngOnInit() {
this._someService.getList()
.subscribe(
results => this.results = results,
error => this.errorMessage = <any>error);
}
et mon modèle comme ça:
export class SomeModel {
constructor(
public id: number,
public timestamp: Date,
public sourceDatabaseServer: string,
public sourceDatabaseName: string,
public targetDatabaseServer: string,
public targetDatabaseName: string
) { }
}
Tout semblait avoir l'air de fonctionner, cependant, lorsque j'ai essayé d'afficher l'horodatage à l'aide de DatePipe comme suit {{item.timestamp | date:'short'}}
, L'application explose avec le message d'erreur suivant:
Invalid argument '2016-04-17T19:40:38.2424240+01:00' for pipe 'DatePipe' in [{{result.timestamp | date:'short'}}
Après quelques recherches, je pense que l’horodatage n’a pas été converti au type Date
, mais qu’il est simplement en train de définir un string
. J'imagine que c'est parce que le type Date
n'est pas connu au moment où Response.json()
est appelée? ou est-ce que quelque chose me manque complètement? Y at-il un correctif ou un travail autour pour cela?
Je mapper le champ de chaîne à une date un:
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;
}
Le tube date
accepte uniquement les valeurs Date
et non les chaînes.
Voir Comment obtenir l'objet Date à partir de Réponse json dans TypeScript pour savoir comment convertir des dates au format JSON.
Sinon, vous pouvez créer votre propre canal de conversion chaîne à date
@Pipe({name: 'toDate'})
export class StringToDate implements PipeTransform {
transform(value, [exponent]) : number {
if(value) {
return new Date(value);
}
}
}
et ensuite l'utiliser comme
{{item.timestamp |toDate | date:'short'}}
Astuce: n'oubliez pas d'ajouter le tuyau à pipes: [StringToDate]
Sur le décorateur @Component(...)
où vous voulez l'utiliser.
Voir également
JSON ne fournit aucune spécification de date, il est donc entièrement fonction de la manière dont il est sérialisé/désérialisé.
Vous pouvez utiliser le paramètre reviver
de JSON.parse
:
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;
}