Search code examples
angulartypescriptrefreshgoogle-places-apimapbox

Changing from Google Geocoiding to Mapbox Places API in Angular 2


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.


Solution

  • 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