How to Inject a service into an async validator?

Viewed 772

I have two very similar async validators. Both check values for uniqueness: Email and initials. The first one looks like this:

public static createEmailUniqueValidator(userService: UserService, originalEmailAddressFn: () => string) {
    return (control: AbstractControl): Observable<ValidationErrors> => {
        const originalEmailAddress: string = originalEmailAddressFn();
        if (originalEmailAddress && originalEmailAddress === control.value) {
            return Observable.of({});
        }
        return Observable.timer(1000).switchMap(() => {
            return userService
                .isEmailAddressUnique(control.value)
                .map(result => (result ? null : { 'This email address is already in use': true }));
        });
    }
}

The second one almost identical, except for the method it calls on the userService. How can I make one generic validator factory and pass it the method it should call to do the actual checking ?

So far, I have this:

public static createValidator(uniqueFn: (value: string) => Observable<Boolean>, originalEmailAddressFn: () => string, errorMessage: string) {
        return (control: AbstractControl): Observable<ValidationErrors> => {
            const originalEmailAddress: string = originalEmailAddressFn();
            if (originalEmailAddress && originalEmailAddress === control.value) {
                return Observable.of({});
            }
            return Observable.timer(1000).switchMap(() => {
                return uniqueFn(control.value)
                    .map(result => (result ? null : { errorMessage: true }));
            });
        }
    }

But I am getting the following error:

ERROR TypeError: Cannot read property 'restService' of undefined at webpackJsonp.../../../../../src/app/services/user/user.service.ts.UserService.isEmailAddressUnique (user.service.ts:108)

restService is another service that is injected in the userService. It looks like the dependencies have not been resolved. How can I fix this ?

This is my userService:

// imports ...

@Injectable()
export class UserService {

  // [...]

  constructor(private restService: RestService) { }

  isEmailAddressUnique(emailAddress: string): Observable<Boolean> {
    return this.restService.get(this.usersUrl + '/validateUniqueEmailAddress/' + emailAddress);
  }
}
1 Answers
Related