Reputation: 547
I have created a service which checks for changes in parent component and send notifications to the child component.
Below is the simple service.
import { Injectable } from '@angular/core';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { CloudDate } from './cloudDate';
import { Clouding } from './clouding';
@Injectable()
export class CloudingService {
// Observable string sources
private cloudingAnnouncedSource = new ReplaySubject<Clouding>(1);
private cloudingConfirmedSource = new ReplaySubject<Clouding>(1);
// Observable string streams
cloudingAnnounced$ = this.cloudingAnnouncedSource.asObservable();
cloudingConfirmed$ = this.cloudingConfirmedSource.asObservable();
// Service message commands
announceClouding(clouding: Clouding) {
this.cloudingAnnouncedSource.next(clouding);
}
confirmClouding(clouding: Clouding) {
this.cloudingConfirmedSource.next(clouding);
}
}
Clouding class looks like this:
export class Clouding {
cameraName: string;
cloudDate: string;
cameraType: string;
}
Now in the parent component, this class is initialized in the constructor and its variables will change depending on different methods. Example:
// In constructor
this.clouding = new Clouding();
// A method
getCameras(): void {
this.clouding.cameraName = this.currentCloudName;
}
//Another method
getCloudDates(): void {
this.clouding.cloudDate = this.currentCloudDate.cloudDate;
}
The variables this.currentCloudName and this.currentCloudDate.cloudDate will change dynamically depending on button clicks.
When the buttons are clicked, I do:
this.cloudingService.announceClouding(this.clouding);
In child component, I do this to get the new value of clouding.
import { Component, OnDestroy, Input, OnInit } from '@angular/core';
import { Clouding} from './clouding';
import { CloudingService } from './clouding.service';
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'app-images',
templateUrl: './images.component.html',
styleUrls: ['./images.component.css']
})
export class ImagesComponent implements OnDestroy, OnInit {
title = 'Images';
@Input()
clouding: Clouding;
subscription: Subscription;
constructor(
private cloudingService: CloudingService
) {
}
ngOnInit(): void {
this.subscription =
this.cloudingService.cloudingAnnounced$.subscribe(
clouding => {
this.clouding = clouding;
console.log(this.clouding);
},
// The 2nd callback handles errors.
(err) => console.error(err),
// The 3rd callback handles the "complete" event.
() => {
}
);
this.cloudingService.confirmClouding(this.clouding);
}
ngOnDestroy() {
// prevent memory leak when component destroyed
this.subscription.unsubscribe();
}
}
Now on the console, I get the below when I click on a button in the parent:
Clouding {cameraName: "Benjamin2", cloudDate: "2017-08-26"}
Clouding {cameraName: "Benjamin2", cloudDate: "2017-08-24"}
My question is, is there a way to make console print only the last change i.e.
Clouding {cameraName: "Benjamin2", cloudDate: "2017-08-24"}
and ignore the first change that occurred. I dont want to do execute a method everytime the object changes, just execute after all changes have been subscribed.
Hope the question is clear.
Upvotes: 0
Views: 552
Reputation: 23483
It sounds like you need a third button to trigger the announce, take this off the name-setting button and date-setting button and put it on the new button.
this.cloudingService.announceClouding(this.clouding);
Upvotes: 1