7

Good day,

How can i handle input type file in formControl? im using reactive form but when i get the value of my form it returns null value on my <input type="file">??

Jydon Mah
  • 383
  • 1
  • 9
  • 29

2 Answers2

13

You need to write your own FileInputValueAccessor. Here is the plunker and the code:

@Directive({
  selector: 'input[type=file]',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: FileValueAccessorDirective,
      multi: true
    }
  ]
})
export class FileValueAccessorDirective implements ControlValueAccessor {
  onChange;

  @HostListener('change', ['$event.target.value']) _handleInput(event) {
    this.onChange(event);
  }

  constructor(private element: ElementRef, private render: Renderer2) {  }

  writeValue(value: any) {
    const normalizedValue = value == null ? '' : value;
    this.render.setProperty(this.element.nativeElement, 'value', normalizedValue);
  }

  registerOnChange(fn) {    this.onChange = fn;  }

  registerOnTouched(fn: any) {  }

  nOnDestroy() {  }
}

And then you will be able to get updates like this:

@Component({
  moduleId: module.id,
  selector: 'my-app',
  template: `
      <h1>Hello {{name}}</h1>
      <h3>File path is: {{path}}</h3>
      <input type="file" [formControl]="ctrl">
  `
})
export class AppComponent {
  name = 'Angular';
  path = '';
  ctrl = new FormControl('');

  ngOnInit() {
    this.ctrl.valueChanges.subscribe((v) => {
      this.path = v;
    });
  }
}
Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • Thanks Maximus, but how can i get the full path of the file? in your example you get the file path with `C:\fakepath\sample.xls` is their a way on getting the full path file? im trying to get the file path so i can send it on the server. – Jydon Mah Jul 21 '17 at 08:29
  • @JydonMah, what do you mean `full` file path? This is the absolute file path – Max Koretskyi Jul 21 '17 at 08:34
  • just for example my file is located at 'C:\documents\sample.xls' it should return the `C:\documents\sample.xls` and not the `C:\fakepath\sample.xls`. – Jydon Mah Jul 21 '17 at 08:37
  • unfortunately, a browser doesn't expose that information because of security reasons. See [here](https://stackoverflow.com/questions/15201071/how-to-get-full-path-of-selected-file-on-change-of-input-type-file-using-jav). The only thing you can get is `fileName` – Max Koretskyi Jul 21 '17 at 08:43
  • 1
    Thanks Maximus for your example and info ;) finally understand it. many thanks. – Jydon Mah Jul 21 '17 at 08:47
  • @JydonMah, great, consider accepting or upvoting my answer then, thanks – Max Koretskyi Jul 24 '17 at 06:38
  • @MaximKoretskyi I really liked your approach here. I've searched a lot until I finally found this reasonable solution. Would you mind to post it somewhere? Maybe on [**medium**](https://medium.com)? Also, a little question... doing this way, how can I display a thumbnail of the file? Could you expalin me or maybe add an example? Thanks. – dev_054 Aug 25 '17 at 02:34
  • @dev_054, yeah, I think I'll put up an article on medium soon. Regarding your question, can you please post a separate question and put the relevant details into the question details? You can then post a link to the question as a comment here – Max Koretskyi Aug 26 '17 at 10:54
  • I'm getting error --- ERROR Error: More than one custom value accessor matches form control with unspecified name attribute – ER.SHASHI TIWARI Jan 20 '19 at 07:00
1

there is no way to handle this in angular form-control. we can provide some hack to make this work if you want to upload the image. just add the <input type=file> as form control on which user can add the file and acter grabbing the file we can change it to the base64code and then assign that value to the hidden field of our main form. then we can store the image file in that way.

else you can go for the ng-file-upload moduleng file upload

Sahil Kashetwar
  • 159
  • 1
  • 7
  • thanks for this advice, ill try to use local reference and pass value on it, but how can we get the full path of file after grabing that value? im getting fakepath everytime i get the value of input files – Jydon Mah Jul 21 '17 at 07:49
  • you can implement your own value accessor to specific input types, see [my answer](https://stackoverflow.com/a/45232279/2545680) – Max Koretskyi Jul 21 '17 at 08:46
  • great solution we can go for this as well. – Sahil Kashetwar Jul 21 '17 at 09:31