Reputation: 17375
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!
Upvotes: 0
Views: 365
Reputation: 17375
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);
Upvotes: 0
Reputation: 96889
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))
Upvotes: 1