Ironsun
Ironsun

Reputation: 881

change detection not working on routed page when first rendered in angular2

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

Answers (2)

micronyks
micronyks

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

Turdaliev Nursultan
Turdaliev Nursultan

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

Related Questions