Reputation: 27
I'm trying to switch from template driven to reactive form. I'm stack with adding async validator while it worked in template driven form with set property in input element, now when trying to set from code gives me constantly a strange error "TypeError: undefined is not an object (evaluating 'this.http')":
@Component({
selector: 'app-new-user',
templateUrl: './new-user.component.html',
styleUrls: ['./new-user.component.css']
})
export class NewUserComponent implements OnInit, OnDestroy {
isPosting: boolean = false;
storeSub: Subscription;
newUserForm: FormGroup;
constructor(
private userService: UsersService,
private http: HttpClient,
private store: Store<fromApp.AppState>
) {
}
ngOnInit() {
this.storeSub = this.store.select('users')
.subscribe(state => {
this.isPosting = state.isPostingNewUser;
}
);
this.newUserForm = new FormGroup({
'name': new FormControl(null, [
Validators.required,
Validators.maxLength(30),
Validators.minLength(3)
]),
'surname': new FormControl(null, [
Validators.required,
Validators.maxLength(50),
Validators.minLength(3)
]),
'email': new FormControl(null, [
Validators.required,
Validators.email
],
this.checkEmailAvailability
),
'phone': new FormControl(null, [
Validators.required,
Validators.maxLength(9),
Validators.pattern('[5-8][0-9]{8}')
]
)
});
}
ngOnDestroy() {
this.storeSub.unsubscribe();
}
onSubmit(): void {
const userWriteModel = new UserWriteModel(
this.newUserForm.get('name').value,
this.newUserForm.get('surname').value,
this.newUserForm.get('email').value,
this.newUserForm.get('phone').value
);
this.store.dispatch(new UserActions.AddUser(userWriteModel));
}
checkEmailAvailability(control: FormControl): Observable<{ emailForbidden: boolean } | null> {
const emailToCheck = control.value;
if(!emailToCheck) {
return of(null);
}
const queryParams = new HttpParams().set('email', emailToCheck);
console.log(emailToCheck);
return of(emailToCheck).pipe(
debounceTime(400),
switchMap(emailToCheck => {
return this.http.get<{ email: string, available: boolean }>(ENDPOINT + '/email/available', {params: queryParams})
.pipe(
map(resp => {
if (resp.email === emailToCheck && resp.available === false) {
return {emailForbidden: !resp.available};
}
return null;
}), catchError(() => of(null)));
})
);
}
}
when validating ends with:
[Error] ERROR
TypeError: undefined is not an object (evaluating 'this.http')
(anonimowa funkcja) — new-user.component.ts:106
_next — switchMap.js:30
next — Subscriber.js:49
debouncedNext — debounceTime.js:40
_complete — debounceTime.js:31
complete — Subscriber.js:61
(anonimowa funkcja) — subscribeToArray.js:5
_trySubscribe — Observable.js:42
subscribe — Observable.js:28
subscribe — Observable.js:23
subscribe — Observable.js:23
(anonimowa funkcja) — forkJoin.js:37
_trySubscribe — Observable.js:42
subscribe — Observable.js:28
subscribe — Observable.js:23
_runAsyncValidator — forms.js:3032
updateValueAndValidity — forms.js:3005
setValue — forms.js:3386
updateControl — forms.js:2407
(anonimowa funkcja) — forms.js:2392
_handleInput — forms.js:242
executeListenerWithErrorHandling — core.js:14296
wrapListenerIn_markDirtyAndPreventDefault — core.js:14331
(anonimowa funkcja) — platform-browser.js:582
onInvokeTask — core.js:27137
runTask — zone-evergreen.js:167
invokeTask — zone-evergreen.js:480
invokeTask — zone-evergreen.js:1621
globalZoneAwareCallback — zone-evergreen.js:1647
dispatchEvent
_autoFillControlWithValueAndOptions
_autoFillControlWithValue
(anonimowa funkcja)
[native code]
defaultErrorLogger (vendor.js:18351)
handleError (vendor.js:18399)
next (vendor.js:41970)
(anonimowa funkcja) (vendor.js:38808)
__tryOrUnsub (vendor.js:70827)
next (vendor.js:70766)
_next (vendor.js:70716)
next (vendor.js:70693)
next (vendor.js:70479)
emit (vendor.js:38798)
run (polyfills.js:136)
onHandleError (vendor.js:41442)
runTask (polyfills.js:183)
invokeTask (polyfills.js:493)
timer (polyfills.js:2565)```
Upvotes: 0
Views: 484
Reputation: 3310
Your validator uses your class members, but since you pass it as a reference - this
is not properly defined.
Try:
'email': new FormControl(null, [
Validators.required,
Validators.email
],
this.checkEmailAvailability.bind(this)
),
Upvotes: 1