Cyclical dependency and cannot resolve all parameters of


#1

Hi,

I have a component (ItemDetailsPage) that is importing a helper service

import { Helper } from './../../app/Helper';

and in the constructor I have

constructor(public viewCtrl: ViewController, public navCtrl: NavController, public navParams: NavParams, 
    public helper: Helper...)

In Helper.ts I have the following:

import { ItemDetailsPage } from './../pages/item-details/item-details';

and I use it like that:

showItemWindow() {
    let itemModal = this.modalCtrl.create(ItemDetailsPage, null, { cssClass: "modal-fullscreen" });
    itemModal.present();
}

When doing the above, I get "cannot resolve all parameters for ItemDetailsPage… I understand that it’s because of a circular dependency. I can move showItemWindow to another component and it works but the reason I put it in the helper, is because I need it from 3 different pages and I wanted one place to open this window.

Is there another cleaner solution for this or moving it to 3 different component is the right one? Thanks


#2

Helper.ts is a provider (@Injectable()) ?


#3

Yes, helper is an Injectable and is defined in app.module.ts as providers list

@Injectable()
export class Helper {...}

#4

Per design and best practice you can’t use ModalController and other Navigation/Pages/Components (AlertCtrl, NavigationCtrl, NavParams, your own pages and components, etc.) in your providers/services

Therefore, in any case, that’s your first problem


#5

Thanks, so if I have a modal that is in use by multiple pages, I should duplicate the code in each component or is there a cleaner way to do that?


#6

You’ve got different pattern to solve that. Spontaneously I would think about:

  • Having an abstract class you would extends in your pages and implementing your code there

  • Implementing for example the code in app.component.ts and using a provider with observable to trigger the action (in app.component you subscribe to the observable, in your pages/components you emit the events)

P.S.: About this last pattern you could for example have a look to the demo repo I did for a talk: https://github.com/peterpeterparker/ionic-zurich-introduction-demo

Have a look to the provider i18n-switcher.ts / I18nSwitcherProvider


#7

Thanks a lot for your pointers.

Because it’s a small section, 2 lines of code, I will duplicate it in the 4 pages, not that clean but not too dirty either considering…


#8

Another option (not that I’m necessarily a fan of this idea) is to have the service take whatever view controllers (such as a ModalController instance here) as a function parameter to any function that needs one. Each client page can inject one and pass it when calling the service function.


#9

Nice idea you got there, thanks.