Raiyan Rashid Prodhan
Raiyan Rashid Prodhan

Reputation: 27

Angular makes a post request automatically while trying to create form fields dynamically using reactive forms

I'm trying to create an angular reactive form where the user will be able to input multiple dates in a single form by pressing the Add (+) button, which will dynamically create form fields for taking date-type inputs. I want the user to be able to add as many dates as they want and after adding all the dates the user will press the submit button and the data will be sent to the backend. But in my code, whenever I press the Add (+) button to create a new form field it automatically calls the onSubmit() function from the sample.component.ts file instead of just calling the addReportingDate() function, which is making an unwanted post request. How can I fix this issue?

sample.component.html

<h2 mat-dialog-title>
  KPI
</h2>
<div mat-dialog-content class="create-department-form">
  <form
    [formGroup]="kpiForm"
    class="department-form"
    (ngSubmit)="onSubmit()"
  >
    <mat-form-field>
      <mat-label>KPI Name</mat-label>
      <label>
        <input formControlName="name" matInput/>
      </label>
    </mat-form-field>
    <mat-form-field>
      <mat-label>KPI Weight</mat-label>
      <label>
        <input type="number" formControlName="weight" matInput/>
      </label>
    </mat-form-field>
    <mat-form-field>
      <mat-label>Select Department Name</mat-label>
      <input type="text"
              placeholder="Pick one"
              aria-label=""
              matInput
              formControlName="departmentId"
              [matAutocomplete]="auto1"
              (keyup)="onKey($event)">
      <mat-autocomplete #auto1="matAutocomplete">
        <mat-option *ngFor="let department of departments" [value]="department.id">
          {{department.id + ' - ' + department.name}}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>
    <mat-form-field>
      <mat-label>Select Employee List</mat-label>
      <input type="text"
              placeholder="Pick one"
              aria-label=""
              matInput
              formControlName="employeeId"
              [matAutocomplete]="auto2"
              (keyup)="onKey($event)">
      <mat-autocomplete #auto2="matAutocomplete">
        <mat-option *ngFor="let employee of employees" [value]="employee.id">
          {{employee.id + ' - ' + employee.name}}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>
    <mat-form-field>
      <mat-label>Select Goal KPI Name</mat-label>
      <input type="text"
              placeholder="Pick one"
              aria-label=""
              matInput
              formControlName="goalKpiId"
              [matAutocomplete]="auto"
              (keyup)="onKey($event)">
      <mat-autocomplete #auto="matAutocomplete">
        <mat-option *ngFor="let goalKpi of goalKpis" (click)="updateGoalKpiSpaceStatus(goalKpi)" [value]="goalKpi.id">
          {{goalKpi.id + ' - ' +goalKpi.name}}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>
    <span *ngIf="selectedGoalKpiWeight">
      <span class="status">Selected Goal KPI Weight: {{selectedGoalKpiWeight ? selectedGoalKpiWeight : 'N/A'}}</span>
      <span class="status">Total Weight Taken: {{selectedGoalKpiTakenWeight ? selectedGoalKpiTakenWeight : 'N/A'}}</span>
      <span class="status">Remaining Weight: {{selectedGoalKpiRemainingWeight ? selectedGoalKpiRemainingWeight : 'N/A'}}</span>
    </span>
    <mat-form-field>
      <mat-label>Add Reporting Date(s)</mat-label>
      <div formArrayName="reportingDates">
        <div *ngFor="let date of reportingDates.controls; let dateIndex=index" [formGroupName]="dateIndex">
          <input type="date" formControlName="date" matInput/>
          <button id="deleteButton" (click)="deleteReportingDate(dateIndex);" mat-mini-fab color="warn" aria-label="Delete reporting date.">
            <mat-icon>delete</mat-icon>
          </button>
        </div>
        <button id="addButton" (click)="addReportingDate()" mat-mini-fab color="primary" aria-label="Add another reporting date.">
          <mat-icon>add</mat-icon>
        </button>
      </div>
    </mat-form-field>
  </form>
</div>

<div mat-dialog-actions>
  <button
    (click)="onSubmit()"
    type="submit"
    mat-raised-button
    color="primary"
    [disabled]="!kpiForm.valid"
  >
    Submit
  </button>
  <button mat-raised-button color="warn" type="button" (click)="onNoClick()">
    Cancel
  </button>
</div>

sample.component.ts file

@Component({
  selector: 'app-add-edit-kpi-dialog',
  templateUrl: './add-edit-kpi-dialog.component.html',
  styleUrls: ['./add-edit-kpi-dialog.component.scss']
})
export class AddEditKpiDialogComponent implements OnInit {

  kpiForm: FormGroup;
  goalKpis: IGoalKpi[];
  departments: IDepartmentList[];
  employees: IEmployeeList[];
  value: string;
  selectedGoalKpiWeight: number;
  selectedGoalKpiTakenWeight = 0;
  selectedGoalKpiRemainingWeight = 0;

  constructor(
    private dialogRef: MatDialogRef<AddEditKpiDialogComponent>,
    private formBuilder: FormBuilder,
    private dialog: MatDialog,
    private goalKpiService: GoalKpiService,
    private kpiService: KpiService,
    private departmentService: DepartmentService,
    private employeeService: EmployeeService,
    private loaderService: NgxUiLoaderService,
    private alertService: AlertService,
    @Inject(MAT_DIALOG_DATA) public data: {
      isEdit: boolean,
      kpiData: IKpi
    }
  ) {
    this.kpiForm = this.formBuilder.group({
      name: ['', Validators.required],
      weight: ['', Validators.required],
      goalKpiId: ['', Validators.required],
      departmentId: ['', Validators.required],
      employeeId: ['', Validators.required],
      reportingDates: this.formBuilder.array([this.formBuilder.group({date: ''})]),
    });
  }

  ngOnInit(): void {
    this.loadAllRequiredData();

    if (this.data.isEdit) {
      this.populateForm();
    }
  }

  get reportingDates() {
    return this.kpiForm.get('reportingDates') as FormArray;
  }

  addReportingDate() {
    this.reportingDates.push(this.formBuilder.group({date: ''}));
  }

  deleteReportingDate(index) {
    this.reportingDates.removeAt(index);
  }

  populateForm() {
    this.kpiForm.controls.name.setValue(this.data.kpiData.name);
    this.kpiForm.controls.weight.setValue(this.data.kpiData.weight);
    this.kpiForm.controls.goalKpiId.setValue(this.data.kpiData.goalKpiName);
    this.kpiForm.controls.employeeId.setValue(this.data.kpiData.employeeName);
    this.kpiForm.controls.departmentId.setValue(this.data.kpiData.departmentName);
  }

  loadAllRequiredData() {
    this.loaderService.start();
    forkJoin([
      this.departmentService.getDepartmentByName(''),
      this.employeeService.getEmployeeByName(''),
      this.goalKpiService.getGoalKpiByName(''),
    ]).subscribe(response => {
      this.departments = response[0].data;
      this.employees = response[1].data;
      this.goalKpis = response[2].data;
    }, error => {
      this.loaderService.stop();
    }, () => {
      this.loaderService.stop();
    });
  }

  updateGoalKpiSpaceStatus(goalKpi: any) {
    this.loaderService.start();
    this.selectedGoalKpiWeight = goalKpi.weight;
    this.kpiService.getToalWeightOfKpisByGoalKpiId(goalKpi.id).subscribe(response => {
     this.selectedGoalKpiTakenWeight = response.data;
    }, error => {
      this.loaderService.stop();
    }, () => {
      this.selectedGoalKpiRemainingWeight = this.selectedGoalKpiWeight - this.selectedGoalKpiTakenWeight;
      this.loaderService.stop();
    });
  }

  loadDataOnSearchResult(name: string, fieldName: string){
    if (fieldName === 'goalKpiId') {
      this.loaderService.start();
      this.goalKpiService.getGoalKpiByName(name)
      .subscribe(response => {
        this.goalKpis = response.data;
      }, error => {
        this.loaderService.stop();
      }, () => {
        this.loaderService.stop();
      });
    } else if (fieldName === 'departmentId') {
      this.loaderService.start();
      this.departmentService.getDepartmentByName(name)
      .subscribe(response => {
        this.departments = response.data;
      }, error => {
        this.loaderService.stop();
      }, () => {
        this.loaderService.stop();
      });
    } else if (fieldName === 'employeeId') {
      this.loaderService.start();
      this.employeeService.getEmployeeByName(name)
      .subscribe(response => {
        this.employees = response.data;
      }, error => {
        this.loaderService.stop();
      }, () => {
        this.loaderService.stop();
      });
    }
  }

  onKey(event: any) {
    console.log(event.target);
    console.log(event.target.attributes.formControlName.value);
    this.value = event.target.value;
    this.loadDataOnSearchResult(this.value, event.target.attributes.formControlName.value);
  }

  onSubmit() {
    this.loaderService.start();
    const {id, name, weight, goalKpiId, goalKpiName, departmentId, employeeId} = this.kpiForm.value;
    const kpiData = {
      name,
      weight: +weight,
      goalKpiName
    };

    if (this.data.isEdit) {
      this.kpiService.updateKpiIdByGoalIdKpiId(this.data.kpiData.goalKpiId, this.data.kpiData.id, kpiData)
        .subscribe(response => {
          this.alertService.success('Kpi updated successfully');
          this.dialogRef.close();
        }, error => {
          this.alertService.danger(error.error.message);
          this.loaderService.stop();
        }, () => {
          this.loaderService.stop();
        });
    } else {
      this.kpiService.addNewEmployeeIdByKpiIdEmployeeId(goalKpiId, employeeId, kpiData)
        .subscribe(response => {
          this.alertService.success('Kpi created successfully');
          this.dialogRef.close();
        }, error => {
          this.alertService.danger(error.error.message);
          this.loaderService.stop();
        }, () => {
          this.loaderService.stop();
        });
    }
  }

  onNoClick() {
    this.dialogRef.close({cancel: true});
  }

}


Upvotes: 0

Views: 300

Answers (1)

robert
robert

Reputation: 6152

Try to make your button element have an attribute type="button"

<button id="addButton" type="button"

This will prevent unwanted submit

Upvotes: 1

Related Questions