Both the use of custom validators and setValidators can get very complex very quickly. I prefer to configure the validators as they may be required and then conditionally enable or disable them.
Using exactly your code:
this.contractsFilter = this.fb.group({
selectedContractType: ['', [Validators.required]],
selectedYear: ['', [Validators.required]],
selectedPde: ['', [Validators.required]],
refNo: ['', []]
});
I would then subscribe to valueChanges for refNo:
this.contractsFilter.controls['refNo'].valueChanges.subscribe(value => {
if (value) { // There is a refNo specified
this.contractsFilter.controls['selectedContractType'].disable();
this.contractsFilter.controls['selectedYear'].disable();
this.contractsFilter.controls['selectedPde'].disable();
} else {
this.contractsFilter.controls['selectedContractType'].enable();
this.contractsFilter.controls['selectedYear'].enable();
this.contractsFilter.controls['selectedPde'].enable();
}
});
Now your validators are all specified in one consistent place, and you can still control whether the validators are executed or not.