Reputation: 881
i am trying to get google maps values from parent component to route component for which i have created a sharedservice as follow
import {Injectable} from 'angular2/core';
import {Subject} from "rxjs/Subject";
@Injectable()
export class SearchService {
private addressmap= new Subject<Sharedcomponent >();
public searchaddressStream$ = this.addressmap.asObservable();
broadcastaddressChange(address: Sharedcomponent ) {
this.addressmap.next(address);
}
}
export class Sharedcomponent {
country: string;
state: string;
city: string;
street: string;
}
from parent i am broadcasting this address on value change and receiving it in child by subscribing to it and its all working only if the child page is rendered with parent. if parent is rendered first then i call the child view via routing then it doesnt show the data at start when page is rendered it shows only if i change the value in parent changed again. the child view is subscribing to the service but its not getting data when rendered. If you need more explanation or code from parent or view let me know. hope someone can help me on this.
UPDATE
this is the update so you can understand my problem its my app component where i am getting values from google maps api
declare var google: any;
@Component({
selector: 'my-app',
templateUrl: 'app/app.component.html',
directives: [ROUTER_DIRECTIVES, ProductComponent],
providers: [ SearchService]
})
export class AppComponent {
constructor(private _http: geoService, private sharedService: SearchService, private cdr: ChangeDetectorRef) {
}
ngOnChanges() {
this.sharedService.broadcastTextChange(this.street);
this.cdr.detectChanges();
}
public maps: geoResult;
public cat_error: Boolean = false;
public xml_Latitude :any;
public xml_Lang: any;
public city: string;
public state: string;
public coutnry: string;
public street= new SharedService;
public input: any;
public autocomplete: any;
ngOnInit() {
var instance = this,
autocomplete;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(res=> {
instance._http.getPlaces(res.coords.latitude, res.coords.longitude).subscribe(
data=> {
instance.maps = data;
console.log(instance.maps);
var result = instance.maps.status;
var result2 = instance.maps.results;
if (result != "undefined" || "" || null) {
instance.setValue(result2[0].address_components[6].long_name, result2[0].address_components[5].long_name, result2[0].address_components[4].long_name);
}
});
});
}
instance.input = document.getElementById('google_places_ac');
autocomplete = new google.maps.places.Autocomplete(instance.input, { types: ['(cities)']});
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace(); console.log(place);
if (place.address_components[3] != undefined ) {
instance.setValue(place.address_components[3].long_name, place.address_components[2].long_name, place.address_components[1].long_name);
} else
{
instance.setValue(place.address_components[2].long_name, place.address_components[1].long_name, place.address_components[0].long_name);
}
});
}
setValue(a, b, c) {
this.street.country = a;
this.street.state = b;
this.street.city = c;
this.sharedService.broadcastTextChange(this.street);
}
}
later i have a child view which gets this value
ngOnInit() {
this.getNewProduct();
this.getlocation();
}
getlocation() {
this.shared.searchTextStream$.subscribe(
text => {
this.street = text;
this.country = this.street.country;
this.state = this.street.state;
this.city = this.street.city
console.log(this.country, this.state, this.city);
}, error=> { console.log(<any>error);}
);
}
getNewProduct() {
this._productService.selectproduct(0)
.subscribe(
product => {
this.model = product;
this.isloading = false;
console.log(this.model)
},
error => this.errorMessage = <any>error);
}
}
but i am not getting geolocation on when this view is rendered and if i change value in parent's text box then its gets updated in view
Upvotes: 0
Views: 293
Reputation: 55443
import {Injectable,EventEmitter} from 'angular2/core';
import {Subject} from "rxjs/Subject";
@Injectable()
export class SearchService {
searchaddressStream$:EventEmitter<Sharedcomponent> = new EventEmitter();
broadcastaddressChange(address: Sharedcomponent ) {
this.searchaddressStream$.emit(address);
}
}
ngOnInit() {
this.getNewProduct();
// this.getlocation();
}
ngViewAfterInit()
{
this.getlocation();
}
Upvotes: 0
Reputation: 2576
If you want to listen to the last broadcast, even if you were not subscribed yet then you need to use BehaviorSubject
instead of Subject
. In this case you will get the last update even if you subscribe after the broadcast. This is your current situation
This code is from RxJS
repository in Github
BehaviorSubject
gives you only the last value. If you need last 10 or 2 values then use ReplaySubject
instead.
/*
* BehaviorSubject
*
* Subject that remembers the last (or initial) value
*/
var xs = new Rx.BehaviorSubject()
xs.subscribe(logAllObserver('BehaviorSubject'))
//=> BehaviorSubject - Value: undefined
var xs = new Rx.BehaviorSubject('default')
xs.subscribe(logAllObserver('BehaviorSubject'))
//=> BehaviorSubject - Value: default
var xs = new Rx.BehaviorSubject('default')
xs.onNext('new one')
xs.subscribe(logAllObserver('BehaviorSubject'))
//=> BehaviorSubject - Value: new one
Upvotes: 1