This is my main component:
import { Component, OnInit } from '@angular/core';
import { MyService } from '../my-service.service';
import { DataShareService } from '../data-share-service.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
private myCustomer: Object;
constructor(private myService: MyService) { }
ngOnInit() {
this.getMyCustomerProfile();
console.log("In Home: " + JSON.stringify(this.myCustomer)); // this prints undefined - why ?
// this.dataShareService.currentCustomer.subscribe(customer => this.customer = customer);
// this.dataShareService.changeCustomer(this.customer);
}
private getMyCustomerProfile(){
this.myService.getProfile()
.subscribe(
customer => {
this.myCustomer = customer;
console.log("In Home: " + JSON.stringify(this.myCustomer)); // this prints the returned json properly
},
error => {
console.log("Error fetching user profile!");
});
console.log("In Home: " + JSON.stringify(this.myCustomer)); // this prints undefined - why ?
}
}
MyService
getProfile
method is a rest call:
getProfile(){
return this.http.get(this.config.myUrl + 'mycustomer/', this.options).map((response: Response) => response.json());
}
Question 1: Why does the console.log
inside getMyCustomerProfile's
subscribe
method prints the returned object json correctly but the other two console.log
prints undefined
?
Question 2: Also, how do I share the returned Object in above component with Sibling component (and not child component) using shared service ?
I tried below, but its not working.
Shared Service:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class DataShareService {
private customerSource = new BehaviorSubject<Object>("default customer");
currentCustomer = this.customerSource.asObservable();
constructor() { }
changeCustomer(customer: Object){
console.log("In Service: "+customer);
this.customerSource.next(customer);
}
}
Sibling:
import { Component, OnInit } from '@angular/core';
import { DataShareService } from '../data-share-service.service';
@Component({
selector: 'app-sibling',
templateUrl: './sibling.component.html',
styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit {
private myCustomer: Object;
constructor(private dataShareService: DataShareService) { }
ngOnInit() {
this.dataShareService.currentCustomer.subscribe(customer => this.myCustomer = customer);
}
}
The HTML Template for both HomeComponent
and SiblingComponent
is printing a property from the returned object:
Welcome {{myCustomer?.name}}
This prints correctly in HomeComponent
but not in SiblingComponent
. Meaning the data is not getting shared. I am not sure what am I doing wrong.
Thanks for reading!
It's all asynchronous. When you use console.log
outside subscribe
(or basically outside the operator chain) it'll be called before any value is emitted and therefore it's undefined
.
Just assign the value into a property in the service class:
.subscribe(customer => this.myService.myCustomer = customer)
If you need the sibling components to be able to react when the myCustomer
changes asynchronously make it a BehaviorSubject
(or ReplaySubject(1)
would in this case do the same).
.subscribe(customer => this.myService.myCustomer.next(customer))
Thanks to Martin for the inputs.
Updating my getMyCustomerProfile method to following worked:
private getMyCustomerProfile(){
this.myService.getProfile()
.subscribe(
customer => {
this.dataShareService.changeCustomer(customer);
},
error => {
console.log("Error fetching user profile!");
});
}
And subscribing the same in both Sibling and main component with the following line:
this.dataShareService.currentCustomer.subscribe(customer => this.customer = customer);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.