Dependency Injection for static method


#1

Hey!

I think I haven’t really understood how dependency injection works in Angular2/Ionic2.

If I want to do this for instance:

export class Test{

  constructor(public alertCtrl: AlertController){
    // This alertCtrl is just available in the instance created by who ever creates an object of this class
  }

  static showAlert(){
    // How do I get an instance of the AlertController
    let alert = AlertController.create({
        title: 'Boom!',
        subTitle: 'Alarm!',
        buttons: ['OK']
    });
    alert.present();
  }
}

How can I get an new instance of the AlertController inside the static function?
As far es I have seen it the constructor of AlertController needs the App itself as a parameter. That’s exactly where DI should kick in, right?

Would be nice if someone could help me with that.

Cheers


#2

Hi @MrFloppy, did you manage to solve this? I’m having the same issue and can’t find a solution.


#3

Well I solved it by not using a static method I guess :smiley:
At least I can’t find any in my project anymore. So I must have got rid of it.

If I remember correctly my idea was to create a general error handler. So I simply created a provider to do so. Works great so far.

Perhaps post your problem in bigger detail and we can see how to do it without a static method.


#4

It should be possible to achieve this without using statics:

import {Injectable} from '@angular/core';
import {AlertController, App} from "ionic-angular/index";
import {SetDetailPage} from "../../pages/set-detail-page";

@Injectable()
export class ExampleService {

    constructor(public alertCtrl: AlertController) {
    }

    showAlert() {
        let alert = this.alertCtrl.create({
            title: 'Boom!',
            subTitle: 'Alarm!',
            buttons: ['OK']
        });
        alert.present();
    }
}

But it’s bad behaviour to call UI from providers.


#5

@imediasolutions That’s basically what I did. I think the issue last time was that I forgot to add the “@injectable”.

But speaking of best practice:
I’ve got, as mentioned, an error handler which kicks in when ever an error appeared. Lets say the API call results in an session expired. Now I want to show the error “Session expired” and go to the login screen.
First I’ve implemented all of that in the provider. Basically showing the error (similar to the example above) and then doing someting like this:
> this.app.getRootNav().setRoot(Login);

After the update from RC4 to 1.0 I’ve got the problem of the circular dependency in there. So I’ve changed it to an event which gets fired. Basically the Login page is listening to the event “logout” and does the same call as above.
Is this the best way to do so or is this still considered bad behaviour?

Thanks!


#6

I absolutely make no claim to “best behaviour” on this topic, but my preference is to have the app component listen to the logout event (I actually use a Subject) and alter its root page accordingly.


#7

Hi all, thanks for the feedback. I’ve followed Josh Morony’s formgroups and formcontrol validator’s example to do an async validator which uses a static method. I tried removing the static keyword but that simply didn’t work. What I need in the async validator is to be able to use http to check whether a username exists on a mysql table. but I can’t seem to inject the http component. the tutorial I followed is https://www.joshmorony.com/advanced-forms-validation-in-ionic-2/

Sorry if I’m using the wrong terminology anywhere. Most of this is brand new to me.

Thanks
Arthur


#8

See here for a couple of ways to be able to access object properties (like injected services) from within form validators.