MaTT
MaTT

Reputation: 13

How to update data between components in Angular 5 in real time?

I'm beginner with Angular and I try to make some exercise. I have 2 components, one for getting text and one for display this text. I have got service and everything works fine when I'm using button to trigger function to change text. What I want to make, is to change text without clicking button or anything else. I already know that I can't use ngOnChange, beacuse it does not work.

component 1 ts

mytext: string;

constructor(private data: MyService) {}

ngOnInit() {
    this.data.currentMytext.subscribe(mytext => this.mytext = mytext);
}

changeMytext(): void {
    this.data.changeMytext(this.mytext);
}

component 1 html

<form>
<button (click)="changeMytext()">Start</button>
<input [(ngModel)]="mytext" type="text" name="mytext">
</form>

component 2 ts

mytext: string;

constructor(private data: MyService) {}

ngOnInit() {
    this.data.currentMytext.subscribe(mytext => this.mytext = mytext);
}

component 2 html

<p>{{mytext}}</p>

service

private mytextSource = new Subject<string>();

currentMytext = this.mytextSource.asObservable();

constructor() { }

changeMytext(mytext: string)
{
    this.mytextSource.next(mytext);
}

Upvotes: 1

Views: 5093

Answers (2)

DeborahK
DeborahK

Reputation: 60548

Because there is already so much code in my "you don't need a subject here" answer, I'll provide the Subject technique in this second answer.

You can use getters/setters with a Subject like this:

Component 1

private _myText: string;
get mytext(): string {
   return this._myText;
};

set myText(value: string) {
   this._myText = value;  // This line is not really needed because it will
                          // get updated by the subscribe below.
   this.data.changeMytext(value);
}

constructor(private data: MyService) {}

ngOnInit() {
    this.data.currentMytext.subscribe(
       mytext => this._mytext = mytext);
}

Template 1

<form>
<input [(ngModel)]="mytext" type="text" name="mytext">
</form>

Component 2

mytext: string;

constructor(private data: MyService) {}

ngOnInit() {
    this.data.currentMytext.subscribe(
        mytext => this.mytext = mytext
    );
}

Template 2

<p>{{mytext}}</p>

Service

private mytextSource = new Subject<string>();

currentMytext = this.mytextSource.asObservable();

constructor() { }

changeMytext(mytext: string)
{
    this.mytextSource.next(mytext);
}

NOTE: I did not syntax check this code. It was all written here, not in an editor.

Upvotes: 0

DeborahK
DeborahK

Reputation: 60548

You can use getters/setters instead of a Subject like this:

Component 1

get mytext(): string {
   return this.data.currentMyText;
};

set myText(value: string) {
   this.data.currentMyText = value;
}

constructor(private data: MyService) {}

Template 1

<form>
<input [(ngModel)]="mytext" type="text" name="mytext">
</form>

Component 2

// This component only needs a getter
// since it is only displaying the value
get mytext(): string {
   return this.data.currentMyText;
};

constructor(private data: MyService) {}

Template 2

<p>{{mytext}}</p>

Service

currentMytext: string;

constructor() { }

NOTE: I did not syntax check this code. It was all written here, not in an editor.

Upvotes: 1

Related Questions