3

I am getting an empty object with my formData or a bad request error. I want to be able to post back a file upload to the server. I believe that the error is coming from the service since that is where FormData is created. However, the service is sending the formData over as an empty object. I tried looking at different tutorials but everyone uses the Upload method that is in the service differently. I have been stuck on this for two days. If anyone could help that would be great!

  Component,
  OnInit,
  ViewChild,
  ElementRef,
  AfterViewInit,
} from "@angular/core";
import { ActivatedRoute, ParamMap, Router } from "@angular/router";
import { Validators, FormBuilder, FormGroup } from "@angular/forms";
import { HttpEventType, HttpErrorResponse } from "@angular/common/http";
import { switchMap, catchError, map } from "rxjs/operators";
import { Observable, of } from "rxjs";
import { Complaint } from "@shared/models/Complaint";
import { ComplaintService } from "@shared/services/complaint.service";
import { FileUploadService } from "../../shared/services/file-upload.service";
import { CurrentUser } from "@shared/models/user";
import { Assignment } from "@shared/models/assignment";
import { CurrentUserService } from "@shared/services/current-user.service";
import { ComplaineeComponent } from "./complainee/complainee.component";
import { AssignmentComponent } from "./assignment/assignment.component";

@Component({
  selector: "app-create-new-complaint",
  templateUrl: "./create-new-complaint.component.html",
  styleUrls: ["./create-new-complaint.component.scss"],
})
export class CreateNewComplaintComponent implements OnInit {
  //Makes fileUpload accessible to component
  @ViewChild("fileUpload", { static: false }) fileUpload: ElementRef;
  files = [];
  @ViewChild(ComplaineeComponent) complaineeComponent: ComplaineeComponent;
  @ViewChild(AssignmentComponent) assignmentComponent: AssignmentComponent;
  complaintForm: FormGroup;
  complaint$: Observable<Complaint>;
  complaint: Complaint;
  assignments: Assignment[] = [];
  user: CurrentUser;
  fileToUpload: File;
  constructor(
    private fb: FormBuilder,
    private router: Router,
    private route: ActivatedRoute,
    private complaintService: ComplaintService,
    private uploadService: FileUploadService,
    private currentUserService: CurrentUserService
  ) {}
  ngOnInit() {
    // if the complaint form was reached through a link, auto-populate the form
    // because we're going to edit or update it
    // otherwise, create a new blank form
    if (this.route.snapshot.params.id) {
      this.complaint$ = this.route.paramMap.pipe(
        switchMap((params: ParamMap) =>
          this.complaintService.GetComplaint(+params.get("id"))
        )
      );
      this.complaint$.subscribe((d) => {
        this.complaint = d;
        this.updateForm(this.complaint);
      });
    }
    this.currentUserService.getUser().subscribe((d) => {
      this.user = d;
      if (this.assignments.length < 1) {
        console.log("complaint assignments are empty");
        this.assignments.push({
          assigneeLastName: this.user.lastName,
          assigneeFirstName: this.user.firstName,
          employeeId: this.user.id,
          begDate: new Date(),
        });
      }
    });
    this.buildForm();
  }
  onSubmit() {
    let complaint: Complaint = {
      complaint: {
        complainantLastName: this.complaintForm.value.complainantLastName,
        complainantFirstName: this.complaintForm.value.complainantFirstName,
        client: {
          id: this.complaintForm.value.Client,
          caseNumber: this.complaintForm.value.caseNumber,
          lastName: this.complaintForm.value.clientLastName,
          firstName: this.complaintForm.value.clientFirstName,
          middleName: null,
          birthDate: this.complaintForm.value.dob,
        },
        relationshipTypeId: this.complaintForm.value.relationshipType,
        complaintDate: new Date(),
        cwsCmsNumber: this.complaintForm.value.caseNumber,
        divisionId: this.complaintForm.value.division,
        statusId: this.complaintForm.value.status,
        concerns: this.complaintForm.value.concerns,
        concernOutcome: this.complaintForm.value.concernOutcome,
        concernNotes: this.complaintForm.value.concernNotes,
        concernMethodId: this.complaintForm.value.source,
        priorityTypeId: this.complaintForm.value.priority,
        complaintTopicId: this.complaintForm.value.complaintTopic,
        complaintSubTopicId: this.complaintForm.value.complaintSubTopic,
        frequencyTypeId: this.complaintForm.value.frequency,
        finalFolderLocationId: this.complaintForm.value.folderLocation,
        isFosterHome: false,
        isPlacement: false,
        isVisitation: false,
      },
      complaineeEmployee: {
        id: this.complaineeComponent.selectedEmployee.employeeID,
        lastName: this.complaineeComponent.selectedEmployee.lastName,
        firstName: this.complaineeComponent.selectedEmployee.firstName,
        email:
          this.complaineeComponent.selectedEmployee.lastName
            .substring(0, 8)
            .toLowerCase() +
          this.complaineeComponent.selectedEmployee.firstName
            .charAt(0)
            .toLowerCase() +
          "@saccounty.net",
      },
      complaineeSupervisor: {
        id: this.complaineeComponent.selectedEmployee.supervisorID,
        lastName: this.complaineeComponent.selectedEmployee.supLastName,
        firstName: this.complaineeComponent.selectedEmployee.supFirstName,
        email:
          this.complaineeComponent.selectedEmployee.supLastName
            .substring(0, 8)
            .toLowerCase() +
          this.complaineeComponent.selectedEmployee.supFirstName
            .charAt(0)
            .toLowerCase() +
          "@saccounty.net",
      },
      complaineeDivsionManager: {
        id: this.complaineeComponent.selectedEmployee.managerID,
        lastName: this.complaineeComponent.selectedEmployee.mgrLastName,
        firstName: this.complaineeComponent.selectedEmployee.mgrFirstName,
        email:
          this.complaineeComponent.selectedEmployee.mgrLastName
            .substring(0, 8)
            .toLowerCase() +
          this.complaineeComponent.selectedEmployee.mgrFirstName
            .charAt(0)
            .toLowerCase() +
          "@saccounty.net",
      },
    };
    console.log(complaint);
    console.log(this.complaint.complaineeSupervisor.id);
  }
  buildForm() {
    this.complaintForm = this.fb.group({
      // details input group
      complaintTopic: [null, Validators.required],
      complaintSubTopic: [null, Validators.required],
      division: [null, Validators.required],
      status: [null, Validators.required],
      frequency: [null, Validators.required],
      priority: [null, Validators.required],
      source: [null, Validators.required],
      folderLocation: [null, Validators.required],
      concerns: [null, Validators.required],
      concernOutcome: [null, Validators.required],
      concernNotes: [null, Validators.required],
      complaintType: [null],
      // complainant input group
      complainantFirstName: [null, Validators.required],
      complainantLastName: [null, Validators.required],
      // complainee input group
      complaineeFirstName: [null, Validators.required],
      complaineeLastName: [null, Validators.required],
      complaineeDivisionManagerFirstName: [null],
      complaineeDivisionManagerLastName: [null],
      // client input group
      clientFirstName: [null, Validators.required],
      clientLastName: [null, Validators.required],
      dob: [null, Validators.required],
      caseNumber: [null, Validators.required],
      relationshipType: [null, Validators.required],
      attachments: [null, {validators: [Validators.required]}]
    });
  }
  updateForm(complaint) {
    if (complaint) {
      this.complaintForm.patchValue({
        complaintTopic: complaint.complaint.complaintTopicId
          ? complaint.complaint.complaintTopicId
          : "",
        complaintSubTopic: complaint.complaint.complaintSubTopicId
          ? complaint.complaint.complaintSubTopicId
          : "",
        division: complaint.complaint.divisionId
          ? complaint.complaint.divisionId
          : "",
        status: complaint.complaint.statusId
          ? complaint.complaint.statusId
          : "",
        frequency: complaint.complaint.frequencyTypeId
          ? complaint.complaint.frequencyTypeId
          : "",
        priority: complaint.complaint.priorityTypeId
          ? complaint.complaint.priorityTypeId
          : "",
        source: complaint.complaint.concernMethodId
          ? complaint.complaint.concernMethodId
          : "",
        folderLocation: complaint.complaint.finalFolderLocationId
          ? complaint.complaint.finalFolderLocationId
          : "",
        concerns: complaint.complaint.concerns
          ? complaint.complaint.concerns
          : "",
        concernOutcome: complaint.complaint.concernOutcome
          ? complaint.complaint.concernOutcome
          : "",
        concernNotes: complaint.complaint.concernNotes
          ? complaint.complaint.concernNotes
          : "",
        complaintType: "discriminationComplaint",
        complainantFirstName: complaint.complaint.complainantFirstName
          ? complaint.complaint.complainantFirstName
          : "",
        complainantLastName: complaint.complaint.complainantLastName
          ? complaint.complaint.complainantLastName
          : "",
        complaineeFirstName: complaint.complaint.complaineeEmployeeFirstName
          ? complaint.complaint.complaineeEmployeeFirstName
          : "",
        complaineeLastName: complaint.complaint.complaineeEmployeeLastName
          ? complaint.complaint.complaineeEmployeeLastName
          : "",
        complaineeDivisionManagerFirstName: complaint.complaint
          .complaineeDivisionManagerFirstName
          ? complaint.complaint.complaineeDivisionManagerFirstName
          : "",
        complaineeDivisionManagerLastName: complaint.complaint
          .complaineeDivsionManagerLastName
          ? complaint.complaint.complaineeDivsionManagerLastName
          : "",
        clientFirstName:
          complaint.complaint.client && complaint.complaint.client.firstName
            ? complaint.complaint.client.firstName
            : "",
        clientLastName:
          complaint.complaint.client && complaint.complaint.client.lastName
            ? complaint.complaint.client.lastName
            : "",
        dob:
          complaint.complaint.client && complaint.complaint.client.birthDate
            ? complaint.complaint.client.birthDate
            : "",
        caseNumber: complaint.complaint.cwsCmsNumber
          ? complaint.complaint.cwsCmsNumber
          : "",
        relationshipType: complaint.complaint.relationshipTypeId
          ? complaint.complaint.relationshipTypeId
          : "",
      });
    } else {
      // we need to create a new complaint
      // this.complaint = new Complaint();
    }
    this.complaintForm.valid
      ? this.router.navigate(["/edit-complaint"])
      : this.complaintForm;
  }
  //Defines the single upload file method
  uploadFile(file) {
    let formData = new FormData();

    formData.append("file", this.complaintForm.get("attachments").value);
    formData.append("dataType", this.complaintForm.get("attachments").value.type);
    file.inProgress = true;
    console.log("form data before service call: ", formData);
    console.log(`Complaint ${this.complaint.complaint.id}`)
    this.uploadService
      .upload(
        formData,
        this.complaint.complaint.id
      )
      .pipe(
        map((event) => {
          switch (event.type) {
            case HttpEventType.UploadProgress:
              file.progress = Math.round((event.loaded * 100) / event.total);
              break;
            case HttpEventType.Response:
              return event;
          }
        }),
        catchError((error: HttpErrorResponse) => {
          file.inProgress = false;
          return of(`${file.name} upload failed.`);
        })
      )
      .subscribe((event: any) => {
        if (typeof event === "object") {
          console.log(event.body);
        }
      });
  }
  // Defines multiple file Upload method
  // private uploadFiles() {
  //   this.fileUpload.nativeElement.value = "";
  //   this.files.forEach((file) => {
  //     this.uploadFile(file);
  //   });
  // }
  // onFileUpload() {
  //   const fileUpload = this.fileUpload.nativeElement;
  //   fileUpload.onchange = () => {
  //     for (let index = 0; index < fileUpload.files.length; index++) {
  //       const file = fileUpload.files[index];
  //       this.files.push({ data: file, inProgress: false, progress: 0 });
  //     }
  //     this.uploadFiles();
  //   };
  //   fileUpload.click();
  // }

  handleFileInput(files: FileList) {
    console.log('calling handle file input');
    this.fileToUpload = files.item(0);
    console.log('fileToUpload: ', this.fileToUpload);
    this.uploadFile(this.fileToUpload);
  }

  uploadFileToComplaint() {
    this.uploadService.postFile(this.fileToUpload, this.complaint.complaint.id).subscribe(d => {
      console.log('fileToUpload: ', this.fileToUpload);
    });
  }

}

FileUploadService:

  // SERVER_URL: string = "http://cst-api-dev/api/Attachment";
  SERVER_URL: string = env.apiEndpoint + "Attachment";

  constructor(private _http: HttpClient) {}

  public upload(
    formData,
    // mimeType: string,
    complaintId: number
  ) {
    console.log("FORM DATA IN SERVICE file: ", formData);
    return this._http.post<any>(
      this.SERVER_URL,{file: formData, complaintId}, {reportProgress: true,observe: "events",}
    );
  }

  postFile(fileToUpload: File, complaintId) {
    const formData: FormData = new FormData();
    formData.append("fileKey", fileToUpload, fileToUpload.name);
    console.log(formData);
    return this._http
      .post<any>(this.SERVER_URL, { file: formData, complaintId })
      .pipe(map(() => true));
  }

my template

  <form [formGroup]="complaintForm" (ngSubmit)="onSubmit()">
    <mat-card class="complaintant-card">
      <mat-card-header>
        <mat-card-title>Create New Complaint</mat-card-title>
      </mat-card-header>
      <mat-card-content>
        <app-details [complaintForm]="complaintForm"></app-details>
        <app-complaintant [complaintForm]="complaintForm"></app-complaintant>
        <app-complainee [complaintForm]="complaintForm"></app-complainee>
        <app-client [complaintForm]="complaintForm"></app-client>
        <div style="text-align: center; margin-top: 50px;">
          <mat-card style="margin-top: 10px;">
            <mat-card-content>
              <ul>
                <li *ngFor="let file of files">
                  <mat-progress-bar [value]="file.progress"></mat-progress-bar>
                  <span id="file-label"> </span>
                </li>
              </ul>
            </mat-card-content>
            <!-- <mat-card-actions>
              <button mat-raised-button color="primary" type="button" (click)="onFileUpload()">
                <mat-icon>file_upload</mat-icon>
                Attach Files
              </button>
            </mat-card-actions> -->
          </mat-card>
            <input
            formControlName="attachments"
            type="file"
            #fileUpload
            accept="image/*"
            id="fileUpload"
            name="fileUpload"
            (change)="handleFileInput($event.target.files)"/>
        </div>
      </mat-card-content>
      <mat-card-actions>
        <button mat-raised-button color="primary" type="submit">Submit</button>
        <button mat-raised-button color="danger" type="submit">Reset</button>
      </mat-card-actions>
    </mat-card>
  </form>
</div>```

GitFitDev
  • 31
  • 1
  • 3

1 Answers1

2

enctype='multipart/form-data'

use multipart/form-data when your form includes any <input type="file"> elements

  postFile(fileToUpload: File, complaintId) {
    const formData = new FormData();
    formData.append('fileKey', fileToUpload, fileToUpload.name);

    console.log(formData);
   const headers = new HttpHeaders({ 'enctype': 'multipart/form-data' });

    const params: HttpParams = new HttpParams();
    param.set('complaintId', complaintId);

    return this._http
      .post<any>(this.SERVER_URL,formData, { headers: headers, params: params })
      .pipe(map(() => true));
  }
Khaled Lela
  • 7,831
  • 6
  • 45
  • 73