Search code examples
angularionic3observableionic4

Ionic 4 Observables


I have been trying to implement the rxjs Observable pattern in a Ionic 4 upgrade project with no success and I would like to know how to successfully implement Observable so that the expected result would be displayed on-screen.

This is the old way of doing things and somewhere 'user:loggedIn' is used to display x results on-screen.

 events.subscribe('user:loggedIn', (userEventData) => {
   this.getUserInfo(userEventData);
   this.registerPushNotifications();
   this.registerPushNotificationHandlers();
 });

Two ways implemented and tested but no results are displayed.

Method 1:

    let userLoggedIn = new Observable((observer) => {
      // const {next, error} = observer;

      observer.next({'user:loggedIn':observer});
      observer.complete();
    });

    userLoggedIn.subscribe((userEventData) => {
      console.log(userEventData)
      this.getUserInfo(userEventData);
      this.registerPushNotifications();
      this.registerPushNotificationHandlers();
    });

Method 2:

    var observer: Observable<any> = of();
    observer.subscribe(userEventData => {
      this.getUserInfo(userEventData);
      this.registerPushNotifications();
      this.registerPushNotificationHandlers();
    });

Is there a way to have the same functionality as the old Ionic events functionality in Ionic 4 using Observable or Subject implementations?


Solution

  • Here's one approach that might work for you. In your auth service you can create a private BehaviorSubject property to store the last value of a private login property. Then you can create a public observable with the BehaviorSubject as its source. Finally you can subscribe to the service's public observable in your page/component which can get and set whatever you need when the change to the state of the login property occurs. Here's a simple example of how it could work:

    loginService.ts

    export class LoginService {
      private login: boolean = false;
      private loginSubject$ = new BehaviorSubject<boolean>(this.login);
      loginChanged$ = this.loginSubject$.asObservable();
    
      constructor() { }
    
      updateLogin(){
        this.login = !this.login;
        this.loginSubject$.next(this.login);
      }
    }
    

    home.page.ts

    export class HomePage implements OnInit, OnDestroy {
    
      timesClicked:number=0;
      loginButtonText:string;
    
      loginChangedSubscription: Subscription
    
      constructor(private loginService: LoginService) {}
    
      ngOnInit() {
        this.loginChangedSubscription = this.loginService.loginChanged$.subscribe((loginValue)=>{
          this.timesClicked += 1;
          this.loginButtonText =  (loginValue ? "Log Me Out" : "Log Me In");
        })
      }
    
      ngOnDestroy(): void {
        if (this.loginChangedSubscription) {
          this.loginChangedSubscription.unsubscribe();
        }
      }
    
      updateLogin():void{
        this.loginService.updateLogin();
      }
    }
    

    Just to show it working .... home.page.html

    <ion-content>
      <ion-item>
        <ion-label>
          {{timesClicked}}
        </ion-label>
      </ion-item>
      <ion-button color="primary" (click)="updateLogin()">{{loginButtonText}}</ion-button>
    </ion-content>
    

    Hope this helps.