import { Injectable } from '@angular/core';
import { SessionProvider } from '../sessionprovider';
import { SqliteProvider } from '../sqlite/sqlite'
import {Storage} from '@ionic/storage'
/*
Generated class for the ConnectioncheckproviderProvider provider.
See https://angular.io/guide/dependency-injection for more info on providers
and Angular DI.
*/
@Injectable()
export class ConnectioncheckproviderProvider {
state:any;
// static get parameters() {
// return [[HttpClient], [Storage]];
// }
constructor(private storage: Storage, public http: HttpClient,public session:SessionProvider,public sqlite:SqliteProvider) {
window.addEventListener('online', this.changestate);
window.addEventListener('offline', this.changestate);
storage.get('age').then((val) => {
console.log('from asyncTest --> Your age is', val);
});
setInterval(this.test,5000)
}
changestate(){
this.storage.get('age').then((val) => {
console.log('from asyncTest --> Your age is', val);
});
this.state=navigator.onLine ? 'online' : 'offline'
}```
Please help: Why do I get undefined error - like in the title - when changestate is called, but in the constructor it works fine (get null for the value because there is nothing in storage)?
Hi @DianLabuschagne,
You probably need to wait for the native plugin to be ready before you can use it in the constructor. You can simply wrap every this.storage
call in the platform.ready()
promise, so it doesn’t get called before the plugin has initialized (that’s why you get is undefined
).
import { Injectable } from '@angular/core';
import { SessionProvider } from '../sessionprovider';
import { SqliteProvider } from '../sqlite/sqlite'
import {Storage} from '@ionic/storage'
import { Platform } from 'ionic-angular'; // Import Platform here
@Injectable()
export class ConnectioncheckproviderProvider {
state:any;
// static get parameters() {
// return [[HttpClient], [Storage]];
// }
// Inject Platform in the constructor
constructor(private storage: Storage, public http: HttpClient,public session:SessionProvider,public sqlite:SqliteProvider, private platform: Platform) {
window.addEventListener('online', this.changestate);
window.addEventListener('offline', this.changestate);
// Wait for platform.ready()
platform.ready().then(() => storage.get('age')).then((val) => {
console.log('from asyncTest --> Your age is', val);
});
setInterval(this.test,5000)
}
changestate(){
// Wait for platform.ready()
this.platform.ready().then(() => this.storage.get('age')).then((val) => {
console.log('from asyncTest --> Your age is', val);
});
this.state=navigator.onLine ? 'online' : 'offline'
}
}
Best,
Rodrigo
Hi Rodrigo
Thank you! but I the weird thing is that it works when called in the constructor, nut not from the changestate() function . But I tried what you suggested this time it is not recognising the platform in the change state function:
error I get:
TypeError: Cannot read property 'ready' of undefined
import { Injectable } from '@angular/core';
import { SessionProvider } from '../sessionprovider';
import { SqliteProvider } from '../sqlite/sqlite'
import {Storage} from '@ionic/storage'
import { Platform } from 'ionic-angular'; // Import Platform here
/*
Generated class for the ConnectioncheckproviderProvider provider.
See https://angular.io/guide/dependency-injection for more info on providers
and Angular DI.
*/
@Injectable()
export class ConnectioncheckproviderProvider {
state:any;
constructor(private platform:Platform,private storage: Storage, public http: HttpClient,public session:SessionProvider,public sqlite:SqliteProvider) {
window.addEventListener('online', this.changestate);
window.addEventListener('offline', this.changestate);
// this.handleStateChange().then(()=>{
this.platform.ready().then(() => this.storage.get('age')).then((val) => {
console.log('from asyncTest --> Your age is', val); // this succeeds
});
setInterval(this.test,5000)
}
changestate(){
this.platform.ready().then(() => this.storage.get('age')).then((val) => {
console.log('from changestate --> Your age is', val); //This fails when I make the online/offline event trigger
});
this.state=navigator.onLine ? 'online' : 'offline'
}```
FOUND THE ANSWER I WAS LOOKING FOR HERE:
it was a scope issue. I did the following:
added .bind(this) to the event listeners in the constructor ->
window.addEventListener(‘online’, this.changestate.bind(this));
window.addEventListener(‘offline’, this.changestate.bind(this));
Yes, I was actually writing the same thing, I’m glad you found the problem. You can also do:
window.addEventListener('online', () => this.changestate());
As arrow functions also share the this
context with the inner function.