Search code examples
angularinternet-explorerpolyfillsngx-formly

IE: Add FormData polyfill to angular with formly


I'm using https://www.npmjs.com/package/formdata-polyfill and nxg formly in a angular project my form has a file upload field configured in formly. Now we have to support IE and a polyfill is required to get this working but I have no idea how to add it. The error is that FormData.get is not supported in IE and needs a polyfill.

polyfills.ts

...
import 'formdata-polyfill';

form.component.ts

...
this.fields = [
    {
      key: 'file',
      id: 'field_import_file',
      type: 'file-upload',
      templateOptions: {
        required: true,
        fieldName: 'Import File',
        floatLabel: 'always',
        appearance: 'outline'
      },
      validation: {
        validators: ['file-upload']
      }
    }
  ];

Solution

  • Not seen any good solutions but I did make a workaround, posted below in case anyone else has this issue. Note this is a workaround not a proper solution.

    in this case I made a hidden form on the page and created a fake file upload field in formly that simulated the event's of the hidden form upload field.

    fake-upload.component.ts

    import { Component } from '@angular/core';
    import { FieldType } from '@ngx-formly/material';
    import { CustomTemplateOptions } from '../../../../../../kup-core/src/lib/models';
    
    @Component({
      selector: 'app-fake-upload-field',
      template: `
        <div>
          <button
            (click)="onClick()"
            [id]="id"
            type="file"
            [formControl]="formControl"
            [formlyAttributes]="field"
            (change)="onChange()"
            ngDefaultControl
            [name]="id"
            mat-stroked-button
          >
            Choose File
          </button>
          <input
            type="text"
            [value]="to.data.filename"
            class="fake-file-upload-input"
            (change)="onChange()"
          />
        </div>
      `,
      styles: [
        `
          .fake-file-upload-input {
            padding: 0;
            margin: 0;
            border: none;
          }
        `
      ]
    })
    export class FakeUploadComponent extends FieldType {
      to: CustomTemplateOptions;
    
      onClick() {
        document.getElementById('realFileUpload').click();
      }
    
      onChange() {}
    }
    

    then manually added the file values back into the formly form model,

    then hidden the forms submit buttons created a fake form submission panel that simulated the events and validation of the formly form the old fashioned way.

      onHiddenFileUploadChange($event) {
        const el: any = document.querySelector('.fake-file-upload-input');
    
        this.stagedFile = $event.target.files;
        this.stagedFilename = $event.target.files[0].name;
    
        el.value = this.stagedFilename;
        this.checkForm();
      }
    
      triggerSave() {
        const form: HTMLElement = document.getElementById('importForm');
        const button: HTMLElement = form.querySelector('button[type=submit]');
        button.click();
      }
    
     private onImportTypeChanged(value: FormlyFieldConfig[]): void {
        this.viewModel.importTypes.map(type => {
          if (type.name === value[0].formControl.value) {
            value[1].formControl.patchValue(type.description);
            this.stagedType = type.name;
          } else if (!value[0].formControl.value) {
            this.stagedType = '';
          }
        });
      }
    

    This was the only way I could find to workaround formly's lack of legacy ie support without forking formly and customizing it directly.