Let’s make an ambitious map (part 2)

Matt Gardner
NYC Planning Tech
Published in
3 min readJul 25, 2018

This is part of a series of posts I’m doing on creating ambitious maps.

Last time I covered a lot of the basics for our ambitious map. We got an EmberJS app up and running, fetched some data, and put a map on the screen. Now let’s add a bit of styling to the map.

First, run ember s in your project folder. This will be the same folder we used last time. Recall how boring the map styling was? Let’s fix that by opening the application.hbs file and taking a look:

There’s a lot going on here, especially for the uninitiated. We’re introducing EmberJS beginners to an unfamiliar templating syntax. Let’s refactor and move some of this into a more logical place. Where?

Our First Component

Components are configurable, composable, reusable, self-contained pieces of an interface. They help organize application responsibilities into logical groups.

Start by running ember g component bike-lane-map. This is going to create 3 files:

installing component
create app/components/bike-lane-map.js
create app/templates/components/bike-lane-map.hbs
installing component-test
create tests/integration/components/bike-lane-map-test.js

Open templates/components/bike-lane-map.hbs and move the {{mapbox-gl}} component (lines 3–9) from application.hbs into it.

Invoke and pass down the `model` property into the bike-lane-map component
Our bike lane map is its own component

Saving the file will create a blank map. That’s because we haven’t passed down the model data into the component. We can pass that data down by setting a property on the component to the model data, {{bike-lane-map data=model}}. We will also have to update the template for bike-lane-map by changing the model value to data.

Let’s continue the refactor. We’ve encapsulated our map into its own component so that we can more easily organize its data, configuration, and behavior inside a single entity. Since we don’t want to create unnecessary confusion, let’s get rid of(hash) helpers by making new component properties for them instead. We’ll also move the contents of the hash helpers into bike-lane-map.js:

Now our component template is responsible only for passing properties. There’s nothing wrong with using hash and array helpers in templates, but I like to think the code is easier to read for others if its in JavaScript. We also keep data and configuration strictly in the JavaScript file.

However, there’s something new going on in bike-lane-map.js — we wrapped the data object in something called a computed property. MapboxGL expects GeoJSON data to be nested in an object that describes its type. A computed property allows us to call upon functions as properties that are recomputed each time they’re called. Because we set data as the first argument of computed, the computed property will always stay in sync with any dependent changes that come down.

Moving on to styling, let’s color code the lines based on the type of bike lane, using MapboxGL’s Style Specification as a guide:

We now have something to work with:

We’ve organized the map into a component and added some styling. This still isn’t very useful — there’s no interaction, filtering, hovering, or highlighting. In a later post, I’ll walk through how to add these features and more.

--

--