Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a service without injection in angular2

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

like image 701
Geoff Avatar asked May 07 '26 14:05

Geoff


2 Answers

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.

like image 151
smnbbrv Avatar answered May 09 '26 04:05

smnbbrv


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)=>{

}); 
like image 38
Shivang Gupta Avatar answered May 09 '26 02:05

Shivang Gupta



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!