How to pass (this) to subscribe callback from Ionic Native Connection Plugin


#1

I am developing a Ionic2 App, using the cordova-plugin-network-information, I am subscribing to the connect and disconnect events from my app.ts and want to be able to pass a reference to my NavController and a Loading component into the subscribe() callback, so whenever the event for a disconnect fires, I can present the user with a Loading overlay on top of the UI. I see that in the callback the reference to the “this” object changes to an object called “SafeSubscriber”, which I think is the rxjs typed class for its Observer object, the problem I have here is that I have no way to get those instances available in app.ts to this code inside the callback, using the Chrome DevTools I also wasn’t able to find my way out of this context in order to access the App object itself.

Here is my code (@ app.ts):

ngOnInit()
{
  // Nav Controller:
  this.nav = <NavController>this.app.getComponent('nav');
  // Disconnect Detection
  let disconnectSubscription = Network.onDisconnect().subscribe(() =>
  {
      console.log('Disconnect Detected');
      // Push Loading into nav stack here...!
      // this.nav.present(this.loading);  <- no 'this' object...
  });
}

I have tried setting a “that” object before doing the subscription, so that the variable “this” doesn’t interfere with the callback “this” scope, it didn’t work in this scenario.I know that this is not the best place to put code that changes directly the UI, but I see no other place, since what I need here is a global event handler that works by setting this overlay whenever there is no connection detected and the user is viewing certain pages within the app.I think there should be a very easy and elegant solution to this, but I don’t seem to be able to find it. Is there a way to pass a parameter to the subscribe() function? some sort of object with the references I need?

Thanks in advance.


#2

I just ran into a very similar issue where a navigation change in a subscription callback was only occasionally loading the next page. I landed here because I was seeing the same “SafeSubscriber” objects in my chrome debugger and was also thinking scope reference clobbering. I’m now pretty sure, however, that the lack of visible ‘this’ reference in the debugger session is just a red-herring.

The actual problem at play seems to be that the new ‘current page’ information being set by the navController in a callback ends up happening after the underlying Angular2 event loop has completed its dirty/clean state checks and none of the UI stack has a reason to rerender the DOM with the new page.

Wrapping my navController operation in an NgZone run context has resulted in my page change executing flawlessly. Adding it as an example in the OP’s snippet (purely as a demonstration of concept and updated with beta.7 getComponent deprecation to create frankencode I have not actually run ):

import {ViewChild} from '@angular/core';
import {Nav} from 'ionic-angular';
import {NgZone} from '@angular/core';

@App({
  templateUrl: 'build/app.html'
})
export class MyApp {
  @ViewChild(Nav) nav: Nav;

  constructor(private ngZone:NgZone) { }

  ngOnInit() {
    // Disconnect Detection
    let disconnectSubscription = Network.onDisconnect().subscribe(() =>
    {
        console.log('Disconnect Detected');
        // Push Loading into nav stack here...!
        this.ngZone.run( () => {
          this.nav.present(this.loading);
        }
    });
  }
}

For more background on why this needs NgZone, see Thoughtram’s blog post on execution zones in Angular2 and the official NgZone docs.