TjDev
TjDev

Reputation: 23

How do I get the value of an Observable in a service from a component and pass it to my view?

I've tried many things for this, and nothing seems to help.

What I'm trying to accomplish:

  1. User clicks button on Selection component view
  2. Event fires, calling changePage() on the selection component
  3. This calls changePage() on the service and passes in a string
  4. changePage() in the service updates an observable
  5. In the main component, a subscription is created and changes the variable pageName's value based on the Observable in the service
  6. The pageName is updated as a header on the page

Service

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs';

@Injectable()

export class PageService{
    pageChange$: Subject<String> = new BehaviorSubject("About Me");

    constructor(){
    }

    public changePage(changeTo: String){
        console.log(changeTo); // LOGS PROPERLY
        this.pageChange$.next(changeTo);
    }
}

Selection Component

export class SelectionComponent implements OnInit {

  constructor(private _pageService:PageService) { }

  ngOnInit() {
  }

  // Called on button click, passed a string from the button
  changePage(changeTo: string){
      this._pageService.changePage(changeTo);
  }
}

Main Component

import { Component, OnInit } from '@angular/core';
import { PageService } from '../page-service.service';
import { AsyncPipe } from '@angular/common';

@Component({
  selector: 'app-main-content',
  templateUrl: './main-content.component.html',
  styleUrls: ['./main-content.component.css'],
  providers: [PageService]
})
export class MainContentComponent implements OnInit {    
  pageName: String;

  constructor(private _pageService: PageService) {  
  }

  ngOnInit() {
      this._pageService.pageChange$.subscribe(value => {
          console.log(value); // DOES NOT LOG
          this.pageName = value;
      });
}

Information to update

<h3 class="content-header">{{ pageName }}</h3>

I've been struggling with this for a while. Admittedly I'm pretty new to Angular, and maybe I'm just confused on how Observables work, but currently it's not working.

I am getting a single console.log in the console with "About Me", but nothing after that. No errors, nothing. The h3 DOES say About Me, but does not change.

Upvotes: 2

Views: 2415

Answers (1)

Andresson
Andresson

Reputation: 1307

In your Main component i noticed that you are providing your PageService like this

@Component({
  ...
  providers: [PageService]
}) 

If you are also doing the same in your Selection Component you wont be able to get the emitted message. This is cause by how Angular's Dependency Injection works. You need to have a Singleton PageService between your Main Component and your Selection Component. If that's the case, you should remove providers: [PageService] from both components and only provide it in your root module. (in most cases app.module.ts).

Try that and see if you wont get the emitted message from PageComponent in your MainComponent.

Edit

You can read more about DI here.

Upvotes: 3

Related Questions