Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Observable subscribe method only getting called once

I'm building a simple angular application in which I want a service to hold some state. My first attempt at this was just a boolean loggedIn. Basically, I want a navbar component to subscribe to this value so that when its false it shows a 'login' option and when its true show an 'admin' button.

My service:

@Injectable()
export class AuthService {
  private _loggedIn = new BehaviorSubject(false);
  public readonly loggedIn$ = this._loggedIn.asObservable();

  constructor(private http: Http, private router: Router) { 
    this._loggedIn = new BehaviorSubject(false);
  }

  public login(u: User): Observable<any> {
    let obs = this.http.post(ApiRoutes.login, u).map(res => res.json());

    obs.subscribe(res => {
      this._loggedIn.next(res.success);

      if (this._loggedIn.getValue())
        this.router.navigate(['/admin']);
    });

    return obs;
  }
}

In my nav component:

@Component({
  selector: 'app-nav',
  templateUrl: './nav.component.html',
  styleUrls: ['./nav.component.scss'],
  providers: [AuthService]
})
export class NavComponent implements OnInit {
  loggedIn: boolean;

  constructor(private as: AuthService) { }

  ngOnInit() {
    this.as.loggedIn$.subscribe(isLoggedIn => {
      this.loggedIn = isLoggedIn;
      console.log('from nav ' + isLoggedIn);
    }, err => {
      console.log(err);
    }, () => {
      console.log('complete');
    });
  }

}

Right now I see console output when the app starts up but not after login returns. Why does the subscribe function in the nav component only get called once (the page does navigate to /admin so I know the subscribe in the service is being called)? Does this have to do with hot/cold observables? I've tried using things like .publishLast().refCount() but to no avail.

like image 371
eatinasandwich Avatar asked Jan 04 '23 23:01

eatinasandwich


1 Answers

You added the AuthService in the providers of the NavComponent. So it has its own, specific instance of AuthService, different from the one used by your authentication component.

This service must be a singleton, shared by all the components in the application. So it should be declared in the providers of the root NgModule, and nowhere else.

like image 175
JB Nizet Avatar answered Jan 27 '23 20:01

JB Nizet