This guide will walk you through using the Google Places API with an Ionic 3 application to avoid CORS errors by implementing a dead-simple NodeJS backend on Heroku.

If you’ve searched for a way to use the Google Places API with your Ionic 3 application without involving a backend, I am afraid you do not have a choice. Since the Google Places API v3 has deprecated JSONP , the best way forward is a NodeJS backend.

Thankfully, you can get started very quickly and easily – and for free – using Heroku to host the NodeJS backend for you.

TLDR

If you don’t want to read the guide and just want the code, it’s available on GitHub here.

You should follow this guide if you:

Want to use the Google Places API in your Ionic 1, Ionic 2, Ionic 3, AngularJS, Angular 2, Angular 3, Angular 4, Angular 5 application but keep having CORS errors when trying to call the API on an endpoint similar to: https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=YOUR_API_KEY

Don’t want to use the Google Places API JavaScript Library because pasting <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script> in to your index.html is ugly and not the way it should be done (why isn’t there a NPM package!?)

in to your is ugly and not the way it should be done (why isn’t there a NPM package!?) Are hesitant about having to learn Heroku and Node when you just want to use the damn API

Might one day need a simple API for other libraries and database anyway!

In this guide, we will:

Walk through building a very simple NodeJS backend which will communicate with the Google Places API, get the data we need, and then return it to our app

Walk through uploading our code to Heroku and running the server

Walk through updating our code, and then updating it on Heroku

How to use Google Places API v3 with an Ionic Application by using a NodeJS server on Heroku as a proxy

Step 1: First things first, sign up to a free account on Heroku. Then download and install the Heroku CLI. The Heroku CLI has a dependency on Git which you also need to install. You’ll also need to install NPM. I will assume you already have a Google API key.

Thankfully, these are all relatively straight-forward installs which most web developers will already have on their machines.

Step 2: Create a new directory somewhere to develop your NodeJS backend. Call it whatever you like. Then navigate to the directory using the command line (or Terminal on Mac).

Step 3: Let’s write some code. From the command line enter npm init and walk through the steps. I usually just keep pressing enter because you can change these values later. This command creates a package.json file in your project directory.

Step 4: We need to install three packages, explained below. To do this enter the following commands:

npm install axios express --save npm install nodemon --save-dev

Axios is a library that wraps the native Node http Class and allows us to make async http calls with support for the Promise API. Ionic/Angular developers will find this very familiar territory.

Express is a library that allows you to run a server on NodeJS.

Nodemon is a library that will make developing locally on your machine easier. It will restart the NodeJS server every time you change the code, a bit like how the browser automatically refreshes for Ionic CLI and Angular CLI projects.

To get the Nodemon package to work for you, you need to add a NPM run script under the scripts property in package.json . It should look like this:

"scripts": { "dev": "nodemon server.js" }

Step 5: Now create a server.js file in the root of your project directory. Inside this file, copy the following:

const express = require('express'); const bodyParser = require('body-parser'); const app = express(); const port = process.env.PORT || 8000; app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", '*'); res.header("Access-Control-Allow-Credentials", true); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,Accept,content-type,application/json'); next(); }); require('./public')(app, {}); app.listen(port, () => { console.log('We are live on ' + port); });

The first three lines are to import the external library packages.

We then set a port number for our app to run on. Heroku doesn’t allow you to set a port which is why the syntax process.env.PORT || 8000 has been used. It allows Heroku to set it’s own port number, but if we run the server on our local development machine it will map to port 8000. You can change this if you wish.

The next block of code allows any domains to make a request to our server. To keep this tutorial simple, I have configured to allow CORS from all sources. In production, you need to change this to avoid your server from being swamped with requests from unauthorised users and domains.

We then import our custom code in the public directory (which we will get to next).

And finally, we fire up our Express server with the app.listen() command and tell it to listen for requests on the specified port.

Step 6: For this part of the tutorial I am going to be focusing on retrieving Place details from the Google Places API ( https://maps.googleapis.com/maps/api/place/details/json?placeid=PLACE_ID&key=YOUR_API_KEY ). You can use any endpoint you wish on the Google API, just change the URL and pass the necessary parameters.

To create the endpoint on your NodeJS server, create a folder in the root of your project called public . Inside this folder create two files: index.js and a file to contain at least one endpoint. I called mine google-place-details.js because it will handle all logic for Google Place Details only.

Inside the index.js file, paste the following code, and refactor as necessary:

const googlePlaceDetails = require('./google-place-details'); module.exports = function (app, db) { googlePlaceDetails(app, db); // Other route groups could go here, in the future };

In the google-place-details.js file paste the following, remembering to pass the appropriate parameters including your API key:

const axios = require('axios'); module.exports = function (app, db) { app.get('/googleplace/:id', (req, res) => { axios.get('https://maps.googleapis.com/maps/api/place/details/json?placeid=' + req.params.id + '&key=YOUR_APPLICATION_KEY') .then(function (response) { if (response.data.status == "OK") { res.send(response.data.result); } else { res.status(400).send("Error"); } }) .catch(function (error) { res.status(500).send("There was an error!"); }); }); };

In this file we are importing the axios library package and then declaring a module which will contain our functions. Express modules require two parameters, the application and a database which is why we have passed the values app and db throughout our files. Looking closely at the server.js file you will see the arguments passed for the db value is a blank object. That’s because we are not creating a database for our application – but you might do one day!

The app.get() invocation takes a string argument for the route and a callback function with two parameters. In this case, when the user visits OURAPP.COM/googleplace/1 the function will execute. Within the route string, :id represents a variable which we can later access through req.params.id .

The remainder of the function should be familiar to all Ionic/Angular developers. We use the axios library to make a HTTP GET request to the Google Places API and pass the appropriate parameters. Once we receive a response, the .then() block is executed. We check the object received from the Google API to ensure there wasn’t an error and then return the data to the browser page with res.send(response.data.result) .

If there is an error on the Google API, for example the ID parameter is invalid, we return an Error 400 with an “Error” message. If the HTTP request to the Google API fails entirely, it is caught in the .catch() block and for simplicity with return an Internal Server Error 500.

Step 7: We can test our server now by returning to the command line and entering

npm run dev

This will use the Nodemon package to fire up an Express server. We can navigate to localhost:8000/googleplace/ChIJD_V5b-EadkgReisRvZ5CxZc in the browser and should receive back a valid response (based on the code above). We can change the URL to localhost:8000/googleplace/ChIJD which at the time of publishing is an invalid ID for the Google Place Details API which will then return a HTTP ERROR 400 response.

Step 8: Once you’re satisfied your app works locally, it’s time to push it to the world-wide-web using Heroku. We’ll be using Heroku’s free plan. Don’t forget that the CORS settings in server.js let anyone use your access to Google’s API.

Head back to the command line and enter

heroku login

And enter your Heroku credentials as prompted.

Next, enter the command

heroic create <name-of-your-app>

This will link your local source code to a Git repository on Heroku which is linked to an application in your Dashboard. Commit the changes to your code using

git add -A git commit -m "<commit message here>"

And now for the moment of truth, push your code to Heroku where it will automatically detect that you are creating a NodeJS server, and hence build the code and make it available

git push heroku master

You can now navigate to the Heroku dashboard in your browser and see your app live. You can also navigate to <your-app-name>.herokuapp.com in your browser – but in our case there is nothing in the root of the application so try <your-app-name>.herokuapp.com/googleplace/ChIJD_V5b-EadkgReisRvZ5CxZc .

To make changes to your code and upload to Heroku

After making changes to your code you should always test it locally by running the command npm run dev . Once you’re satisfied you’ll need to check it in with git commit -m "<summary of changes>" and then push it to Heroku with git push heroku master where it will automatically build and run the server.