Data padrão para formato de conversão JSON no aplicativo Angular

Nov 30 2020

Suponha que um componente (dentro do aplicativo angular) tenha várias formas reativas contendo datepickers (estou usando mat-datepickerdo 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 formlylib para construir meus formulários, pois o conjunto de componentes em cada formulário pode variar. Você pode não estar familiarizado, formlymas 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

1 ibenjelloun Dec 04 2020 at 15:23

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 MatDatepickerWrapperComponentpara 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.

1 RobinDijkhof Dec 04 2020 at 05:26

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.

1 Becike Dec 04 2020 at 15:03

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.