App module not work with providers


#1

I’m using Ionic 2 and my app not work with global providers.

My provider declaration:

@NgModule({
   ...
   providers: [
       MyService
   ]
})

My provider content:

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

And in my component:

@Component({
    ...
})
export class MyComponent {
    constructor(serviceVariable: MyService) {
        serviceVariable.someMethod();
    }
}

My ionic info: Cordova CLI: 6.5.0 Ionic Framework Version: 2.3.0 Ionic CLI Version: 2.2.1

Ionic App Lib Version: 2.2.0
Ionic App Scripts Version: 1.1.4
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Linux 4.9
Node Version: v6.2.0
Xcode version: Not installed
When i try to use in my application i dont see the provider MyService.

Anyone know why?


#2

What do you mean by you don’t see the provider MyService?


#3

When i call (serviceVariable: MyService) in component constructor, the ionic don`t recognize the MyService provider.


#4

I think the problem lies outside of what you’ve posted so far. An entire complete reproducible codebase would be helpful.


#5

My Code:

import { NgModule, ErrorHan    dler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { AboutPage } from '../pages/about/about';
import { ContactPage } from '../pages/contact/contact';
import { HomePage } from '../pages/home/home';
import { TabsPage } from '../pages/tabs/tabs';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import {MyService} from '../providers/my-service';
@NgModule({
  declarations: [
    MyApp,
    AboutPage,
    ContactPage,
    HomePage,
    TabsPage
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    AboutPage,
    ContactPage,
    HomePage,
    TabsPage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    MyService,
    {provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {}

And in my compoenent:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
@Component({
  selector: 'page-contact',
  templateUrl: 'contact.html'
})
export class ContactPage {
	constructor(public navCtrl: NavController, private myService: MyService) {
		this.myService.getAll()
			.then(data => {
				console.log(data);
			})
		}
	}	
}

My provide:

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

/*
  Generated class for the MyData provider.

  See https://angular.io/docs/ts/latest/guide/dependency-injection.html
  for more info on providers and Angular 2 DI.
*/
@Injectable()
export class MyService {

  constructor(public http: Http) {
    console.log('Hello MyService Provider');
  }

  getAllt(){
  	return "teste meu";
  }
}

#6

Typo error?

getAllt(){
  	return "teste meu";
  }

#7

No, is a typo error on post. Isn`t this.


#8

This should work:
ionViewDidLoad() {
let dd = this.myService.getAll();
console.log(dd)
}

(method getAll() returns string )


#9

Hi pe1,

My problem is here, in bold:

export class ContactPage {
constructor(public navCtrl: NavController, private myService: MyService)

My application not recognize MyService Provider, even me declaring and set in providers in app.module.ts.


#10

hmm the issue is not in the code you paste here. I’ve tested and it works fine. When you inject myService to the ContactPage you should see the message ‘Hello MyService Provider’ on dev console


#11

I don’t see an import for MyService in ContactPage.


#12

The question is:

  • If i use the provider in other page.ts, have i to import the provider in this page?

It works, but …

I wanted to import and use it globally on all pages without having to import for each one page.

And i think to do this is declare in app.component providers array. Is this, or not?


#13

already gave you the answer as far as I can tell. You should still import MyService in your page to let it know it’s being used. Only putting it inside your constructor isn’t going to work. Whether you put it inside your declarations or not. I don’t see why you shouldn’t import it besides convenience. There aren’t any downsides to it. You actually already have it globally imported (inside app.module.ts). This spares you the effort to put it in the providers of your component every time.


#14

No, in app.module’s.


#15

Read up on Angular Dependency Injection. Oversimplification: you need to import on every page, but if you declare the provide in app.modue.ts, it will be the same provider everywhere, not multiple independent copies.

There are reasons DI is a good thing for browser programming, but it does require a shift in perspective. You might be used to a programming style where different pieces of the program know a lot about the program. Part of the goal here is to ensure that each page needs to know as little as possible to do its job.


#16

Yes, in app.module. Sorry!


#17

It’s just for it. Because I use one provider in all pages in my app. So, I do not want to import in all pages one to one Explicitly.


#18

Yes, but i declare only in app.modules.ts but my page.ts do not recognize the provider method. Only if i import in this page too. Then the app “visualize” the methods this provider.


#19

TypeScript consists of a bunch of really clever people bolting features onto a language that was thrown together in a week and a half to give Netscape’s marketing department a club with which to try to bash Sun over the head with.

As such, all of the OOP constructs are really just smoke and handwaving using what primitives exist.

When you write:

constructor(private fooService: FooService) {
}

…a lot of stuff happens behind the scenes. Angular’s DI mechanism analyzes what you wrote and knows that it has to provide you a parameter of type FooService. On its face, FooService is just an identifier. Only when you provide a declaration for it (via “import”) does it have a clue what that type is. In fact, under the hood, what it is is a constructor function that instantiates an object with the properties and prototype voodoo that constitutes JavaScript “classes”.

The FooService constructor you are requesting here must match the FooService constructor provided by the code that defines the class, because it is used as a key in a lookup dictionary inside the DI system. This can be the source of many wondrous and mysterious bugs when you unintentially end up with multiple versions of the same class inside your app and DI gives different objects to different consumers. To make matters more exciting, the ensuing error messages are very cryptic and give absolutely no clue as to what is happening (see here).


#20

Hey, off topic but I’m curious about your code example. I’ve made my DI parameters public, private, and with no explicit scope, to see which is better, and I haven’t found a significant difference between public and private. Do you think I should care about this?