3

Am new to angular2 and i have a class which has static functions in angular2 and i would like to implement a http request on one of the static functions that is

I have static classes that manage form validation

FORM VALIDTION
this.userform = this._formbuilder.group({
  first_name: [this.user.first_name, Validators.required],
  last_name: ['', Validators.required],
  username: ['', Validators.compose(
    [
      Validators.required,Validators.minLength(5)
    ]
  )],
  password: ['',Validators.compose([
    Validators.required,ValidationService.passwordValidator
  ])],
  email: ['', Validators.compose([
    Validators.required,ValidationService.emailValidator
  ])],
  role: ['', Validators.required],

})

on the ValidationService

constructor(private _http:Http){}

 static passwordValidator(control) {
  if(control.value != undefined){
  if (!control.value.match(/^(?=.*[0-9])[a-zA-Z0-9!@#$%^&*]{6,100}$/)) {
    return { 'invalidPassword': true };
  }
 }

 }

static emailValidator(){

return this._http. //this returns an error i would like to 
      //query server to see if email exists

 }

In my case above how can i use the http in the static function probably by assigning it to a variable

That is let http...

This is being used Here but it was in RC5 whic fails to me

2 Answers 2

5

Short answer:

you should not do things like that. Inject your class as a service and don't use static methods.

Long answer:

First of all, I don't believe this was ever working in RC5.

Second, if you don't add your class to the injector (you don't pass it as a constructor attribute to another service / component) you should not call it service in angular, although it might be service in your understanding.

Third, static methods on angular services make nearly no sense. Yes, there are cases when it might help (service in angular2 might have more than one instance), however I believe this is not your case.

If you want to use angular services (and Http is an angular service) you must inject them as I told above as a constructor attribute to another service / component, which means if you want to use Http you need to have your service injectable.

So the answer is no, you can't do it in a nice way.

However, there are workarounds.

First of all, it is simple to pass a Http instance to your static function:

static emailValidator(http: Http) {

and in your component:

ValidationService.emailValidator(this.http)

where this.http is Http injected into the component.

Another way. Services are easy to create on your own. If the service has no injection request in a constructor (does not inject anything) you could simply do

let myhttp = new Http();

However, the original Http requires two things to be injected, see https://angular.io/docs/ts/latest/api/http/index/Http-class.html:

constructor(_backend: ConnectionBackend, _defaultOptions: RequestOptions)

So you would also need to pass as an argument two other entities / services, which you might also need to instantiate... In the end you are writing your own injector.

The third way is to take a standard Angular injector and try to play around it.

This all might work but as a developer I would cry if I would need to support things like that.

Sign up to request clarification or add additional context in comments.

4 Comments

but as a developer I would cry if I would need to support things like that +1
nice answer smnbbrv, ive decided to change the validator to be a service but its good to explore if there are other options which might come in handy later
I also hope it helps somebody because sometimes it is useful to know these things. A week ago I had a similar problem: passing a service instance to a simple class and passing it directly to the class constructor (first workaround) helped to achieve that. The second workaround is actually very much used for unit testing the services, so this is also helpful.
Could you please check on this ive implemented but getting an error stackoverflow.com/questions/41910470/…
1

There is a way by creating singleton static instance. Use the below code inside your ValidationService. In constructor we are assigning static instance variable to current instance.

Now we can access instance inside static methods and use Http service dynamically.

static _instance: ValidationService;
constructor(private _http: Http) {
    if (!ValidationService._instance) {
        ValidationService._instance = this;
    }

    return ValidationService._instance;
}

Inside your emailValidator use below code:

 static emailValidator():Observable<any> {
    return this._instance._http.get("").map((data) => {

    });

}

Inside your component where you want to use ValidationService, inject ValidationService dependency and use below code whereever emailValidator is required.

ValidationService.emailValidator().subscribe((data)=>{

}); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.