I'm able to change the value of a component's variable from another component as console.log() shows in this example.
My problem is that second component's view does not refresh despite the variable change.
Example:
first.component.ts
import {Component} from '@angular/core'; import {SecondComponent} from './second.component'; @Component({ selector: 'first', template: ` <h2>First component</h2> <button (click)="changeOutside()">Change</button> `, providers: [SecondComponent] }) export class FirstComponent { constructor(private otherComponent: SecondComponent) {} changeOutside() { this.otherComponent.change(); } } second.component.ts
import {Component} from '@angular/core'; @Component({ selector: 'second', template: ` <h2>Second component</h2> <div>Pet: {{animal}}</div> <button (click)="change()">Change</button> ` }) export class SecondComponent { animal: string = 'Dog'; change() { this.animal = 'Cat'; console.log(this.animal); } } Both components are totally unrelated from different branches of the DOM tree.
I've also tried with the first component emitting an event and the second component subscribing to it with the same result, the variable changes but view does not update.
After Günter's suggestion (thanks), I've tried with the next solution with no success. Even the console.log is not working.
first.component.ts
import {Component} from '@angular/core'; import {UpdateService} from './update.service'; @Component({ selector: 'first', template: ` <h2>First component</h2> <button (click)="changeOutside()">Change</button> ` }) export class FirstComponent { constructor(private updateService: UpdateService) {} changeOutside() { this.updateService.changeAnimal('Cat'); } } update.service.ts
import {Injectable} from '@angular/core'; import {Subject} from 'rxjs/Subject'; @Injectable() export class UpdateService { // Observable string sources private newAnimalSource = new Subject<string>(); // Observable string streams newAnimal$ = this.newAnimalSource.asObservable(); changeAnimal(animal: string) { this.newAnimalSource.next(animal); } } second.component.ts
import {Component} from '@angular/core'; import {UpdateService} from './update.service'; import {Subscription} from 'rxjs/Subscription'; import {Subject} from 'rxjs/Subject'; @Component({ selector: 'second', template: ` <h2>Second component</h2> <div>Pet: {{animal}}</div> <button (click)="change()">Change</button> ` }) export class SecondComponent { animal: string = 'Dog'; subscription: Subscription; constructor(private updateService: UpdateService) { this.subscription = updateService.newAnimal$.subscribe( animal => { console.log(animal); this.animal = animal; }); } change() { this.animal = 'Cat'; } } Solved
Finally, the solution proposed by Günter worked after adding UpdateService as a provider in the @NgModule of app.module.ts