angular - Typescript getCurrent location and pass to backend to get the result and pass to Material Table data source -
i have angular 2 project tries user's current location, therefore in class have following code:
export class currentlocation { constructor(private http: http) { } private lat : any; private lon : any; private params = new urlsearchparams(); private url = 'api/search/location'; getposition = (lat, lon) => { navigator.geolocation.getcurrentposition((position) => { this.lat = position.coords.latitude; this.lon = position.coords.longitude; }); } getcurrentlocation(): observable<any> { this.getposition(this.lat, this.lon); console.log(this.lat+ "," + this.lon); //console.log(this.lat + ":" + this.lon); this.params.set('lat', this.lat); this.params.set('lon', this.lon); //console.log(this.params.tostring()); var result = this.http.get(this.url, { search: this.params }); result.topromise(); return result; } } but lat , lon return undefined.. expected behaviour want once got latitude , longitude, send backend address following url http://localhost:8080/api/search/location?lat=123&lon=123
but seems setting value lat , lon failed.
how can set latitude , longitude in class?
edit on august 3:
according libertyernie's answer below, can pass current lat , lon backend, don't know how convert observable, since try using table module in angular material, in module data source must observable...
here code after try, still not working...
import { component, oninit } '@angular/core'; import { http, response, urlsearchparams } '@angular/http'; import { datasource } '@angular/cdk'; import { behaviorsubject } 'rxjs/behaviorsubject'; import { observable } 'rxjs/observable'; import 'rxjs/add/operator/startwith'; import 'rxjs/add/observable/merge'; import 'rxjs/add/operator/map'; import { restaurant } '../restaurant/restaurant'; import { category } '../category/category'; import { restaurantservice } '../restaurant/restaurant.service'; @component({ selector: 'app-home', templateurl: './home.component.html', styleurls: ['./home.component.css'] }) export class homecomponent implements oninit { displayedcolumns = ['id', 'name', 'category', 'address', 'city']; exampledatabase: examplehttpdatabase | null; datasource: exampledatasource | null; location: currentlocation | null; lat: any; lon: any; result: promise<any>; constructor(http: http) { this.exampledatabase = new examplehttpdatabase(http); this.datasource = new exampledatasource(this.exampledatabase); this.location = new currentlocation(http); } ngoninit() { this.result = this.location.getcurrentlocation(this.lat, this.lon); this.result.then(function(result){ console.log(result._body); }) console.log(this.lat, this.lon); this.datasource.connect(); } } export class examplehttpdatabase { private restauranturl = 'api/restaurant'; // url web api getrestaurants(): observable<restaurant[]> { var result = this.http.get(this.restauranturl) .map(this.extractdata); result.topromise(); return result; } extractdata(result: response): restaurant[] { return result.json().map(restaurant => { return { id: restaurant.id, name: restaurant.restaurant_name, category: restaurant.category.map(c => c.categoryname).join(','), address: restaurant.address.address, city: restaurant.address.city.city_name } }); } constructor(private http: http) { } } export class currentlocation { constructor(private http: http) { } private lat: any; private lon: any; private params = new urlsearchparams(); private url = 'api/search/location'; getposition = () => { var latitude, longitude; return new promise((resolve, reject) => { navigator.geolocation.getcurrentposition((position) => { resolve(position.coords); }, (err) => { reject(err); }); }) } async getcurrentlocation(lat, lon): promise<any> { let coords = await this.getposition(); lat = this.lat = coords['latitude']; lon = this.lon = coords['longitude']; this.params.set('lat', this.lat); this.params.set('lon', this.lon); var result = this.http.get(this.url, { search: this.params }); return await result.topromise(); } } export class exampledatasource extends datasource<restaurant> { constructor(private _exampledatabase: examplehttpdatabase) { super(); } /** connect function called table retrieve 1 stream containing data render. */ connect(): observable<restaurant[]> { return this._exampledatabase.getrestaurants(); } disconnect() { } } sorry code little bit confusing.. don't know how pass result connect() function make material table works..
full code in github: https://github.com/zhengye1/eatr/tree/dev
all of code in getcurrentlocation() run before callback given navigator.geolocation.getcurrentposition has chance run. can see putting console.log statement inside callback:
navigator.geolocation.getcurrentposition((position) => { console.log("got position", position.coords); this.lat = position.coords.latitude; this.lon = position.coords.longitude; }); there couple of reasons getcurrentposition needs use callback:
- the geolocation lookup might require browser query online service figure out location
- users might given prompt asking if want share location website (this default behavior in browsers)
the solution involves making wrapper around getcurrentposition returns promise. don't know how angular 2 observables work won't able in part, have getposition return promise so:
getposition = () => { return new promise((resolve, reject) => { navigator.geolocation.getcurrentposition((position) => { resolve(position.coords); }, (err) => { reject(err); }); }); and maybe getcurrentlocation (just guessing):
async getcurrentlocation(): promiselike<any> { let coords = await this.getposition(this.lat, this.lon); this.lat = coords['latitude']; this.lon = coords['longitude']; this.params.set('lat', this.lat); this.params.set('lon', this.lon); var result = this.http.get(this.url, { search: this.params }); return await result.topromise(); }
Comments
Post a Comment