Reputation: 667
I am attempting to run form validators based on the selected radio button, so if instagram is selected one validator is run and if facebook is selected a different validator is run. My component template is the following:
<div class="form-group" [ngClass]="{ 'has-error' : !requestURL.valid && submitAttempt }">
<div class="radio">
<label for="instagram">
<input type="radio"
name="socialmedia"
id="instagram"
value="instagram"
[checked]="selectedSourceType === 'instagram'"
(click)="updateSelectedSourceType('instagram')">
<i class="fa fa-instagram"></i>
</label>
<label for="facebook">
<input type="radio"
name="socialmedia"
id="facebook"
value="facebook"
[checked]="selectedSourceType === 'facebook'"
(click)="updateSelectedSourceType('facebook')">
<i class="fa fa-facebook"></i>
</label>
</div>
<label for="requestSource">Submit URL</label>
<span *ngIf="requestURL.hasError('alreadyTracked')" class="already-following">Already Following This User</span>
<input type="text"
id="requestSource"
class="form-control"
placeholder="Enter a website, Facebook Page or Instagram handle"
ngControl="requestURL">
So on click the selectedSourceType is switched and the value of this should determine which validator is run. However because of the constructor, the original value at run time is the validator that is run, even when the other radio button is selected. Does anybody have any possible solutions for this? This is the content of my class, the validators are just a string check for now and are working as expected individually:
theForm: ControlGroup;
requestURL: Control;
submitAttempt: boolean = false;
isLoading: boolean = false;
selectedSourceType:string = 'facebook';
validationUrls = {
instagram: 'post-ig-url?src=',
facebook: 'post-fb-url?src='
}
constructor(private _applicationService:AppService,
private _elRef:ElementRef,
private _router:Router,
private _http:Http,
private _builder:FormBuilder) {
super(_elRef, _applicationService, _router);
this.createRequestURLControl(CustomValidators.facebookURL);
this.theForm = _builder.group({
requestURL: this.requestURL
});
}
requestSource(form){
console.log('Selected source:', this.selectedSourceType);
this.isLoading = true;
this.submitAttempt = true;
let sub = this._http.post(this.validationUrls[this.selectedSourceType] + form.requestURL, '')
.subscribe(data => {
console.log("URL Submitted for review", data);
this.isLoading = false;
}, error => {
console.info(error.json().message);
});
this.addSubscription(sub);
}
createRequestURLControl(validator:any) {
this.requestURL = new Control('', Validators.compose([validator, Validators.required]) );
}
updateSelectedSourceType(sourceType:string) {
this.selectedSourceType = sourceType;
// update validators
if (sourceType === 'facebook') {
this.createRequestURLControl(CustomValidators.facebookURL);
} else {
this.createRequestURLControl(CustomValidators.instagramURL);
}
// clear input
}
Upvotes: 2
Views: 841
Reputation: 657248
Just make the validator a method of the component, or a closure in the current scope so it has access to values of your component.
class MyComponent {
someValidator(c:Control) {
if(this.radio...) {
...
}
}
createRequestURLControl(validator:any) {
this.requestURL = new Control('', Validators.compose([(c:Control) => this.someValidator(c), Validators.required]) );
}
}
I didn't investigate what exact validator you want to have conditional or how the condition can be evaluated but you should get the idea.
Important is to use ()=>
so this
keeps working inside the validator method.
Upvotes: 2