Using single form for create and edit in Angular using Reactive Form Approach
Published: 2024-01-24 11:36:34


In Angular, the Reactive Forms approach provides a powerful and flexible way to manage form-related operations within a web application. When creating or editing data, it is common to use a single form to streamline the user experience and codebase. This approach simplifies the development process by reusing the same form component for both creating and editing records.

The key concept behind using a single form for create and edit functionalities is to dynamically adjust the form's behavior based on the application's context. Angular Reactive Forms allow developers to define and manipulate forms programmatically, making it easier to adapt the form's structure and validation rules.

Here's a step-by-step breakdown of how this approach can be implemented:

Form Initialization:

Create a reactive form using Angular's FormGroup and FormControl classes.
Define form controls for each input field, specifying initial values and validation rules.
Detecting Mode (Create/Edit):

Determine whether the form is used for creating a new record or editing an existing one. This can be based on a route parameter, a service state, or any other contextual information.
Dynamic Form Adjustments:

Based on the detected mode, conditionally enable or disable form controls.
Set initial values for form controls when in edit mode, fetching data from the backend or any other source.
Submit Handling:

Implement a form submission handler that can be used for both create and edit operations.
For create, send a POST request to the server with the form data.
For edit, send a PUT or PATCH request with the updated data.
User Interface Adjustments:

Adjust the user interface based on the mode. This may include changing button labels, hiding or showing certain elements, or providing appropriate notifications.
Reactive Form Benefits:

Leverage the power of Angular Reactive Forms for dynamic form control handling, validation, and overall form management.
Easily handle complex form scenarios with nested form groups and form arrays.
By employing a single form for both create and edit operations, developers can maintain a cleaner and more modular codebase, reducing redundancy and making it easier to maintain and extend the application. This approach aligns with the principles of DRY (Don't Repeat Yourself) and promotes a consistent user experience across the application.

`import { Component, Inject, NO_ERRORS_SCHEMA, OnInit } from '@angular/core';
  ngOnInit(): void {
    this.getTeacher()
    if(this.data.teachers) this.selectedTeacher = this.data.teachers.firstName + ' ' + this.data.teachers.lastName

    if (this.data.student) {
      this.studentTeacherForm = this.formBuilder.group({
        firstName: ['', Validators.required],
        lastName: ['', Validators.required],
        standard: ['', [Validators.required, Validators.max(12), Validators.min(1)]],
        teachers: [null, Validators.required],
      })
    }
    else {
      this.studentTeacherForm = this.formBuilder.group({
        firstName: ['', Validators.required],
        lastName: ['', Validators.required],
        subjectOfTeacher: ['', Validators.required],
      })
    }
    this.formPatchValue()
  }
`

`  formPatchValue() {
    if (this.data.student  && this.data.firstName) {
      this.studentTeacherForm.patchValue({
        firstName: this.data.firstName,
        lastName: this.data.lastName,
        standard: this.data.standard ? this.data.standard : "",
        teachers: this.data.teachers
      })
    }
    else if(!this.data.student && this.data.firstName) {
      this.studentTeacherForm.patchValue({
        firstName: this.data.firstName,
        lastName: this.data.lastName,
        subjectOfTeacher: this.data.subjectOfTeacher

      })
    }
  }

  getTeacher() {
    this.crudService.getTeacher().subscribe((data: any) => {
      if (data) {
        this.teacherSubjects = data
      }
    })
  }
`

  `createTeacherStudent() {
    console.log('called', this.studentTeacherForm)
    if (this.studentTeacherForm.valid) {

      if (this.data && this.data.student && !this.data.firstName) {
        let obj = { ...this.studentTeacherForm.value }
        this.crudService.createStudent(obj).subscribe((data)=>{
          if (data) {
            this._snackBar.open('Student Created Succefully!')
            setTimeout(() => {
              this._snackBar.dismiss()
            }, 3000);
            this.dialogRef.close(true)
          }
        },err=>{
          console.log('err',err)
        })
      }
      else if (this.data && !this.data.student && !this.data.firstName) {
        console.log('called')
        let obj = { ...this.studentTeacherForm.value }
        this.crudService.createTeacher(obj).subscribe((data) => {
          if (data) {
            this._snackBar.open('Teacher Created Succefully!')
            setTimeout(() => {
              this._snackBar.dismiss()
            }, 3000);
            this.dialogRef.close(true)
          }
        })
      }
      if (this.data.firstName && !this.data.student) {
        let obj = { ...this.studentTeacherForm.value,id:this.data.id }
        this.crudService.updateTeacher(obj).subscribe((data) => {
          if (data) {
            this._snackBar.open('Teacher Updated Succefully!')
            setTimeout(() => {
              this._snackBar.dismiss()
            }, 3000);
            this.dialogRef.close(true)
          }
        })
      }
      else {
        let obj = { ...this.studentTeacherForm.value,id:this.data.id }

        this.crudService.updateStudent(obj).subscribe((data) => {
          if (data) {
            this._snackBar.open('Student Updated Succefully!')
            setTimeout(() => {
              this._snackBar.dismiss()
            }, 3000);
            this.dialogRef.close(true)
          }
        })
      }
    }

  }
}
`

code given for your reference please go through it 
and share your response in comments if you like my post and learned something new from this post