Search code examples
angularservicecommunication

Angular 7 service communication between components


I'm creating wizard with steps. I have two components which has no parent-child relationship:

  1. Footer component with submit button which is redirecting to the next step.
  2. Form component which has validation on some inputs.

I created also a service for communication between those 2 components above.

What I want to achieve is to invoke method on footer submit button which will check if form from component number 2 is valid. If yes, we can go to next step, if not, I need to invoke validation errors, without going to next step, until user pass some information to inputs on form.

I'm not sure how can I achieve this. Any thoughts? Thank you.

I have tried to invoke validation on button but in the same form component. It works as expected. Now I would like to invoke this method on submit button in the footer.

This is my onSubmitStep() method in footer component:

public onSubmitStep() {
    if (this.currentStep < this.maxSteps) {
        this.currentStep += 1;
        this.switchStep();
        this.showDefaultFooter = false;
    }
}

This is what I have in my form component:

public contractPropertiesContent: ContractPropertiesInput;
public contractPropertiesForm: FormGroup;

constructor(private fb: FormBuilder, private router: Router, private contractPropertiesService: ContractPropertiesService) {}

ngOnInit() {
    this.contractPropertiesContent = this.contractPropertiesService.getContractPropertiesContent();
    this.contractPropertiesForm = this.initFormGroup();
}

private initFormGroup() {
    return this.fb.group({
        paymentConditionsInput: ['', Validators.required],
        creditDaysInput: ['', Validators.required],
        targetInput: ['', Validators.required]
    });
}

Solution

  • complementary the comment (see a simple stackblitz based in yours stackblitz

    in your form.component

      ngOnInit() {
        this.myService.customObservable
           .pipe(filter((x:any)=>x.command)
           .subscribe(res=>{
             if (res.command=="check")
             {
               this.contractPropertiesForm.updateValueAndValidity();
               this.myService.callComponentMethod({isValid:this.contractPropertiesForm.valid})
             }
        })
        this.contractPropertiesForm=this.initFormGroup()
      }
    

    In your footer.component

      ngOnInit() {
        this.myService.customObservable
          .pipe(filter(x=>x.isValid!=null))
          .subscribe(res=>{
             if (res.isValid)
             {
                if (this.currentStep < this.maxSteps) {
                  this.currentStep += 1;
             }
           }
        })
      }
    
      public onSubmitStep() {
            this.myService.callComponentMethod({command:"check"})
      }
    

    See that the button make a callComponentMethod({command:"check"}) and susbcribe to the observable. Is the observable who mannage currentStep

    The form listen for an object with "command", and send to callComponentMethod if the form is valid or not

    updated: a simple aproach if the form.component and footer.component belong to the same <router-outlet> (*) is using Input

    If out main component is like

    <app-form #form></app-form>
    <app-footer [form]="form"></app-footer>
    

    Out footer get in a Input the form.component

    @Input('form') form
    

    And we can simply

      public onSubmitStep() {
          this.form.contractPropertiesForm.updateValueAndValidity();
          if (this.form.contractPropertiesForm.valid)
              this.currentStep++;
      }
    

    See the new stackblitz

    (*)I want to say that this aproach it's not valid if we has some like

    <router-outlet></router-outlet>
    <app-footer ></app-footer>