Anna F
Anna F

Reputation: 1683

Shared service and Observable, BehaviourSubject in Angular2

I have a shared service SharedService

@Injectable()
export class SharedService {
  private title = new BehaviorSubject<string>("");
  currentMessage = this.title.asObservable();
  constructor() { }
  setData(val: string) {
    this.title.next(val);
  }
}

I have a component, where I get new data

export class Fill implements OnInit {
public title;

  constructor(public shared: SharedService) {
  }
  ngOnInit() {
this.shared.setData(this.title);
}}

And the component Info, where I want read new data export class InfoComponent implements OnInit {

  constructor(public shared: SharedService) { 
    this.title = ''; }
  ngOnInit() {

    console.log('i am title from info ')
    this.shared.currentMessage.subscribe(title => this.title = title)
    console.log(this.shared.currentMessage);
    console.log(this.title);
}}

In both cases of console.log I get Objects, that contains information, that I need - but I can't retrieve value of it. So, on my console it look like Message from console

But if try something like

console.log(this.shared.currentMessage.source.source.value);

it says Property 'source' is protected and only accessible within class 'Observable' and its subclasses.

this.shared.currentMessage.value
this.title.value

doesn't work also... How could I retrieve data (value) of one or another?

Upvotes: 0

Views: 1540

Answers (3)

Rahul Singh
Rahul Singh

Reputation: 19640

ngOnInit has to be Outside the constructor.

And as pointed by @micronkys

As you are subscribing to a observable the value of this.title is not available in the next line as the subscribing is async and so the title dosent get updated . when you log it.

try and use *ngIf = "title" in the template like this

<div *ngIf = "title">
  {{title}}
</div>

UPDATE

this.shared.currentMessage.subscribe((title) => {
                          this.title = title;
                          console.log(this.title)
}

Please find a plunker for the problem hope you get the answer now

Upvotes: 0

Pankaj Parkar
Pankaj Parkar

Reputation: 136184

Update

I suspect currentMessage = this.title.asObservable(); is invalid line inside your SharedService Injectable.

You could write a method to expose this.title expose by currentMessage method like below

@Injectable()
export class SharedService {
  private title = new BehaviorSubject<string>("");
  //below line was wrong.
  //currentMessage = this.title.asObservable();
  currentMessage(){
     return this.title.asObservable();
  }
  constructor() { }
  setData(val: string) {
    this.title.next(val);
  }
}
//Usage
console.log(this.shared.currentMessage().getValue());

Yes, you should first take out ngOnInit from constructor function. I supposed you want to retrieve initial state of your BehaviourSubject, so then you could use .getValue() function on that Observable without subscribing to stream.

console.log(this.shared.currentMessage.getValue());

Upvotes: 0

micronyks
micronyks

Reputation: 55443

Yes. @wostex mentioned it correctly. Keep ngOninit out side of the constructor function and,

this.shared.currentMessage.subscribe(title => {

     this.title = title;
     console.log(this.title)
})

Upvotes: 0

Related Questions