1

I'm using DevExtreme components, and this is where the callback function gets called in the html:

<dxi-validation-rule type="custom"
     [validationCallback]="validationCallback"
     message="Email exists">
</dxi-validation-rule>

In the ts file:

validationCallback (e)  {
  const x = this.userService.getUserByEmail(e.value);
  x.subscribe(ref => ref.email != null ? true : false);
  return x;
}

Service code:

getUserByEmail(email: string): Observable<User> {
  return this.afs
    .collection<User>('users', ref => ref.where('email', '==', email))
    .snapshotChanges()
    .map(
      users => {
        const user = users[0];
        if (user) {
          const data = user.payload.doc.data() as User;
          const id = user.payload.doc.id;
          console.log('found: ' + data.email);
          return { id, ...data };
        } else {
          return null;
        }
      }
    );
}

Problem with that code is that I get:

Cannot read property 'getUserByEmail' of undefined

Basically means I'm trying to access this.userService which is out of the function's scope. How would I be able to access an external function to validate e-mail in this situation?

Dilan Tharaka
  • 517
  • 5
  • 15
Rosenberg
  • 2,424
  • 5
  • 33
  • 56

1 Answers1

1

may be a one way to do it by create a method that return an arrow function then set getUserByEmail to that arrow function this way you will obtain a reference to this object

public getUserByEmail;

ngOnInit() {
 this.getUserByEmail = getUserByEmailFactory();
}

getUserByEmailFactory() {

  return  (email: string) => {
    return this.afs
      .collection<User>('users', ref => ref.where('email', '==', email))
      .snapshotChanges()
      .map(
        users => {
          const user = users[0];
          if (user) {
            const data = user.payload.doc.data() as User;
            const id = user.payload.doc.id;
            console.log('found: ' + data.email);
            return { id, ...data };
          } else {
            return null;
          }
        }
      );
  }

}

you can an afs to getUserByEmailFactory then the return function will have a closure then you will no longer need to use this

public getUserByEmailFactory(afs){
 ...
}

ngOnInit() {
  this.getUserByEmail = getUserByEmailFactory(this.afs);
}

or can be like this

public getUserByEmail = () => { ... }

arrow function

Muhammed Albarmavi
  • 23,240
  • 8
  • 66
  • 91