12

I am trying to use a injected dependency within a static method and of course the injected dependency is instance-scoped and can't be used within the static method.

Here is my class:

@Injectable()
export class PasswordValidationService {

  constructor(private userAccountService:UserAccountService) {
  }

  static passwordValidator(control:AbstractControl) {
    return control
      .valueChanges
      .debounceTime(400)
      .switchMap(()=> this.userAccountService.checkCurrentPassword(control.value))
      .map(res=> {
          if (res.json() === true) {
            return null;
          }
          else {
            return {invalid: true};
          }
        }
      );
  }

}

My question is what is the best practice in order to use the UserAccountService (dependency) within a static method?

edit: I redesigned my app towards using instance methods instead of static methods as follows:

Here is the validator:

import {Injectable} from "@angular/core";
import {UserAccountService} from "../../useraccount/useraccount.service";
import {AbstractControl} from "@angular/common";
import {Observable} from "rxjs/Observable";


@Injectable()
export class PasswordValidationService {

  constructor(private userAccountService:UserAccountService) {
  }

  passwordValidator(control:AbstractControl):Observable<any> {
    let validationResult = this.userAccountService.checkCurrentPassword(control.value)
      .map(res=> {
          if (res.json() === true) {
            return null;
          }
          else {
            return {invalid: true};
          }
        }
      );

    return validationResult;
  }

}

Here is the component using the validator:

constructor(private router:Router,
              private formBuilder:FormBuilder,
              private stylingService:StylingService,
              private sessionService:SessionService,
              private passwordValidationService:PasswordValidationService) {
  }

  ngOnInit() {
    this.signinForm = this.formBuilder.group({
      credentials: this.formBuilder.group({
        username: [this.credentials.username, Validators.required],
        password: [this.credentials.password, [Validators.required, this.passwordValidationService.passwordValidator]]
      })
    });
  }

Here is the error message I get:

browser_adapter.ts:82 TypeError: Cannot read property 'userAccountService' of undefined
    at PasswordValidationService.passwordValidator (http://localhost:8080/app/shared/services/password-validation.service.js:18:36)
    at eval (http://localhost:8080/vendor/@angular/forms/src/validators.js:137:49)
    at Array.map (native)
    at _executeValidators (http://localhost:8080/vendor/@angular/forms/src/validators.js:137:23)
    at FormControl.eval [as validator] (http://localhost:8080/vendor/@angular/forms/src/validators.js:116:33)
    at FormControl.AbstractControl._runValidator (http://localhost:8080/vendor/@angular/forms/src/model.js:178:56)
    at FormControl.AbstractControl.updateValueAndValidity (http://localhost:8080/vendor/@angular/forms/src/model.js:164:29)
    at new FormControl (http://localhost:8080/vendor/@angular/forms/src/model.js:304:14)
    at FormBuilder.control (http://localhost:8080/vendor/@angular/forms/src/form_builder.js:36:16)
    at FormBuilder._createControl (http://localhost:8080/vendor/@angular/forms/src/form_builder.js:68:25)

2 Answers 2

4

Either don't make the method static or forward from an instance method

export class PasswordValidationService {

  constructor(private userAccountService:UserAccountService) {
  }

  validate(control:AbstractControl) {
    return PasswordValidationService.passwordValidator(control);
  }

  static passwordValidator(control:AbstractControl) {
    ...
  }
}
Sign up to request clarification or add additional context in comments.

12 Comments

That doesn't make much sense to me. If it needs to call a static method, there is no point in injecting it. Why does it need a static method?
Do you see what I mean? It needs to be in a validator array like so: [Validators.required, ValidationService.passwordValidator]
Mind you I could always have a function as described here: blog.thoughtram.io/angular/2016/03/14/…
Why not [injectedValidator.validate]? There is no need for a static method.
I guess you need to register the validator as [Validators.required, (control) => passwordValidationService.passwordValidator(control)]or ``[Validators.required,passwordValidationService.passwordValidator.bind(passwordValidationService)]to make this` work inside passwordValidator
|
2

I used it setting an instance as static somewhere in the app initialization, and then use it.

class AppComponent {
    constructor(private barService: BarService{
        BarService.appInstance = barService
    }
}


class FooUtil{

  doSomethingFancy(){
      //you might even check for BarService.appInstance the way you want to handle it
     BarService.appInstance.somethingEvenMoreFancy()
  }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.