Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to pass object to rxjs subscribe() callback function?

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:

    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...
      });
    }

This is what I get when querying for the 'this' object inside Chrome DevTools (this is supposed to keep its original context inside a lambda [fat arrow] function is this correct?)

enter image description here

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, as 'that' which was declared immediately before the subscribe() (let that: any = this;) was undefined inside of the callback when the disconnect event was fired.

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.

like image 371
Will de la Vega Avatar asked May 09 '16 02:05

Will de la Vega


People also ask

What are the three callback functions available during subscription of observables?

On the parameter that was given when creating the observable there are three functions available to send data to the subscribers of the observable: “next”: sends any value such as Numbers, Arrays or objects to it's subscribers. “error”: sends a Javascript error or exception. “complete”: does not send any value.

How do I subscribe to observable?

Subscribinglink An Observable instance begins publishing values only when someone subscribes to it. You subscribe by calling the subscribe() method of the instance, passing an observer object to receive the notifications.

How do I get data from subscribe?

To do this, you create what is known as a Subject (in this case a BehaviorSubject ) and you can populate that with data when your API call returns a response. Then, in order to access this data elsewhere, you can create a "get" function to return the Subject (which is itself an Observable ) whenever you need the data.

What is Observer complete () in Angular?

The observer's complete() callback specifies the action to take when the observable has completed producing and emitting data. const observer = { complete: () => console. log('You have used up all the vowels.') }; Js.


3 Answers

I'm pretty sure that simple closure should do the trick. Try this:

ngOnInit()
    {
      // Nav Controller:
     var nav = <NavController>this.app.getComponent('nav');

      // Disconnect Detection
      let disconnectSubscription = Network.onDisconnect().subscribe(() =>
      {
          console.log('Disconnect Detected');          
          nav.present(true);  
      });
    }
like image 66
Toan Nguyen Avatar answered Sep 21 '22 14:09

Toan Nguyen


I ran into this same problem. I am getting SafeSubscriber in my project as well. However, when I attempted to create a Plunker for it, I was unable to reproduce the problem. That said, the attached plunker does demonstrate that the fat arrow + this behaves as expected. So you should not have to do any that = this style workaround.

like image 43
Lucas Avatar answered Sep 21 '22 14:09

Lucas


To pass the component variable objects inside subscribe you have to play with more rxjs operators like combineLatest. Simply create a new Observable of the object you want to pass inside subscribe and make that as an argument to combineLatest. eg.

    // Note: The **of** here is the rxjs of operator to create the observable. 
    combineLatest(
         [
            of(the object you want to pass{Here you will have the this variable}), 
            your API call
         ])
        .pipe(take(1),)
        .subscribe(([yourObject, apiResponse]) => {
            console.log(yourObject + " " + apiResponse);
         });

Here is the reference I found my final answer.

like image 36
karan patel Avatar answered Sep 20 '22 14:09

karan patel