Building a rentals website

It’s time to show what we can accomplish with these tools! It seems like the most popular examples are Airbnb-like interfaces – a list of data on one side and a map visualising it on the other side. Heck, even the ember guides create a rentals website! This example showcases a large chunk of the power of this addon and how it can positively affect a developer’s productivity and the quality of the their code.

Keep in mind this is just a visual example. Let’s simulate fetching a geo-bound AJAX query from a BE server by filtering an array of random locations as you pan the map. Let’s also attach some mouseover effects!

Tip You might want to view this demo on a device with a larger screen.

View rentals example ›
Breakdown of the demo

Let’s quickly discuss what is happening in the demo. You can view the code for the entire demo in the repo, but most of the work is happening in the template.

  1. We set the center of the map and the zoom level in the first line.
  2. We then set a bunch of map options: we modify the look of the map tiles with styles, disable the scroll wheel to force the feed to scroll down instead, and mess around with the map controls to achieve a minimalist look.
  3. We use onceOnIdle and onBoundsChanged events to fetch the current map bounds. We use these bounds to filter the random array of markers on the map. This filtered array is called boundedLondonLocations. This simulates loading external data when panning or zooming the map.
  4. We use the {{each}} helper to loop over the locations and display an overlay with custom content at the given location coordinates. Inside the overlay, we render a custom, styled tooltip div, containing the price of the rental.
  5. The onMouseover and onMouseleave events modify the active property on the rental, which lets us animate the tooltip and the card in the feed. Finally, the onClick event receives the clicked rental and scrolls to its card in the feed.

<GMap
  @lat={{this.london.lat}}
  @lng={{this.london.lng}}
  @zoom={{12}}
  @styles={{this.myMapStyle}}
  @scrollwheel={{false}}
  @gestureHandling="greedy"
  @disableDefaultUI={{true}}
  @zoomControl={{true}}
  @zoomControlOptions={{g-map/hash
    position=this.google.maps.ControlPosition.TOP_LEFT}}
  @fullscreenControl={{true}}
  @onceOnIdle={{this.saveBounds}}
  @onBoundsChanged={{this.saveBounds}}
  class="ember-google-map-cover" as |map|>

  {{#each this.boundedLondonLocations as |location|}}
    <map.overlay
      @lat={{location.lat}}
      @lng={{location.lng}}
      @onClick={{fn this.scrollToListing location}}
      @onMouseover={{fn (mut location.active) true}}
      @onMouseleave={{fn (mut location.active) false}}>

      <div class="tooltip {{if location.active "active"}}">
        £{{location.price}}
      </div>

    </map.overlay>
  {{/each}}

</GMap>

Let’s learn how to test apps with maps.

Testing ›