Date par défaut au format de conversion JSON dans l'application Angular

Nov 30 2020

Supposons qu'un composant (à l'intérieur de l'application angulaire) ait plusieurs formes réactives contenant des sélecteurs de date (j'utilise à mat-datepickerpartir de la bibliothèque de matériau angulaire) et d'autres entrées. Après qu'un utilisateur a cliqué sur le bouton «Soumettre», j'envoie la valeur des formulaires à sauvegardé (avec HttpClient.post). Le problème est que les champs datepicker sont sérialisés comme "2020-11-18T22:00:00.000Z"(évidemment la Date.toJSON()méthode est appelée) alors que le backend attend un autre format.

Notez que j'utilise formlylib pour créer mes formulaires, car l'ensemble des composants de chaque formulaire peut varier. Vous n'êtes peut-être pas familier avec, formlymais de toute façon, l'ensemble des sélecteurs de date peut également varier, donc je ne peux pas convertir les champs de sélecteur de date directement car je ne connais pas la liste exacte des champs de date dans un endroit où j'envoie la valeur des formulaires.

Existe-t-il une solution élégante à mon problème? Vous ne pouvez pas imaginer quelque chose de mieux que le patching Date.prototype.toJSON()ou le bouclage d'objets envoyés sur le serveur, vérifiez le type de champs et le changement de champ si c'est un Date? Je ne trouve pas de moyen de définir le format de la sortie de valeur par datepicker, que ce soit sous forme matérielle ou formelle.

Réponses

1 ibenjelloun Dec 04 2020 at 15:23

La mise en œuvre de ControlValueAccessor serait une solution élégante. L'idée est de créer un composant de sélecteur de date qui prend votre format de date en entrée et renvoie votre format en sortie.

Pour cela, il vous suffit de créer un nouveau composant que j'appellerais MatDatepickerWrapperComponentpour cet exemple. Le modèle de ce composant ne serait rien de plus que le sélecteur de date matériel:

<mat-form-field appearance="fill">
  <mat-label>Choose a date</mat-label>
  <input matInput [matDatepicker]="picker" [(ngModel)]="model" (ngModelChange)="modelChange($event)">
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

Du côté des composants, vous devrez implémenter ControlValueAccessor , et faire les transformations dont vous avez besoin:

writeValue(value: string): void {
    this.model = transformDateFromMyFormatToIso(value);
}
modelChange(value: string) {
    const transformedValue = transformIsoDateToMyFormat(value);
    this.onChange(transformedValue);
  }

Vous pouvez maintenant ajouter le nouveau composant à un formulaire comme vous auriez ajouté le composant d'origine.

Voici un exemple de stackblitz en cours d'exécution.

1 RobinDijkhof Dec 04 2020 at 05:26

J'essaierais d'utiliser un intercepteur HTTP. Je pense que vous pourrez peut-être utiliser votre intercepteur pour changer toutes les dates du corps en autre chose.

entrez la description du lien ici est un exemple du fonctionnement de l'intercepteur. Dans l'exemple, un en-tête est ajouté. Voici et voici un exemple de modification du corps.

1 Becike Dec 04 2020 at 15:03

J'ai eu le même problème. Je pourrais résoudre ce problème en remplaçant le convertisseur de date JSON dans le composant de l'application:

overrideToJSONDate() {
    Date.prototype.toJSON = function () {
      return new Date(this).toLocaleString();
    }
  }

J'appelle cette fonction une fois dans le constructeur du composant d'application. Vous pouvez appliquer et logique à l'intérieur de la fonction, mais assurez-vous de revenir avec la chaîne actuelle.