Getting variable from provider makes blank page


#1

Hello everyone,

I am trying to make a simple app to check bluetooth and device… I started making a tabs main app then a injectable provider where I could manage bluetooth connection and devices through all tabs.

Starting to check if my own provider works I played just showing a simple variable on a ion-input field used as a label but when I compile and run the app on my mobile phone it shows total blank page if I assign provider’s variable to the ion-input when it shouldn’t. Here my simple code:

devicefactory.ts

import { Injectable } from "@angular/core";
//import { BluetoothLE } from '@ionic-native/bluetooth-le';

@Injectable()
export class DevicesService {
	public ble_status : boolean;
	public check_string : any;

	// public BLE : BluetoothLE
	constructor(){
		this.ble_status = false; 
		//this.BLE.initialize();
		//this.BLE.isEnabled().then(result => { this.ble_status = result.isEnabled; });
		this.check_string = "Provider enabled";
	}

	getStatus() { return this.ble_status; }
	getStatusString() { return this.check_string; }

	enableBLE() {
		//if (this.ble_status) this.BLE.enable();  else  this.BLE.disable();
		if (this.ble_status) this.check_string = "Provider enabled";  else  this.check_string = "Provider disabled";
	}
}

so I initialized my own provider in app.module.ts:

import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { HoergerateApp } 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 { SettingsPage } from '../pages/settings/settings';
import { DevicesService } from '../providers/devicefactory/devicefactory';


@NgModule({
  declarations: [
	HoergerateApp,
	AboutPage,
	SettingsPage,
	ContactPage,
	HomePage,
	TabsPage
  ],
  imports: [
	BrowserModule,
	IonicModule.forRoot(HoergerateApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
	HoergerateApp,
	AboutPage,
	SettingsPage,
	ContactPage,
	HomePage,
	TabsPage
  ],
  providers: [
	StatusBar,
	SplashScreen,
	DevicesService,   // my own provider
	{provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {
  
}

then in my home.html I have settled that ion-input:

<ion-header>
  <ion-navbar>
	<ion-title>Home</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <h2>Welcome to Ionic!</h2>
  <p>
	This starter project comes with simple tabs-based layout for apps
	that are going to primarily use a Tabbed UI.
  </p>
  <p>
	Take a look at the <code>src/pages/</code> directory to add or change tabs,
	update any existing page or create new pages.
  </p>
   <p>
	Check bluetooth status:<br>
	<strong><ion-input round id="ble_state" type="text" [(ngModel)]="ble_state"></ion-input></strong>
  </p>
</ion-content>

and in home.ts I assign that provider’s variable to the ion-input:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { DevicesService } from '../../providers/devicefactory/devicefactory';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  public ble_state : string;

  constructor(public navCtrl: NavController, public deviceProvider : DevicesService) {
	//this.ble_state = ( this.deviceService.ble_status ?  "Bluetooth is enabled" : "BLuetooth is disabled" );

	this.ble_state = deviceProvider.getStatusString();
	//this.ble_state = deviceProvider.check_string;
  }
  
}

If I comment that line of code about assignment variable, the app works and shows the content of home.html like it’s something related to that assignment way.
I tried also to assign directly to [(ngModel)] as like as:

[(ngModel)]="deviceProvider.check_string"

and during compilation no errors displayed so I am here asking you if I missed something or it’s maybe related to some dependencies that works with assignments?

Supposing it’s related about dependencies since it’s just a simple example I am making, here the content of my package.json:

{
  "name": "sampleproject",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "scripts": {
	"start": "ionic-app-scripts serve",
	"clean": "ionic-app-scripts clean",
	"build": "ionic-app-scripts build",
	"lint": "ionic-app-scripts lint"
  },
  "dependencies": {
	"@angular/animations": "5.2.11",
	"@angular/common": "5.2.11",
	"@angular/compiler": "5.2.11",
	"@angular/compiler-cli": "5.2.11",
	"@angular/core": "5.2.11",
	"@angular/forms": "5.2.11",
	"@angular/http": "5.2.11",
	"@angular/platform-browser": "5.2.11",
	"@angular/platform-browser-dynamic": "5.2.11",
	"@ionic-native/bluetooth-le": "^4.16.0",
	"@ionic-native/core": "~4.15.0",
	"@ionic-native/splash-screen": "~4.15.0",
	"@ionic-native/status-bar": "~4.15.0",
	"@ionic/storage": "2.2.0",
	"cordova-android": "7.1.1",
	"cordova-ios": "4.5.5",
	"cordova-plugin-bluetoothle": "4.4.4",
	"cordova-plugin-device": "^2.0.2",
	"cordova-plugin-ionic-keyboard": "^2.1.3",
	"cordova-plugin-ionic-webview": "^2.2.0",
	"cordova-plugin-splashscreen": "^5.0.2",
	"cordova-plugin-statusbar": "^2.4.2",
	"cordova-plugin-whitelist": "^1.3.3",
	"ionic-angular": "3.9.2",
	"ionic-plugin-bluetoothle": "^1.0.0",
	"ionicons": "3.0.0",
	"list": "2.0.16",
	"rxjs": "5.5.11",
	"sw-toolbox": "3.6.0",
	"zone.js": "0.8.26"
  },
  "devDependencies": {
	"@ionic/app-scripts": "3.2.0",
	"typescript": "~2.6.2"
  },
  "description": "An Ionic project",
  "cordova": {
	"plugins": {
	  "cordova-plugin-bluetoothle": {},
	  "cordova-plugin-whitelist": {},
	  "cordova-plugin-statusbar": {},
	  "cordova-plugin-device": {},
	  "cordova-plugin-splashscreen": {},
	  "cordova-plugin-ionic-webview": {
		"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
	  },
	  "cordova-plugin-ionic-keyboard": {}
	},
	"platforms": [
	  "android",
	  "ios"
	]
  }
}

Thanks to all!
Cheers!
Luigi


#2

Hello all again!

I am really stuck with it… I tried to uninstall and delete everything, then reinstalling node + npm + ionic + cordova from scratch obtaining this installation:

Ionic:

   ionic (Ionic CLI)  : 4.5.0
   Ionic Framework    : ionic-angular 3.9.2
   @ionic/app-scripts : 3.2.1

Cordova:

   cordova (Cordova CLI) : 8.1.2 (cordova-lib@8.1.1)
   Cordova Platforms     : android 7.1.4, ios 4.5.5
   Cordova Plugins       : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 2.2.5, (and 4 other plugins)

System:

   Android SDK Tools : 26.1.1 (C:\Users\npule\AppData\Local\Android\Sdk)
   NodeJS            : v10.14.1 (C:\Program Files\nodejs\node.exe)
   npm               : 6.4.1
   OS                : Windows 10

So I tried to make a new sample with the objective to create a provider who would pass me a simple string to a ion-input in the home:

the provider:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

/*
  Generated class for the DevicefactoryProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class DevicefactoryProvider {
  ble_state : "Bluetooth disabled!";

  constructor(public http: HttpClient) {
	this.ble_state = "Bluetooth disabled!";
	//console.log('Hello DevicefactoryProvider Provider');
  }

  setState(ble_state) { this.ble_state = ble_state }

  getState() { return this.ble_state; }

}

my app.module.ts

import { SplashScreen } from '@ionic-native/splash-screen';
import { DevicefactoryProvider } from '../providers/devicefactory/devicefactory';
import { SettingsPage } from "../pages/settings/settings";

@NgModule({
  declarations: [
	MyApp,
	AboutPage,
	SettingsPage,
	ContactPage,
	HomePage,
	TabsPage
  ],
  imports: [
	BrowserModule,
	IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
	MyApp,
	AboutPage,
	SettingsPage,
	ContactPage,
	HomePage,
	TabsPage
  ],
  providers: [
	StatusBar,
	SplashScreen,
	DevicefactoryProvider,
	{provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {}

the home.html

<ion-header>
  <ion-navbar>
	<ion-title>Home</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <h2>Welcome to Ionic!</h2>
  <p>
	This starter project comes with simple tabs-based layout for apps
	that are going to primarily use a Tabbed UI.
  </p>
  <p>
	Take a look at the <code>src/pages/</code> directory to add or change tabs,
	update any existing page or create new pages.
  </p>
  <p>
	Check bluetooth status:<br>
	<strong><ion-input round id="ble_state" type="text" [(ngModel)]="ble_state"></ion-input></strong>
  </p>
</ion-content>

and the home.ts

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { DevicefactoryProvider } from "../../providers/devicefactory/devicefactory";

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  ble_state: string;

  // , public devicefactory : DevicefactoryProvider
  constructor(public navCtrl: NavController, private df : DevicefactoryProvider) {
	this.ble_state = this.df.getState();
	//this.ble_state = "Bluetooth disabled!";
  }

}

and the package.json to check if I could have mistaken/forgot something during installations:

{
  "name": "hoergerateapp",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "scripts": {
	"start": "ionic-app-scripts serve",
	"clean": "ionic-app-scripts clean",
	"build": "ionic-app-scripts build",
	"lint": "ionic-app-scripts lint"
  },
  "dependencies": {
	"@angular/animations": "5.2.11",
	"@angular/common": "5.2.11",
	"@angular/compiler": "5.2.11",
	"@angular/compiler-cli": "5.2.11",
	"@angular/core": "5.2.11",
	"@angular/forms": "5.2.11",
	"@angular/http": "5.2.11",
	"@angular/platform-browser": "5.2.11",
	"@angular/platform-browser-dynamic": "5.2.11",
	"@ionic-native/core": "~4.17.0",
	"@ionic-native/splash-screen": "~4.17.0",
	"@ionic-native/status-bar": "~4.17.0",
	"@ionic/storage": "2.2.0",
	"cordova-android": "7.1.4",
	"cordova-ios": "4.5.5",
	"cordova-plugin-device": "^2.0.2",
	"cordova-plugin-ionic-keyboard": "^2.1.3",
	"cordova-plugin-ionic-webview": "^2.2.5",
	"cordova-plugin-splashscreen": "^5.0.2",
	"cordova-plugin-statusbar": "^2.4.2",
	"cordova-plugin-whitelist": "^1.3.3",
	"ionic": "4.5.0",
	"ionic-angular": "3.9.2",
	"ionicons": "3.0.0",
	"rxjs": "5.5.11",
	"sw-toolbox": "3.6.0",
	"zone.js": "0.8.26"
  },
  "devDependencies": {
	"@ionic/app-scripts": "3.2.1",
	"typescript": "~2.6.2"
  },
  "description": "An Ionic project",
  "cordova": {
	"plugins": {
	  "cordova-plugin-whitelist": {},
	  "cordova-plugin-statusbar": {},
	  "cordova-plugin-device": {},
	  "cordova-plugin-splashscreen": {},
	  "cordova-plugin-ionic-webview": {
		"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
	  },
	  "cordova-plugin-ionic-keyboard": {}
	},
	"platforms": [
	  "android",
	  "ios"
	]
  }
}

As you can see, it’s really simple and tried to follow around posts where it was explaining about providers but when I do “ionic cordova run android” it compiles all ok but when it launchs the app on the mobile I see always a blank page.
Why? Shall I have missed something?.. It’s been 15 days I am fighting with it… any suggest?

Thanks all!
Cheers
Luigi


#3

I would suggest either adding HttpClientModule to the imports section of your app module or taking the http parameter out of DevicefactoryProvider's constructor.


#4

Thanks rapropos for your answer!..
OK, I’ll try to add it this evening when I’ll back home from work… Is it this “HttpClient” maybe mandatory when working with providers? And what is it used for with variables or even simple stuffs in providers?
I am asking because, to tell the truth, when adding new provider I did "ionic generate provider " and it did all automatically so that import was already there…and plus during compilation ti didn’t noticed any warnings/errors for that HttpClient so I couldn’t put any suspects to it…


#5

No.

Nothing, but I would wager that if you connect Chrome’s Developer Tools to your running app and look in the console, you will see something along the lines of “error: can’t resolve all parameters for DevicefactoryProvider(?)”, because Angular’s DI doesn’t know how to instantiate an HttpClient. Therefore, your provider never gets born.


#6

Ah so you mean if I don’t really need to have HttpClient as Import in my provider I just could remove it from my provider , right?


#7

Yes, you could just remove it from the provider’s constructor.


#8

OK, this evening I’ll try both ways and I’ll let you know! :slight_smile: Thanks for now, rapropos


#9

Hello rapropos!

It worked removing that HttpClient stuff! Now I am fighting adding bluetooth in provider so I can use it in every tab’s page without losing connection :slight_smile:
Thanks again, rapropos! :slight_smile: