Stephan K.
Stephan K.

Reputation: 15712

TypeError: Cannot read property 'next' of null in Angular2 Observable

Error

TypeError: Cannot read property 'next' of null

Template calling the Observer.next (the problem)

import { NavService } from '../../providers/services/nav-service/nav-service';

@Component({
  selector: 'ion-header',
  providers: [NavService],
  template: `
    <ion-navbar>
        <ion-title>{{navService.getCurrentName()}}</ion-title>
        <ion-buttons start>
            <button (click)="navService.goHome()">
                <span primary showWhen="ios">Cancel</span>
                <ion-icon name="md-close" showWhen="android,windows"></ion-icon>
            </button>
        </ion-buttons>
    </ion-navbar>
  `
})

Service with Observable

import { Platform } from 'ionic-angular';
import { Observable } from 'rxjs/Observable';
import { Injectable, ViewChild } from '@angular/core'

@Injectable()

export class NavService {
private dismissObserver: any
public  dismiss: any

constructor (
    private authService:    AuthService,
    private platform:       Platform
) {
    this.dismissObserver = null;
    this.dismiss = Observable.create(observer => {
        this.dismissObserver = observer;
    });
}

public goHome():void {
    this.dismissObserver.next(true);
}

app.ts with subscription

@Component({
    providers: [NavService]
})

export class MyApp {

  @ViewChild(Nav) navController: Nav
  constructor(
    public navService: NavService

) {
    this.initializeApp()
  }

 initializeApp() {

    this.platform.ready().then(() => {

        StatusBar.styleDefault()
        this.setRoot()
        this.navController.setRoot(HomePage);

        this.navService.dismiss.subscribe((event) => {
            console.log ("event", event);
            this.navController.setRoot(HomePage)
        })
    })
}

ionicBootstrap(MyApp, [])

Btw, I am using this "tutorial":

Ionic2, inject NavController to Injectable Service

Upvotes: 4

Views: 7606

Answers (1)

Can Nguyen
Can Nguyen

Reputation: 1470

The code in Observable.create where you assign dismissObserver is called when dismiss is subscribed. So if you call goHome before that subscription, dismissObserver is null by that time and you get the error

Anyway, what you're implementing with dismiss and dismissObserver is the concept of a Subject. Just replace your NavService constructor and goHome by:

constructor (
  private authService:    AuthService,
  private platform:       Platform
) {
  this.dismiss = new Subject();
}

public goHome():void {
  this.dismiss.next(true);
}

and you're fine: You may miss value(s) if your subscription comes after it, but no error is thrown. Try replacing Subject by BehaviorSubject to cache one value for subscriptions that come after the emission.

EDIT: I forgot to mention you need to import { Subject } from 'rxjs/Subject';

Upvotes: 7

Related Questions