I am working on a web app that geocodes a point when clicked on a map.
The app was written in Angular 2. I am unfortunately not familiar with Angular.
Currently the app geocodes with Google and the text box automatically updates when the result is returned. The code currently looks like this:
import { Injectable, Inject } from '@angular/core';
import { Http } from '@angular/http';
import { Point } from '../models/geojson.model';
@Injectable()
export class GeocoderService {
private geocodeUrl: string = 'https://maps.googleapis.com/maps/api/geocode/json?key=REDACTED';
constructor(private http: Http) {
}
public addressFromPoint(point: Point) {
let url: string = this.geocodeUrl + '&latlng=' + encodeURIComponent(point.latLong());
console.log(url);
return this.http.get(url);
}
public addressToPoint(address: string) {
let url: string = this.geocodeUrl + '&address=' + encodeURIComponent(address);
console.log(url);
return this.http.get(url);
}
public getAddress(point: Point) {
let address: string;
this.addressFromPoint(point).subscribe(
(response) => {
address = response.json();
}
)
return address;
}
public getPoint(address: string):Point {
let point: Point;
this.addressToPoint(address).subscribe(
(response) => {
point = new Point([]);
},
(error) => {
});
return point;
}
}
I have changed this to use the Mapbox Places API, as follows:
import { Injectable, Inject } from '@angular/core';
import { Http } from '@angular/http';
import { Point } from '../models/geojson.model';
@Injectable()
export class GeocoderService {
private geocodeUrl: string = 'https://api.mapbox.com/geocoding/v5/mapbox.places/';
private ACCESS_TOKEN: string = 'access_token=REDACTED';
constructor(private http: Http) {
}
public addressFromPoint(point: Point) {
let url: string = this.geocodeUrl + point.longLat() + '.json?' + this.ACCESS_TOKEN;
console.log(url);
return this.http.get(url);
}
public addressToPoint(address: string) {
let url: string = this.geocodeUrl + address + '.json?' + this.ACCESS_TOKEN;
console.log(url);
return this.http.get(url);
}
public getAddress(point: Point) {
let address: string;
this.addressFromPoint(point).subscribe(
(response) => {
address = response.json();
}
)
return address;
}
public getPoint(address: string):Point {
let point: Point;
this.addressToPoint(address).subscribe(
(response) => {
point = new Point([]);
},
(error) => {
});
return point;
}
}
The geocoder service is used as follows:
this.app.geocoder.addressFromPoint(point).subscribe((response) => { let name = response.json().formatted_address; });
which I have now updated to match the Mapbox API like this:
this.app.geocoder.addressFromPoint(point).subscribe((response) => { let name = response.json().features[0].place_name; });
When I run the app now, I can see in the F12 console that the correct address is being geocoded, but the text boxes no longer automatically update.
I thought it could be the typings, but this still does not work after I cast to strings. I also thought it could be the length of the string as the mapbox version is longer (perhaps the text box has a limit) but finding a substring of this also does not seem to update the textbox. I also tried updating it to a string literal, but even that does not work. My guess is that the problem lies in how it is using observables, but I don't know how to solve this.
What are some other reasons that my text box stopped updating? I can edit to supply more information or code if this is not enough to go on.
That all looks fine. I think if the observable is not emitting a value it's probably because an error is occurring in the observable or else it is just not emitting a valid value. Because Mapbox and Google have different response formats just check that you are using the correct references to place_name
and features
everywhere and not using formatted_address
or results