Thaqif Yusoff
Thaqif Yusoff

Reputation: 71

Variable wont display data from observable

My variable wont display the data although it has been passed the value. If I use console it does display the value. I am fairly new to angular so please bear with me.

export class Page2Component implements OnInit {
    public person = {} as Person;

    constructor(public broadCastService : BroadcastService) {
        this.broadCastService.events.subscribe((e) => {
        this.person.age =e.age;
        this.person.name = e.name;
    });
}
<div class="column-6">
    <h2>This is the PAGE 2</h2>
    <p>Message will be display here from first.html</p>
    Name: {{person.name}}<br>
    Age: {{person.age}}<br>
</div>
<div id="2"></div>

My broadcast service.

export class BroadcastService {  
    public events: Observable<any>;
    private channel = new BroadcastChannel('test_channel');

    constructor() {
        this.events = new Observable ((observer) => {
            //this.events = Observable.create(obs => {
            this.channel.onmessage = ev => {
                observer.next(ev.data);
            }
            this.channel.onmessageerror = ev => {
                observer.error(ev);
            }
        });
    }

    public addPerson(person : any) {
        this.channel.postMessage(person); 
    }
}

Upvotes: 2

Views: 149

Answers (2)

Poul Kruijt
Poul Kruijt

Reputation: 71911

I'm gonna go on a limp here, and assume that the onmessage is running outside of the angular zone. You can check this by logging the NgZone.isInAngularZone() response like this:

this.channel.onmessage = ev => {
  console.log('Is in zone:', NgZone.isInAngularZone()); // probably logs false
  observer.next(ev.data);
}

The issue is either that you need to use the addEventListener method to make sure it runs in the zone. Like this:

 this.channel.addEventListener('message', (ev) => {
  console.log('Is in zone:', NgZone.isInAngularZone()); // should log true 
  observer.next(ev.data);
});

Or force it to run inside the zone (Make sure to make your class an @Injectable()):

@Injectable()
export class BroadcastService {  
  // ...
  constructor(readonly ngZone: NgZone) {
    // ...
     this.channel.onmessage = ev => {
      this.ngZone.run(() => {
        console.log('Is in zone:', NgZone.isInAngularZone()); // should log true
        observer.next(ev.data)
      });
    }
  }
}

Upvotes: 1

Ramesh Rajendran
Ramesh Rajendran

Reputation: 38683

Call your function in ngOnInit() instead of constructor.

export class Page2Component implements OnInit {   

  public person = {} as Person;
  constructor(public broadCastService : BroadcastService) {

   }
   ngOnInit(){
   this.broadCastService.events.subscribe((e) => {
      this.person.age =e.age;
      this.person.name = e.name;
    });
  }

Upvotes: 0

Related Questions