Reputation: 237
Good day everyone. Please I have a problem working with BehaviorSubject
. I Am trying to use a behavior subject in a shared service that gets/updates user information. I want when a user data is updated, other components that subscribe to the shared service will be updated too.
Service.ts
private userData= new BehaviorSubject<any>([]);
data = this.userData.asObservable();
customerData: any;
// this gets user data
getUserInfo(id){
this.apiUrl = ` ${this.siteUrl}customers/${id}`;
this.customerData = this.http.get(this.apiUrl);
this.userData.next(this.customerData);
return this.customerData;
}
//Update user data
updateCustomerData(id, customerDataUpdated){
let headers = new HttpHeaders ({
"Content-Type" : "application/json"
});
this.apiUrl = `${this.siteUrl}customers/${id}`;
return new Promise((resolve, reject) => {
this.http.put(this.apiUrl, customerDataUpdated, {headers} ).subscribe(
response => {
resolve(response);
this.userData.next(this.customerData);
},
error => {
resolve(error);
}
)
});
Profile.ts
Please tell me how do I use the BehaviorSubject here, so that if there is any update on any component subscribe to the shared service, this component will also be updated . Thanks
customerData: any;
constructor( private WC: Service){
}
ngOnInit() {
// get authenticated user id
this.isUserLoggedIn = localStorage.getItem('currentUserId');
this.WC.getUserInfo(this.isUserLoggedIn).subscribe((data)=>{
this.customerData = data;
});
}
edit page
// Update user info
async updateMethod(){
let loading = await this.loadingCtrl.create({
message: 'Updating...'
});
loading.present();
this.isUserLoggedIn = localStorage.getItem('currentUserId');
let customerDataUpdated = {
"first_name": `${this.user.first_name}`,
"last_name": `${this.user.last_name}`,
"email": `${this.user.email}`,
"username": `${this.user.username}`,
"billing": {
// "first_name": `${this.user.billing.phone}`,
// "last_name": `${this.user.value.billing_last_name}`,
"address_1": `${this.user.billing.address_1}`,
// "address_2": `${this.user.value.billing_address_2}`,
// "postcode": `${this.user.value.billing_postcode}`,
// "email": `${this.user.value.billing_email}`,
"phone": `${this.user.billing.phone}`
},
}
console.log('new update', this.user);
//update user data
this.WC.updateCustomerData(this.isUserLoggedIn, customerDataUpdated).then((data)=>{
this.changedetector.detectChanges();
loading.dismiss();
});
}
}
Upvotes: 3
Views: 14934
Reputation: 17504
Let me explain, You want to get getUserInfo
depending on user ID which is http
call. Hence it's triggered only once even though its an observable.
Try:
service.ts
private userData= new BehaviorSubject<any>([]);
userInfo$ = this.userData.asObservable();
// this gets user data
getUserInfo(id){
this.apiUrl = ` ${this.siteUrl}customers/${id}`;
return this.http.get(this.apiUrl).pipe(switchMap(userData) => {
this.userData$.next(userData);
return this.userInfo$;
})
}
private fetchUserInfo(id){
this.apiUrl = ` ${this.siteUrl}customers/${id}`;
this.http.get(this.apiUrl).subscriber(data =>{
this.userData$.next(userData);
})
}
//Update user data
updateCustomerData(id, customerDataUpdated){
let headers = new HttpHeaders ({
"Content-Type" : "application/json"
});
this.apiUrl = `${this.siteUrl}customers/${id}`;
return this.http.put(this.apiUrl, customerDataUpdated, {headers}).pipe(
tap(response => this.fetchUserInfo(id))
)
});
Make changes in edit-page.component.ts accordingly for updateCustomerData
as it is not a promise anymore.
A note of caution: if you use userInfo$
and pass some other id
into getUserInfo()
then it'll affect your Profile.ts
component. Because they are sharing common observable.
Upvotes: 2
Reputation: 141
Please try this,
customerData: any;
constructor( private WC: Service){ }
ngOnInit() {
//this will triger when data is changing
this.WC.data.subcribe(res => {
});
}
Upvotes: 2