Search code examples
angularangular8angular-reactive-formsangular-formsangular-formbuilder

Angular Subscribe valuechanges in formarray in form group


I'm angular8 and I have a form array inside of form group but I want to detect new changes of a certain input.

ngOnInit(): void {
    this.makeForm = this.fb.group({

     
      
      year:['', Validators.required],
      amount:['', Validators.required],
      desc:['', Validators.required],
      details: new FormArray([
        this.det(), 
      ])
    })


det(){
      return new FormGroup({
        requestfor     : new FormControl(''),
        remarks        : new FormControl('')
    })}


I have to check the data that every value changes in formarray values. But I am getting error if I use

this.makeForm.value.details.get('requestfor').valueChanges

and the error is

ERROR TypeError: Cannot read property 'valueChanges' of undefined

how to get the value inside of form array value

How to get the value.....


Solution

  • You need subscribe to valuesChanges, when you create the FormGroup

    det(){
       //use an auxiliar const
       const group=new FormGroup({
            requestfor     : new FormControl(''),
            remarks        : new FormControl(''),
            // file_id        : new FormControl(''),
        })}
        //subscribe
        group.get('requestForm').valueChanges.subscribe(res=>{
        })
        //return group
        return group;
    }
    

    You can also has an array of Observables, and pass the index to your function det

    changesArray:Observable[]=[] //<--don't forget initialize
    
    det(index=0){
       //use an auxiliar const
       const group=new FormGroup({
            requestfor     : new FormControl(''),
            remarks        : new FormControl(''),
            // file_id        : new FormControl(''),
        })}
        //fill the array
        this.changesArray[index]=group.get('requestForm').valueChanges
        //return group
        return group;
    }
    

    And when you add or delete a new group to the formArray subscribe to a forkJoin of the array

     if (this.subscriptions)
        this.subscriptions.unsubscribe();
    
     this.subscriptions=forkJoin(changesArray)
        this.subscriptions.subscribe(res=>{
     })
    

    Update If we want control the whole array, we can define an array of observables and a subcriptions:

      observables:Observable<any>[]=[]
      suscription:Subscription
    

    We need make a function where we are going to subscribe to a CombineLastest

      controlChange()
      {
        if (this.suscription)
          this.suscription.unsubscribe()
    
        this.suscription=combineLatest(this.observables.map(
          (o,i)=>o.pipe(startWith(this.array.controls.length>i?this.array.value[i].one:null))
          )).subscribe(res=>{
          console.log(res)
        })
    
      }
    

    We call to this function, when remove an element

      removeGroup(index)
      {
        this.array.removeAt(index);
        this.observables.splice(index,1)
        this.controlChange()
      }
    

    And in function group Array add a new element to this.observables

      groupArray(data:any=null)
      {
        data=data || {one:null,two:null}
        const group=new FormGroup({
          one:new FormControl(data.one),
          two:new FormControl(data.two)
        })
        this.observables[this.array.controls.length]=group.get('one').valueChanges
        this.controlChange()
        return group
      }
    

    NOTE: I this last part of code I use a getter

      get array() {
        return this.form.get("array") as FormArray;
      }
    

    The stackblitz