Type Error while presenting alert generated in external service?


#1

I have an external class AlertHelper which contains predefined Alerts for Error and Success events.
when an event occurs i call the service function which returns an alert object and i present it using the nav in the related page.

@Injectable()
export class AlertHelper {
    showLoadingFailedAlert(): Alert {

        let alert = Alert.create({
            title: '_title',
            subTitle: '_subTitle',
            buttons: [{
                text: 'Ok',
                handler: () => {
                    console.log('Ok clicked');
                }
            }]
        });
        return alert;
    }
}

i call it like

this.nav.present(this.alertHelper.showLoadingFailedAlert());

My problem is
Typescript shows the following error:

Argument of type 'Alert' is not assignable to parameter of type 'ViewController'.

Some places it shows

Argument of type 'Alert' is not assignable to parameter of type 'ViewController'.
  Types have separate declarations of a private property '_cntDir'.

It works fine if i create an Alert locally.

Also Is there any possible way for me to pass the nav to the service so that the service can present the alert?


#2

are you use AlertHelper class in Providers ? You can use forwardRef function of angular

import { forwardRef } from 'angular2/core';

providers:[forwardRef(()=> AlertHelper )]

may be this will help…


#3

If i change the return type of the function showLoadingAlert() from Alert to any , typescript error vanishes but during runtime I get this error

EXCEPTION: No provider for ViewController! (AlertCmp -> ViewController)
@kuntal it didn’t help :frowning:


#4

My AlertHelper class is an external npm module, do i have to add any other dependencies ?


#5

can you please provide some more code


#6

utils module package.json

  "name": "utils-module",
  "dependencies": {
    "angular2": "^2.0.0-beta.0",
    "angular2-jwt": "^0.1.8",
    "debug": "^2.2.0",
    "es6-promise": "^3.1.2",
    "es6-shim": "^0.33.3",
    "ionic-angular": "^2.0.0-beta.3",
    "lodash": "^4.6.1",
    "reflect-metadata": "^0.1.2",
    "rxjs": "^5.0.0-beta.0",
    "zone.js": "^0.5.15"
  }

alert-helper.ts inside the utils module

import { Injectable } from 'angular2/core';
import { Alert } from 'ionic-angular';

@Injectable()
export class AlertHelper {
    showLoadingFailedAlert(): Alert {

        let alert = Alert.create({
            title: '_title',
            subTitle: '_subTitle',
            buttons: [{
                text: 'Ok',
                handler: () => {
                    console.log('Ok clicked');
                }
            }]
        });
        return alert;
    }
}

I compile the above module to js without any error and uses npm link on my main app project

npm link utils-module

On main app project i then

import { Page, Alert, NavController } from 'ionic-angular';
import { forwardRef } from 'angular2/core';

import { AlertHelper } from 'utils-module';    // importing from external module

@Page({
    templateUrl: 'build/modules/auth/pages/login/login.html',
    providers: [forwardRef(() => AlertHelper)]  // as @kuntal suggested 
})

export class LoginPage {

    constructor(nav: NavController, public alertHelper: AlertHelper) {
        this.alertHelper = alertHelper;
        this.nav = nav;
        
        let alert = Alert.create({
            title: '_title',
            subTitle: '_subTitle',
            buttons: [{
                text: 'Ok',
                handler: () => {
                    console.log('Ok clicked');
                }
            }]
        });

        // This Works!!!!
        this.nav.present(alert);

        // This doesnt Works
        this.nav.present(this.alertHelper.showLoadingFailedAlert());
    }
}

if the return type of Alert function is ‘Alert’ as mentioned above i get the following error while compiling

Argument of type 'Alert' is not assignable to parameter of type 'ViewController'.
  Types have separate declarations of a private property '_cntDir'.

If i change the return type to ‘any’ which of course is not a good practice

showLoadingFailedAlert(): any {   // changed 'Alert' to 'any'

        let alert = Alert.create({
            title: '_title',
            subTitle: '_subTitle',
            buttons: [{
                text: 'Ok',
                handler: () => {
                    console.log('Ok clicked');
                }
            }]
        });
        return alert;
    }

Now i don’t get any error while compiling but during runtime i get

EXCEPTION: No provider for ViewController! (AlertCmp -> ViewController)


#7

I try with your code and alert working fine ,

alert-helper.ts

import { Injectable } from 'angular2/core';
import { Alert } from 'ionic-angular';

@Injectable()
export class AlertHelper {
  public  showLoadingFailedAlert(): Alert {

        let alert = Alert.create({
            title: '_Test title',
            subTitle: '_Test subTitle',
            buttons: [{
                text: 'Ok',
                handler: () => {
                    console.log('Ok clicked');
                }
            }]
        });
        return alert;
    }
}

helper-test.html

<ion-content class="grid-full">
<ion-buttons>
   <button  (click)="showAlert()">Click</button>
</ion-buttons>
</ion-content>

helper-test.ts

import {Page, NavController} from 'ionic-angular'
import {AlertHelper} from '../../helper/alert-helper'

@Page({
    templateUrl: 'build/pages/helper-test/helper-test.html',
    providers: [AlertHelper]

})

export class AppHelperTestPage {

    
    constructor(public alerthelper: AlertHelper,public nav: NavController) {
    //this.showAlert(); This also works   
        
        
    }

    showAlert()
    {
         
       this.nav.present(this.alerthelper.showLoadingFailedAlert());
    }

}

#8

It works when you are in the same project you are importing it from, i had it like this , but i thought i will move it to a different module.

It seems that the Alert class is extended from the ViewController class , when were are in the same project the dependencies are satisfied by the decorators ( my assumption :slight_smile: )

when i am in a external npm module there is no @App decorator or any ionic decorators to bootstrap the dependencies

I think i should bootstrap the dependencies manually and export the module , but i have no idea how to do it.