This is a simple guide to getting up and running with Google Maps in your Ember CLI project. For reference, the code & procedure has been adapted from a now-defunct blog post by Jan Votava. Thanks for the great start, Jan!

Ember CLI is the newest way of getting started with Ember apps. It breaks the traditional method of creating an Ember app into command-line arguments & lots of modular bits and pieces. This creates a much more scalable and team-friendly flow while building Ember apps, but comes with an added set of challenges.

In this post, we'll walk through adding a Google Maps component to our app using Ember CLI. If it looks scary at first, that's okay: just take a deep breath, put your hands on the home row (or wherever - I'm not a cop) and start following along. You'll be surprised how easy it is to implement.

Setup & Expectations

For this tutorial, we'll work from an unmodified Ember app created with ember new. All the commands we use should be run from your application's root folder - that's the folder containing app/, vendor/ and Brocfile.js. We'll work to create a VERY simple page containing only a header and a map, as pictured below:

Our map we hope

If you'd like to jump directly to code, you can follow along with this tutorial at this Github repo.

I'm working on a Mac laptop running OSX 10.10 (Yosemite) and using the default shell (bash). If you're on a different platform or are using a custom shell, some of the commands may differ slightly. I'll assume anyone in that situation can debug themselves, but if you need a hand please reach out on Twitter!

Importing the Google Maps library

We'll be using the Google Maps Javascript API (v3) for integration here. Google's examples provide this library by way of a script tag in the head of your HTML. This can be emulated in Ember by adding

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js" ></script>

to your app/Index.html, but that's neither modular nor does it adhere to the "Ember way".

Instead, we'll add Google's API by importing it into our app using Ember CLI's tools. This will take a couple extra steps but will make things much more modular.

First, we need to download a local copy of the API. The quickest way to do this is with cURL, a simple command line utility used for transferring files. Enter the following command to download the Google library and add it to your "vendor" folder:

curl -o vendor/gmaps.js https://maps.googleapis.com/maps/api/js

After a moment, you can use ls vendor to make sure the file gmaps.js has been created. Once you've verified this, use your text editor of choice to open Brocfile.js. Near the bottom of this file, just above module.exports = app.toTree();, add this line of code:

app.import('vendor/gmaps.js');

This will let the build pipeline know it needs to bring the Google Maps API in while updating your app. Ember CLI will bundle the contents of gmaps.js into the file dist/assets/vendor.js each time it builds from now on.

A note on API Keys - Google recommends using your Google Developer API key when making requests to the Maps API. It's not strictly requred, but if you'd like to incorporate this feature so you can manage your rate limits & allowed domains, take a look here . Once you've got an API key, you'll simply download the Maps API using this command:

curl -o vendor/gmaps.js https://maps.googleapis.com/maps/api/js?key=YOUR-KEY-HERE

Setting up our Component

Now that we've got Google connectivity, we need to create our component. Ember CLI makes this part incredibly easy - just run the following:

ember generate component google-map

You can name your component whatever you'd like, but Ember requires that you include a hyphen in the name, so give the camelCase a break on this one. We'll stick with google-map for the remainder of this tutorial. The CLI tools will take over and create both a component Javascript file & a template file.

We'll start with the component itself. Add the necessary code to your app/components/google-map.js file to make it match this:

import Ember from 'ember';

export default Ember.Component.extend({  
    var container = this.$('.map-canvas')[0];
    insertMap: function() {
        var options = {
            center: new window.google.maps.LatLng(
                this.get('latitude'),
                this.get('longitude')
            ),
            zoom: 15
        };
        new window.google.maps.Map(container, options);
    }.on('didInsertElement')
});

Now, we create a template container for our component by editing app/templates/components/google-map.hbs:

<div class="map-canvas"></div>
{{yield}}

And finally, we add a call to our shiny new Google-Maps component to our default page, app/templates/application.hbs:

<h2 id="title">My Map Component</h2>
{{google-map latitude="34.851939" longitude="-82.399752"}}

Now save everything, run ember server in your terminal, navigate your browser to localhost:4200 and....TAADAAH!

ERROR ERROR ERROR

Oh no - what's this? Console errors? Looks like it's time for some debugging....

Ember CLI Content Security configuration

Ember CLI comes budled by default with [ember-cli-content-security-policy(https://github.com/rwjblue/ember-cli-content-security-policy), an adapter to bring requests made from your app in line with the W3C Content Security Policy recommendations. This helps protect your app from unexpected connections being created, but it's very restrictive by default and blocks ALL external resources. Since the Google Maps API needs to reach out to Google, we'll need to whitelist the necessary domains.

To clear the sea of red in your console, open config/environment.js. Just below your ENV declaration, before the line if (environment === 'development') {, add the following code:

ENV.contentSecurityPolicy = {  
    'script-src': "'self' 'unsafe-eval' https://*.googleapis.com https://*.gstatic.com",
       'img-src': "'self' https://*.googleapis.com https://*.gstatic.com",
       'font-src': "'self' https://*.gstatic.com",
       'style-src': "'self' 'unsafe-inline' https://*.googleapis.com"
}

This whitelist should allow all of Google's necessary content through your makeshift firewall. Now that we've cleared our console errors, we should see our map, right? Not quite yet - one more step before our map is good to go!

Voila!

If you look through the Elements tab of your developer tools, you'll see that the map element is now rendering. Unfortunately, it's not visible on the page. This is because we never set a size for the element containing the map. We can do this with CSS. Edit the file app/styles/app.css and add this:

    .map-canvas {
        height: 500px;
        width: 500px;
    }

Now refresh your page and cross your fingers. If you have no misspellings, you should see a map similar to the following:

Our finished map

WOOHOO! WE DID IT!

Next Steps

Once you're finished strutting around your room and bragging to all your friends about your amazing new Ember skills, you'll realize this doesn't do much. The coordinates are hard-coded and there's no support for any sort of map markers or monitoring. There are very few situations in which this is more useful than a static image.

However, here's the beauty of programming - YOU'VE GOT THE POWER! Now that you know the structure of this component you can flex your Javascript muscle and build more functionality onto this base. Have fun, make mistakes and get messy - web development is a very forgiving practice!

Thanks for following along and good luck!

Problems? Suggestions? Hit me up on Twitter at @ADotMartin!