Reputation: 2116
I have 2 components in my angular app. Component A is a header and component B sets a value that I need in component A. The problem is that component A is getting set before B so the value that I need is not being displayed when I need it. If I refresh my browser then it shows. My code will explain better.
Component A
offerExpiry: any;
constructor(
public expiry: ExploreOfferService
) {
}
ngOnChanges() {
this.expiry.event.subscribe((data) => {
this.offerExpiry = data;
});
}
<div class="col-5 right">
<div>
<span *ngIf="offerExpiry">{{offerExpiry?.data}} days left to respond</span>
<img src="../../../../assets/icons/calendar(old).png">
</div>
</div>
Component B
offerExpiry: any;
...
async ngOnInit() {
if (this._exploreService.offer) {
...
} else {
const offer = await this._exploreService.getOfferDetails();
const date1 = new Date(offer.expiryDate);
const date2 = new Date(offer.startDate);
const diffTime = Math.abs(date2.getTime() - date1.getTime());
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
this.offerExpiry = diffDays;
this._exploreService.publishExpiryDate({data: this.offerExpiry});
}
}
service file
public publishExpiryDate(data: any) {
this._subject.next(data);
}
Upvotes: 0
Views: 173
Reputation: 483
When you are getting data from service do this in your service: create a subject and a method to get it subscribed in component B
private com_sub = new Subject<any>();
getData(): Observable<any> {
return this.com_sub.asObservable();
}
whenever you get data in from service, pass it to subject:
this.com_sub.next(data);
In Component B, that loads earlier, subscribes that subject like :
this.yourservice.getData().subscribe(data => {
console.log('your data here',data);
});
Upvotes: 2
Reputation: 941
Create one shared Observable service in your module and once your values are set from component B update the value and subscibe that observable variable in component A. so you will be received you updated value
steps are as follows
step 1 : create shared observable service
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable({
providedIn: 'root'
})
export class ObservablesService {
constructor(
) { }
public updatedValue = new BehaviorSubject<object>([]);
changeInUpdatedValue(value = {}) {
this.updatedValue.next(value);
}
}
step 2 : Import that service in constructor and from Component B calls method changeInUpdatedValue function onces you receive the value
constructor(
private _observablesService: ObservablesService,
) {
//in data you can send your updated value whatever it is array,object or string
this._observablesService.changeInUpdatedValue({ status: true, data: {} });
}
step 3 : Import that service in constructor and from Component A subscribe method updatedValue function onces you receive the value
constructor(
private _observablesService: ObservablesService,
) {
this._observablesService.updatedValue.subscribe((result: any) => {
//you will receive your value here
})
}
Thanks
Upvotes: 1
Reputation: 4117
ngOnChanges
is life hook for component binding changes, rather than subscribing observable there, subscribe the service variable in constructor or ngOnInit
Service.ts
public getSubject() {
return this._subject;
}
public publishExpiryDate(data: any) {
this._subject.next(data);
}
In Component A,
constructor(service: Service) {
this.service.getSubject().subscribe((data) => {
this.offerExpiry = data;
});
}
Upvotes: 1
Reputation: 905
Create a variable of type any in your service file then need to assign it in behaviroural subscriber that will listen when your component B loaded and subscribe the variable in onInit() in component A.
Upvotes: 1