Google Places Autocomplete and Ionic 2

The Google Places Autocomplete service is a useful service if you want to add location autocomplete to your app.  Recently I needed this in an Ionic 2 app I was developing.

What is the Google Places Autocomplete service?  From the Google Places website:

The Place Autocomplete service is a web service that returns place predictions in response to an HTTP request. The request specifies a textual search string and optional geographic bounds. The service can be used to provide autocomplete functionality for text-based geographic searches, by returning places such as businesses, addresses and points of interest as a user types.

Using the service in your Ionic 2 app is very easy:

In your index.html add the following line:

<script type=text/javascript src=http://maps.googleapis.com/maps/api/js?key=yourkey&amp;libraries=places></script>

replace yourkey with your own Google Maps API key which you generate via the Google API Console.

On a component’s HTML page add the fields you want to use for the autocomplete (in this example I have two, a FROM field and a TO field:

<p class = “label”>From</p>
<input (focus)=”clearFrom()” id=”journey_from” name=”journey_from” type=”text” placeholder=”Enter location”[(ngModel)]=”fromValue”>
<p class = “label”>To</p>
<input (focus)=”clearTo()” id=”journey_to” name=”journey_to” type=”text” placeholder=”Enter location”[(ngModel)]=”toValue”>

In your component (this example used Typescript) define the model values:

fromValue:string;

toValue:string;

and in the constructor initialise them:

this.fromValue = “”;
this.toValue = “”;

Then add an ngOnit() method that setups up autocomplete service listeners against both fields:

ngOnInit(){

// get the two fields
let input_from = (<HTMLInputElement>document.getElementById(“journey_from”));
let input_to = (<HTMLInputElement>document.getElementById(“journey_to”));

// set the options
let options = {
types: [],
componentRestrictions: {country: “uk”}
};

// create the two autocompletes on the from and to fields
let autocomplete1 = new google.maps.places.Autocomplete(input_from, options);
let autocomplete2 = new google.maps.places.Autocomplete(input_to, options);

// we need to save a reference to this as we lose it in the callbacks
let self = this;

// add the first listener
google.maps.event.addListener(autocomplete1, ‘place_changed’, function() {

let place = autocomplete1.getPlace();
let geometry = place.geometry;
if ((geometry) !== undefined) {

console.log(place.name);

console.log(geometry.location.lng());

console.log(geometry.location.lat());

});

// add the second listener
google.maps.event.addListener(autocomplete2, ‘place_changed’, function() {
let place = autocomplete2.getPlace();
let geometry = place.geometry;

if ((geometry) !== undefined) {

console.log(place.name);

console.log(geometry.location.lng());

console.log(geometry.location.lat());

});

});

}

That’s all there is to it – you should now be able to see google place names appear when you type in either of those fields – and see the selected item’s attributes written to the console.

 


I’m a mobile applications developer based in the UK, concentrating primarily on hybrid application development with Ionic and Ionic 2 but also with native development skills. Please visit www.crossplatformsolutions.co.uk for more information about me and how I may be able to help you with mobile application development, particularly with Ionic 2 but also with other mobile frameworks and technologies.  Thanks for visiting.

 

 

17 thoughts on “Google Places Autocomplete and Ionic 2

  1. Vinit Jain

    Thanks for posting this. I’m new to ionic framework and am trying to get this working on a prototype app. i cant get this code to compile in ts. I added google-api npm package and its tsd file to no avail. how did you get the google. code to compile in the .ts code?

    Reply
    1. richardshergold Post author

      Hi. I’m not at my computer now but you will need to include the typings files. Check the ionic conference app as that uses google maps. That should get you sorted.

      Reply
      1. Vinit Jain

        Thanks for your quick response. So i matched the typings to the conference app. but i still get the following at run time. I’m running the app in the browser using ionic serve

        EXCEPTION: Error: Uncaught (in promise): EXCEPTION: ReferenceError: google is not defined in [null]
        ORIGINAL EXCEPTION: ReferenceError: google is not defined
        ORIGINAL STACKTRACE:
        ReferenceError: google is not defined
        at SelectLocationPage.ngOnInit (http://127.0.0.1:8100/build/js/app.bundle.js:321:33)
        at AbstractChangeDetector.ChangeDetector_HostSelectLocationPage_0.detectChangesInRecordsInternal (viewFactory_HostSelectLocationPage:21:99)
        at AbstractChangeDetector.detectChangesInRecords (http://127.0.0.1:8100/build/js/app.bundle.js:13334:18)
        at AbstractChangeDetector.runDetectChanges (http://127.0.0.1:8100/build/js/app.bundle.js:13311:14)
        at AbstractChangeDetector.detectChanges (http://127.0.0.1:8100/build/js/app.bundle.js:13300:73)
        at ChangeDetectorRef_.detectChanges (http://127.0.0.1:8100/build/js/app.bundle.js:14201:73)
        at ViewController.willEnter (http://127.0.0.1:8100/build/js/app.bundle.js:45870:22)
        at NavController._postRender (http://127.0.0.1:8100/build/js/app.bundle.js:44184:30)
        at http://127.0.0.1:8100/build/js/app.bundle.js:44132:27
        at http://127.0.0.1:8100/build/js/app.bundle.js:44510:13

    1. Vinit Jain

      Never mind. For some reason text/javascript script type was adding another quotes around the js link ( so double quotes). console wasnt throwing any error but now after removing text/javascript type it is able to load the js. thanks for guiding me in the right direction though.

      Reply
  2. Juan

    Hi Richard,

    Thanks for the tutorial, it helped me a lot. It works well in chrome, but not in an iOS device. Here is the problem: When I try to select a suggestion from the autocomplete list, it actually selects nothing. I tried looking in forums, but no one seems to have an elegant fix for this. Did you tried it in an iOS device? Do you have an idea on how to quick fix this problem in iOS?

    Thanks a lot.

    Reply
  3. Neel

    Hi, I have followed this approach in my project in locationAddAddress component, when first time locationAddAddress component is loaded then google loads addresses in dropdown, after that if i visit any other component and come back to locationAddAddress component then it stops working and no address is being added in dropdown

    Please refer my code below:

    ngOnInit()
    {
    this.getAddressSettings();
    }

    getAddressSettings() {
    var locationServiceRef = this.locationService;
    var thisRef = this;

    this.locationService.getAddressSettings().subscribe(
    data => {
    document.getElementById(‘RecipientAddress’).value = ”;

    this.autocomplete = new google.maps.places.Autocomplete(
    (document.getElementById(‘RecipientAddress’)),
    { types: [‘geocode’] });

    var accessAutoComplete = this.autocomplete;

    google.maps.event.addListener(accessAutoComplete, ‘place_changed’, function () {
    …. });

    …..
    }

    Reply
  4. Saurabh Agnihotri

    hi richards .
    i still get the following at run time. I’m running the app in the browser using ionic serve..

    Error: Uncaught (in promise): TypeError: Unable to get property ‘Autocomplete’ of undefined or null reference
    TypeError: Unable to get property ‘Autocomplete’ of undefined or null reference
    at TripdetailsPage.prototype.ngOnInit (http://localhost:8100/build/main.js:46604:9)
    at checkAndUpdateDirectiveInline (http://localhost:8100/build/main.js:11112:9)
    at checkAndUpdateNodeInline (http://localhost:8100/build/main.js:12489:13)
    at checkAndUpdateNode (http://localhost:8100/build/main.js:12458:9)
    at debugCheckAndUpdateNode (http://localhost:8100/build/main.js:13087:5)
    at debugCheckDirectivesFn (http://localhost:8100/build/main.js:13028:13)
    at Anonymous function (Function code:18:5)
    at debugUpdateDirectives (http://localhost:8100/build/main.js:13013:5)
    at checkAndUpdateView (http://localhost:8100/build/main.js:12425:5)
    at callWithDebugContext (http://localhost:8100/build/main.js:13413:9)
    at debugCheckAndUpdateView (http://localhost:8100/build/main.js:12953:5)
    at ViewRef_.prototype.detectChanges (http://localhost:8100/build/main.js:10523:54)
    at NavControllerBase.prototype._viewAttachToDOM (http://localhost:8100/build/main.js:45268:9)
    at NavControllerBase.prototype._transitionInit (http://localhost:8100/build/main.js:45371:13)
    at NavControllerBase.prototype._postViewInit (http://localhost:8100/build/main.js:45223:9)
    at g (http://localhost:8100/build/polyfills.js:3:7128)
    at l (http://localhost:8100/build/polyfills.js:3:6245)
    at Anonymous function (http://localhost:8100/build/polyfills.js:3:6805)
    at t.prototype.invokeTask (http://localhost:8100/build/polyfills.js:3:15089)
    at onInvokeTask (http://localhost:8100/build/main.js:4489:21)
    at t.prototype.invokeTask (http://localhost:8100/build/polyfills.js:3:15089)
    at n.prototype.runTask (http://localhost:8100/build/polyfills.js:3:10364)
    at a (http://localhost:8100/build/polyfills.js:3:5306)
    at invoke (http://localhost:8100/build/polyfills.js:3:16204)

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s