Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jhchabran
Last active February 13, 2019 12:00
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhchabran/e09883c3bc1b703a224d to your computer and use it in GitHub Desktop.
Save jhchabran/e09883c3bc1b703a224d to your computer and use it in GitHub Desktop.
Google Map component, with reagent and reframe. Questions asked on Clojurians #re-frame's channel.
; Following code is WRONG, see comments for details.
(defn google-map []
(let [pos (subscribe [:current-position])]
(reagent/create-class
{:reagent-render
(fn []
[:div
[:h4 "Map"]
[:div#map-canvas {:style {:height "400px"}}]])
:component-did-mount
(fn []
(let [map-canvas (.getElementById js/document "map-canvas")
map-options (clj->js {"zoom" 9})
gmap (js/google.maps.Map. map-canvas map-options)
marker (js/google.maps.Marker. (clj->js {:map gmap :title "Drone"}))]
(reagent.ratom/run!
(let [latlng (js/google.maps.LatLng. (:latitude @pos) (:longitude @pos))]
(.setPosition marker latlng)
(.panTo gmap latlng)))))})))
; Another attempt, using props and lifecycle to udpate marker position
(defn gmap-component []
(let [gmap (atom nil)
options (clj->js {"zoom" 9})
update (fn [comp]
(let [{:keys [latitude longitude]} (reagent/props comp)
latlng (js/google.maps.LatLng. latitude longitude)]
(.setPosition (:marker @gmap) latlng)
(.panTo (:map @gmap) latlng)))]
(reagent/create-class
{:reagent-render (fn []
[:div
[:h4 "Map"]
[:div#map-canvas {:style {:height "400px"}}]])
:component-did-mount (fn [comp]
(let [canvas (.getElementById js/document "map-canvas")
gm (js/google.maps.Map. canvas options)
marker (js/google.maps.Marker. (clj->js {:map gm :title "Drone"}))]
(reset! gmap {:map gm :marker marker}))
(update comp))
:component-did-update update
:display-name "gmap-component"})))
(defn gmap-wrapper []
(let [pos (subscribe [:current-position])]
(fn []
[gmap-component @pos])))
@jhchabran
Copy link
Author

So far and according the feedback I got, 2 and 3 are correct. 4is probably correct anyway. Still waiting for some validations on 1 :)

@jhchabran
Copy link
Author

I feel like if's correct enough it would be a nice addition to https://github.com/reagent-project/reagent-cookbook/tree/master/recipes/google-maps given the re-frame part is replaced with a ratom.

@jhchabran
Copy link
Author

4 was just a consequence of putting the run! at the wrong place, initial comment updated accordingly.
I don't think it was wrong per se but it's now unnecessary once run! is called where it should be.

@jhchabran
Copy link
Author

⚠️ Got some feedback from Re-Frame's author, using run! is very wrong here (if following re-frame approach).

@mike-thompson-day8
Copy link

mike-thompson-day8 commented Aug 6, 2015

@jhchabran
Copy link
Author

@jhchabran
Copy link
Author

It should use will-receive-props for update as we don't interact with the dom as opposed to http://nils-blum-oeste.net/clojurescripts-reagent-using-props-in-lifecycle-hooks/ example.

@raymcdermott
Copy link

When using this I have found it important to run :component-will-unmount to dispose of the stateful component

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment