0

I need to pass a value from an input of type File to to an object in which is my ngModel. To upgrade was easy, but I'm not able to make that value change in the view (two-way) part. When submitting the form the object appears as undefined, if I set the object in hand when starting the component it works, however of course, it needs to be changed according to the file that the user selects.

Html component:

<div class="file-field input-field row col s12" [formGroup]="group">
  <div class="btn">
    <span>{{ config.label }}</span>
    <input type="file"
     [(ngModel)]="fileModel" 
     (change)="getImage($event)"
     [formControlName]="config.name"
     accept="{{ config.accept }}"
    >
  </div>
  <div class="file-path-wrapper">
    <input class="file-path validate" type="text">
  </div>
</div>

component:

 fileModel: FileModel;

  getImage(event) {
    if (event.target.files)  {
      var fileToUpload = event.target.files[0];

      var fileReader = new FileReader();
      var fileModel: FileModel;

      var reader = new FileReader();
      reader.onload = (function (theFile) {
        var fileName = theFile.name;
        return function (e) {
          this.fileModel = new FileModel(fileName, e.target.result);
          console.log(this.fileModel);
        };
      })(fileToUpload);
      reader.readAsDataURL(fileToUpload);
    }
  }
}

Component in which you have the form and the submit:

    @Component({
      ...
    })
    export class IwtiFuncionarioNovoComponent implements OnInit, AfterViewInit {

      @ViewChild(DynamicFormComponent) iwtiFuncionarioNovoForm: DynamicFormComponent;
      config: FieldConfig[] = [];
      opcoesCargos = new Array<SelectData>();
      opcoesSetores = new Array<SelectData>();

      constructor(
        ...
      ) { }

      ngOnInit() {

        this.config.push(this.controlService.createInput('nome', 'input', 'text', 'Nome', true, [Validators.required]));
        this.config.push(this.controlService.createSelectDropdownInput<Setor>('setorId', 'Setor', this.opcoesSetores, 'Selecione...', [Validators.required]));
        this.config.push(this.controlService.createSelectDropdownInput<Cargo>('cargoId', 'Cargo', this.opcoesCargos, 'Selecione...', [Validators.required]));
        this.config.push(this.controlService.createInput('username', 'input', 'text', 'Usuário', false, [Validators.required]));
        this.config.push(this.controlService.createInput('password', 'input', 'password', 'Senha', false, [Validators.required]));
        this.config.push(this.controlService.createInputFile('imagem', 'Foto', true));
        this.config.push(this.controlService.createSubmitButton('Salvar', 'save'));


      }

  submit(iwtiFuncionarioForm: any) {
    this.ambiente.invertBusy();
    console.log(iwtiFuncionarioForm);
    this.ambiente.invertBusy();   
  }
}

This component is where I create the form via reactiveForm and define the form inputs. The problem is in the component that has the inpu file. How to do to the result I have in this.fileModel pass to the submit of this form? Via ngModel does very well, but the input file does not accept the run-time change for this type of input.

Luiz Negrini
  • 656
  • 10
  • 32
  • 1
    Try to print `console.log(this)` front of `console.log(this.fileModel);` then you can understand what is going on – yurzui Jun 27 '17 at 20:21
  • The model fillet value is changed in this method. I already tested it and it appears normally filled, however in ngModel does not receive. Console.log (this) showed the fileReader filled correctly as well. Remember that as I said in explanation, the value of fileModel is correct, I did the same with it: console.log (this.fileModel) there in code and it is filled as it should. – Luiz Negrini Jun 27 '17 at 20:25
  • Is `this` instance of your component? – yurzui Jun 27 '17 at 20:27
  • do not. However, how can you set the fileModel to be that this.fileModel inside the console.log appears populated? I'm confused – Luiz Negrini Jun 27 '17 at 20:28
  • arrow function or `var self = this` – yurzui Jun 27 '17 at 20:30
  • `reader.onload = (e) => { this.fileModel = new FileModel(fileToUpload.name, e.target.result); console.log(this.fileModel); }` – yurzui Jun 27 '17 at 20:33
  • E.target.result does not exist, the result does not exist. – Luiz Negrini Jun 27 '17 at 20:35
  • Explain what to do with the self, I do not understand. – Luiz Negrini Jun 27 '17 at 20:35
  • 1
    https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_this – yurzui Jun 27 '17 at 20:38
  • estou tendo este erro quando altero o valor de self: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string. – Luiz Negrini Jun 27 '17 at 20:38
  • I read that it is not possible to change the value of ngModel when it is in an input type = "file", is it correct? What to do in this case? – Luiz Negrini Jun 27 '17 at 20:57
  • I do not think ngModel works for input type="file". https://stackoverflow.com/questions/40421148/access-input-files-using-ngmodel – wannadream Jun 27 '17 at 21:07
  • @wannadream The harder I picked up that is the data file. But the problem now is to pass to the model that is inside the submit of the form, that this, is in another component because I am using reactive forms. I do not know any other way to pass data without being with NgModel – Luiz Negrini Jun 27 '17 at 21:11
  • @wannadream However only works if when the component is already loaded with a value. If it is changed then it is giving this error up. – Luiz Negrini Jun 27 '17 at 21:13
  • I am a little confused. You should drop ngModel and manipulate fileModel in (change) function. – wannadream Jun 27 '17 at 21:22
  • @wannadream I'm using reactiveForms. Then this inputfile component does not have the data of the other component that is who receives the data. I'll change the question by showing the other component. When I submit the form if you remove ngModel the binding is not done because there is nothing that connects the result of the event "change ($ event)" with my form.image. – Luiz Negrini Jun 27 '17 at 21:24
  • I changed the question if I could look again. Now I only go in tomorrow. Thanks for listening. @wannadream – Luiz Negrini Jun 27 '17 at 21:32
  • This is the only one I can find which is relevant to your question. https://stackoverflow.com/questions/43444440/how-to-include-a-file-upload-control-in-an-angular2-reactive-form – wannadream Jun 27 '17 at 21:32
  • My code takes the byteArray of the image and needs to join it to a json composed of more data in a form, not sending the image of the entire form separately. @wannadream – Luiz Negrini Jun 27 '17 at 21:34

0 Answers0