Hello, I am trying to use helix to display a leaflet map but am not able to get it to display... it would be handy if the docs showed a few different examples using use-state and use-effect :once to display the initial map... can somebody who knows how to use helix send me a working code example of how to use form 3 components, thanks peeps
I’m not sure what you mean by a form 3 component?
If you know the JS you’d write, it’s not hard to do a mechanical translation into helix. I can help with that
var map = L.map('map', { center: [51.505, -0.09], zoom: 13 });
thats the code that displays the map, 'map' after the opening brackets represents the html element id it will me displayed in
I'll send the link to leaflets website it may make more sense to you: https://leafletjs.com/reference-1.7.1.html
can you show me what you’ve tried so far?
sure...
(defnc customer-map [] (use-effect :once (fn [] (L.map "map" (clj->js {:center default-center :zoom 9 :layers [(L.tileLayer osm-url copy-osm)] })))))
The use-effect macro wraps everything you pass in after the dependencies (in this case :once) in a function for you
So right now, the function you’re passing in is being returned by the function that use-effect creates to wrap it, and not running
Well, it runs on unmount 😅
I don't understand how it all works...
Thanks for taking the time to help me by the way
If you remove the function you’re wrapping (L.map ,,,) in it will get you closer
how will the map be displayed then?
It will run when the effect gets run
but I have that code nowhere else
here is an example I found written in js, using hooks;
import React from 'react';
import L from 'leaflet';
function Map() {
React.useEffect(() => {
// create map
L.map('map', {
center: [49.8419, 24.0315],
zoom: 16,
layers: [
L.tileLayer('http://{s}.<http://tile.osm.org/{z}/{x}/{y}.png|tile.osm.org/{z}/{x}/{y}.png>', {
attribution:
'&copy; <a href="<http://osm.org/copyright>">OpenStreetMap</a> contributors'
}),
]
});
}, []);
return <div id="map"></div>
}
export default Map;
how would I convert that to use helix?
I mean write it like this:
(defnc customer-map []
(use-effect
:once
(L.map "map" (clj->js {:center default-center
:zoom 9
:layers [(L.tileLayer osm-url copy-osm)]})))
,,,)
without the (fn [] ,,,)
wrapping the body of the effect
the docs on hooks document the differences between React's useEffect
and helix's use-effect
: https://cljdoc.org/d/lilactown/helix/0.0.12/doc/hooks#doing-side-effects
words are hard! and this is a confusing bit of syntactical difference between React and helix.
helix's use-effect
automatically wraps whatever you pass into it in a (fn [] ,,,)
, so wrapping it again, isn't doing what you want here
I tried it both ways, I am going to give it another go now...
e.g.:
(react/useEffect
function () {
console.log("hi");
}, [])
is the same as
(use-effect
:once
(js/console.log "hi"))
there could be another error, but this way we'll definitely be running that effect on mount
this is the error I get
react-dom.development.js:23276 Uncaught #error {:message "Props received were … onent as a function."Props received were a map. This probably means you're calling your component as a function., :data {:props nil}} commitRootImpl @ react-dom.development.js:23276 exports.unstable_runWithPriority @ scheduler.development.js:647 runWithPriority$1 @ react-dom.development.js:11277 commitRoot @ react-dom.development.js:22991 performSyncWorkOnRoot @ react-dom.development.js:22330 scheduleUpdateOnFiber @ react-dom.development.js:21882 updateContainer @ react-dom.development.js:25483 (anonymous) @ react-dom.development.js:26022 unbatchedUpdates @ react-dom.development.js:22432 legacyRenderSubtreeIntoContainer @ react-dom.development.js:26021 exports.render @ react-dom.development.js:26104 reagent$dom$render_comp @ dom.cljs:18 (anonymous) @ dom.cljs:48 (anonymous) @ dom.cljs:38 app$core$start @ core.cljs:82 app$core$init @ core.cljs:94 (anonymous) @ shadow.module.main.append.js:2
Props received were a map. This probably means you're calling your component as a function.
it sounds like you might be calling your component like (customer-map {:foo "bar"})
?
I'm not
okay. I see reagent in the stack trace
how are you trying to render the helix component from reagent?
as a hicup component
but I've tried it with and without square brackets and normal brackets
I can help with that. Before that, though, is there a particular reason you're using reagent and helix together?
my app is using re-frame so I need reagent
okay. when you want to render a helix component inside a reagent one, the easiest way to do it is to use helix's $
macro
e.g.:
(defn app
[:div
[:h1 "My App!"]
[menu options]
[:div
($ customer-map)]])
excellent, thank you I shall try that now, thank you so much 🙂
sure thing! and here's a link to the docs on $
: https://github.com/lilactown/helix/blob/master/docs/creating-elements.md
Thank you so much, I have it working now
Have a great day and keep up the good work