Data padrão para formato de conversão JSON no aplicativo Angular
Suponha que um componente (dentro do aplicativo angular) tenha várias formas reativas contendo datepickers (estou usando mat-datepicker
do angular material lib) e outras entradas. Depois que um usuário clica no botão "Enviar", eu envio o valor dos formulários para o backup (com HttpClient.post
). O problema é que os campos do datepicker são serializados como "2020-11-18T22:00:00.000Z"
(obviamente, o Date.toJSON()
método é chamado), enquanto o backend espera outro formato.
Observe que estou usando formly
lib para construir meus formulários, pois o conjunto de componentes em cada formulário pode variar. Você pode não estar familiarizado, formly
mas de qualquer forma o conjunto de selecionadores de data pode variar também, então não posso converter campos de selecionador de data diretamente porque não sei a lista exata de campos de data em um lugar para onde envio o valor dos formulários.
Existe uma solução elegante para o meu problema? Não consigo pensar em algo melhor do que monkey-patching Date.prototype.toJSON()
ou loop através de objetos enviados no servidor, verifique o tipo de campos e altere o campo se for um Date
? Não consigo encontrar uma maneira de definir o formato de saída de valor pelo selecionador de data, tanto no material quanto na forma.
Respostas
Implementar ControlValueAccessor seria uma solução elegante. A ideia é criar um componente selecionador de data que usa seu formato de data como entrada e o envia de volta como saída.
Para isso, basta criar um novo componente que eu chamaria MatDatepickerWrapperComponent
para este exemplo. O modelo deste componente não seria nada mais do que o selecionador de data de material:
<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>
Do lado do componente, você terá que implementar ControlValueAccessor e fazer as transformações necessárias:
writeValue(value: string): void {
this.model = transformDateFromMyFormatToIso(value);
}
modelChange(value: string) {
const transformedValue = transformIsoDateToMyFormat(value);
this.onChange(transformedValue);
}
Agora você pode adicionar o novo componente a um formulário da forma como teria adicionado o original.
Aqui está um exemplo de stackblitz em execução.
Eu tentaria usar um interceptor HTTP. Acho que você pode usar seu interceptador para alterar todas as datas no corpo para outra coisa.
insira a descrição do link aqui é um exemplo de como o interceptor funciona. No exemplo, um cabeçalho é adicionado. Aqui e aqui estão um exemplo de modificação do corpo.
Eu tive o mesmo problema. Eu poderia resolver isso substituindo o conversor de data JSON no componente do aplicativo:
overrideToJSONDate() {
Date.prototype.toJSON = function () {
return new Date(this).toLocaleString();
}
}
Eu chamo essa função uma vez no construtor do componente do aplicativo. Você pode aplicar uma lógica dentro da função, mas certifique-se de retornar com a string atual.