0

I want patch a single value inside a nested FormArray. The patching value is a base64encode of files. And, this patch should happen on onFileChange event. But, somehow, it's not working and showing the error, patchValue is not a function. The following is the line of code that I am using to patch the value : this.uploader.controls['sections']['value'][this.valueofitem].patchValue({afterImage: btoa(binaryString)});.
And it is written inside the file reader function. Please see the code below.

Component.ts file

import {Component, OnDestroy, OnInit, ElementRef, ViewChild} from '@angular/core';
import {Router, ActivatedRoute} from '@angular/router';
import {FileuploaderService} from '../fileuploader.service';
import {CountryService} from '../../country/country.service';
import {ServicelocationsService} from '../../servicelocations/servicelocations.service';
import {CategoriesService} from '../../categories/categories.service';
import {FormBuilder, FormGroup, Validators, FormArray, FormControl} from '@angular/forms';

@Component({
  selector: 'app-services-cu',
  templateUrl: '../pages/fileuploader-cu.component.html'
})

export class FileuploaderCuComponent implements OnInit {
  uploader: FormGroup;
  profilepicSize = 0;
  valueofitem = 0;

  constructor() {
  }

  ngOnInit() {
    this.uploader = new FormGroup({
      sections: new FormArray([
        this.initSection(),
      ]),
    });
  }

  initSection() {
    return new FormGroup({
      beforeImage: new FormControl(''),
      afterImage: new FormControl('')
    });
  }

  addSection() {
    const control = <FormArray> this.uploader.get('sections');
    control.push(this.initSection());
  }

  getSections(form) {
    return form.controls.sections.controls;
  }

  removeSection(i) {
    const control = <FormArray> this.uploader.get('sections');
    control.removeAt(i);
  }

  onSubmit(form) {
    // console.log(this.uploader);
    // this.uploader.controls['sections']['value'][this.valueofitem].afterImage = 'Test';
    // console.log(this.uploader.controls['sections']['value']);
    const reader = new FileReader();
    for (const images of this.uploader.controls['sections']['value']) {
      console.log(images.afterImage);
    }
  }

  onFileChange(event, i) {
    const reader = new FileReader();
    if (event.target.files && event.target.files.length) {
      const [file] = event.target.files;
      this.profilepicSize = file.size;
      this.valueofitem = i;
      reader.readAsBinaryString(file);
      reader.onload = this._handleReaderLoaded.bind(this);
    }

  }
  _handleReaderLoaded(readerEvt) {
    const binaryString = readerEvt.target.result;
    // this.uploader.patchValue({
    //   beforeImage: btoa(binaryString)
    // });
    const control = <FormArray> this.uploader.get('sections');
    // console.log(this.uploader.controls['sections']['value'][this.valueofitem].afterImage);
   this.uploader.controls['sections']['value'][this.valueofitem].patchValue({afterImage: btoa(binaryString)});
  }
}

Component.html file

    <div class="row">
  <div class="col-md-12 col-sm-12 col-xs-12">
    <div class="x_panel">
      <form [formGroup]="uploader" novalidate (ngSubmit)="onSubmit(uploader)">
        <!--- Section -->
        <div class="row">
          <div formArrayName="sections">
            <div class="row" *ngFor="let section of getSections(uploader); let i = index">
              <div class="col-md-12 col-sm-12 col-xs-12">
                <div [formGroupName]="i">
                  <!---Uploader Section -->
                  <div class="col-sm-12 col-md-4">
                    <div class="input-group margin-bottom-sm">
                      <label>Before:</label>
                      <input type="file" formControlName="beforeImage" accept=".jpeg, .jpg, .png" class="form-control">
                      <span style="font-size:12px;">(Formats:jpeg, jpg, png Size: 1MB)</span>
                    </div>
                  </div>
                  <div class="col-sm-12 col-md-4">
                    <div class="input-group margin-bottom-sm">
                      <label>After:</label>
                      <input type="file" formControlName="afterImage" accept=".jpeg, .jpg, .png" class="form-control"
                             (change)="onFileChange($event,i)">
                      <span style="font-size:12px;">(Formats:jpeg, jpg, png Size: 1MB)</span>
                    </div>
                  </div>
                  <!---End of Uploader Section -->
                </div>
                <br>
                <button type="button" (click)="addSection()" class="btn btn-info btn-sm">Add More</button>
                <button type="button" class="btn btn-danger btn-sm" *ngIf="getSections(uploader).length > 1"
                        (click)="removeSection(i)">Remove Section
                </button>
              </div>
            </div>
          </div>
        </div>
        <!-- End Section -->
        <hr>
        <div class="row">
          <div class="col-md-6 col-md-offset-6">
            <div *ngIf="errors" class="alert alert-danger">{{errors.error|json}}</div>
            <!--<a class="btn btn-warning pull-right" [routerLink]="'/controlpanel/users/'"> Cancel</a>-->
            <a class="btn btn-danger pull-right" [routerLink]="'/company/services/'"><i class="fa fa-close"></i>
              Cancel</a>
            <button class="btn btn-primary pull-right" [disabled]="loading" type="submit">{{ actionType }}
            </button>
          </div>
        </div>
      </form>
      <pre> {{uploader.value | json}} </pre>
    </div>
  </div>
</div>
Michael Técourt
  • 3,457
  • 1
  • 28
  • 45
Jinto Antony
  • 458
  • 8
  • 26
  • Can you provide a StackBlitz? – Prashant Pimpale Feb 21 '19 at 05:31
  • @PrashantPimpale Hi, https://stackblitz.com/edit/angular-hy8prm – Jinto Antony Feb 21 '19 at 05:40
  • Getting error's in the Stackblitz! – Prashant Pimpale Feb 21 '19 at 06:15
  • patchValue is applied to a FormControl, so I imagine you want to make this.uploader.controls.sections[i].patchValue({afterImage: btoa(binaryString)}); NOTE:In the stackblitz change the selector of app-component by "my-app" – Eliseo Feb 21 '19 at 07:41
  • @Eliseo stackblitz updated. I have this issue, I can select two files. and it will convert to base64 when selecting a file. The problem is that, when I select the second file, it changes the value of the first selected file to fake path. Is there any way to prevent this ? – Jinto Antony Feb 21 '19 at 08:45
  • @PrashantPimpale Stackblitz updated. I have this issue, I can select two files. and it will convert to base64 when selecting a file. The problem is that, when I select the second file, it changes the value of the first selected file to fake path. Is there any way to prevent this ? – Jinto Antony Feb 21 '19 at 08:45
  • @JintoAntony have a look at:https://stackoverflow.com/questions/4851595/how-to-resolve-the-c-fakepath – Prashant Pimpale Feb 21 '19 at 09:37
  • Alternate option:https://stackblitz.com/edit/angular-h8cx2r – Prashant Pimpale Feb 21 '19 at 09:37

0 Answers0