5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

一人LiveViewAdvent Calendar 2021

Day 7

Phoenixで作るGPS Logging System 7 GoogleMapの表示

Last updated at Posted at 2021-12-16

ひとりLiveView Advent Calendar の7日目の記事です

この記事はElixir Conf US 2021発表したシステムの構築と関連技術の解説を目的とした記事です

GPS Loggerアプリから送信されたデータを表示するためにGoogleMapAPIを使用してLiveView上にGoogleMapを表示させます

今回は以下の3つを実装します

  • npmでライブラリインストール
  • JS HookでGoogleMapApiを読み込む
  • LiveView上で表示

npm ライブラリの追加

phoenix 1.6になってからwebpackからesbuildに移行してnpm非依存になりましたが
npm installすれば普通に使用できます

assetsに移動してGoogleMap loaderを追加します

cd assets
npm install @googlemaps/js-api-loader
cd ..

#JS HookでGoogleMapの表示
LiveViewにはJS Hookというものがあって、
backendとfrontendでデータをやり取りする場合は APIを通すか、それ用のライブラリをインストールする必要があり、面倒くさいものですが

  • JS側のhandleEvent, pushEvent
  • Elixir側のpushEvent

という関数を使って相互に JSONとMapのやり取りができます

mount時にGoogleMapを表示するようにします
実際に試す場合は GoogleMapAPIのキーを取得してください

assets/js/hooks.js
import { Loader } from "@googlemaps/js-api-loader";
let Hooks = {}
const apiKey = "your api key"
Hooks.Map = {
  mounted() {
    const loader = new Loader({
      apiKey: apiKey,
      version: "weekly",
    })

    loader.load().then(() => {
      const map = new googlemaps.Map(
        document.getElementById("map"),
        {
          center: { lat: 33.30639, lng: 130.41806 },
          zoom: 9
        }
      );
      window.map = map;
    })
  }
}

export default Hooks;

mount()関数が LiveView のmount後に実行されるので、
初期データの作成他に待ち受けるイベントを記述したりします

hooksファイルができたら,liveSocketのoptionsの箇所に hooks: Hooks で追加します

assets/js/app.js
...
import Hooks from "./hooks"
let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks, params: {_csrf_token: csrfToken}})
...

Hooksを読み込む際の注意点ですが
Hooksを読み込むタグにIDをつけて読み込むモジュールをphx-hook="Map"で指定します
また、canvasなどタグ内が頻繁に変化する箇所はLiveViewが変更を検知して再レンダリングされるので、
LiveViewが変更しないようにphx-update="ignore"を指定します

lib/live_logger_web/live/map_live/show.html.heex
<h1>Show Map</h1>

<%= if @live_action in [:edit] do %>
  <%= live_modal LiveLoggerWeb.MapLive.FormComponent,
    id: @map.id,
    title: @page_title,
    action: @live_action,
    map: @map,
    return_to: Routes.map_show_path(@socket, :show, @map) %>
<% end %>

<ul>
  <li>
    <strong>Name:</strong>
    <%= @map.name %>
  </li>
  <li>
    <strong>Description:</strong>
    <%= @map.description %>
  </li>
</ul>
<!--- 以下追加 --->
<div id="googleMap" phx-update="ignore" phx-hook="Map">
  <div id="map"></div>
</div>

<span><%= live_patch "Edit", to: Routes.map_show_path(@socket, :edit, @map), class: "button" %></span> |
<span><%= live_redirect "Back", to: Routes.map_index_path(@socket, :index) %></span>

google mapの表示領域の高さを600pxに指定します。
heightを指定しないとmapが表示されないので忘れないようにしましょう

assets/css/app.css
...
#map{
  height: 600px
}

GoogleMapが表示されました!

スクリーンショット 2021-12-17 0.46.21.png

最後に

LiveView上にGoogleMapを表示することができました!
本記事は以上になります

次はBulmaを使用してスタイリングをしていきます

code

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?