1

I have tried this

export function uniqueUserNameValidation(commonsService: CommonsService): AsyncValidatorFn {
  return (c: AbstractControl): Promise < ValidationErrors | null > | Observable < ValidationErrors | null > => {
    return commonsService.uniqueUserName(c.value).pipe(
      map(data => {
        return data && data.status ? {
          'uniqueValidation': true
        } : null
      })
    )
  }
}

Common Services Method

uniqueUserName(name:string){
        return this.http.get<booleanData>(constDefault.API_URL+"/commons/nameAlreadyExist/"+name+"/Tank")
}

I am getting this error

core.js:1673 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'uniqueUserName' of undefined TypeError: Cannot read property 'uniqueUserName' of undefined

2
  • You can't. Just write a regular service with a method that returns an AsyncValidatorFn. Or write that function directly in the component which needs it, and inject the service in the component. Commented Nov 26, 2018 at 10:43
  • @holydragon no. It's because the commonsService variable is undefined: Cannot read property 'uniqueUserName' of undefined. Commented Nov 26, 2018 at 10:52

2 Answers 2

1

Angular's automatic dependency injection only works for angular component constructors (which are being managed by the DI system).

As a solution to the specific problem shown in the question, you can inject the service into the component which will be calling the uniqueUserNameValidation and then pass the service as an argument to uniqueUserNameValidation. I think that, in general, this would be the preferred solution to your problem because it doesn't stray from standard angular practices.

Example

export class MyComponent {
  constructor(private commonsService: CommonsService, private fb: FormBuilder) {}

  ngOnInit() {
    const form = this.fb.group({
      name: ['', uniqueUserNameValidation(this.commonsService)]
    })
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

I assume that your CommonsService is a proper Angular Service. If so, you could use Injector.

First import and declare the Injector in your module (app.module.ts etc.) and in the constructor of module init the instance:

import {Injector} from '@angular/core';

export let InjectorInstance: Injector;

...
...
...


export class AppModule {

  constructor(private injector: Injector) {
    InjectorInstance = this.injector;
  }
}

Then in your file that is exporting the function, import the variable from the module:

import {InjectorInstance} from 'path/to/app.module';

Then you can use the .get() method of Injector to get the service instance:

export function uniqueUserNameValidation(): AsyncValidatorFn {

  const commonsService = InjectorInstance.get<CommonsService>(CommonsService);

  return (c: AbstractControl): Promise < ValidationErrors | null > | Observable < ValidationErrors | null > => {
    return commonsService.uniqueUserName(c.value).pipe(
      map(data => {
        return data && data.status ? {
          'uniqueValidation': true
        } : null
     })
    )
  }
}

8 Comments

Now I am getting this error: TypeError: Cannot read property 'get' of undefined
It's my bad. I forgot to add init code in the constructor. Edited the answer.
@HarunYilmaz Hi, I added all the thins you specified and I get: "TypeError: Cannot read property 'get' of undefined". I have this in my AppModule: export class AppModule { constructor(private injector: Injector) { InjectorInstance = this.injector; } }. I have added this import in my ts file that has the export :import {InjectorInstance} from '../app.module'; And finally, I 'm using it in my export function like this: const translate = InjectorInstance.get<TranslateService>(TranslateService)
Hello @user3362334 Did you put export let InjectorInstance: Injector; in the app.module.ts file?
Yes, I put it below the imports
|

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.