This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-04-11
Channels
- # aws (6)
- # beginners (167)
- # cider (41)
- # cljs-dev (6)
- # cljsrn (3)
- # clojure (399)
- # clojure-dusseldorf (1)
- # clojure-nl (2)
- # clojure-spec (3)
- # clojure-uk (47)
- # clojurescript (16)
- # core-async (8)
- # cursive (56)
- # datomic (14)
- # devcards (1)
- # docs (2)
- # duct (2)
- # editors (3)
- # emacs (3)
- # fulcro (178)
- # graphql (10)
- # off-topic (107)
- # onyx (7)
- # pedestal (21)
- # planck (13)
- # re-frame (58)
- # reagent (76)
- # ring-swagger (3)
- # shadow-cljs (85)
- # slack-help (2)
- # sql (1)
- # tools-deps (11)
- # uncomplicate (5)
- # vim (24)
- # yada (4)
@piotrek perhaps this: http://book.fulcrologic.com/#_the_function_as_a_child_pattern
Unfortunately I think this is related to https://reactpatterns.com/#function-as-children, not https://reactpatterns.com/#higher-order-component. The former works with actual component instances and the latter is wrapping component classes, not instances. Maybe I need to write Fulco version of the GoogleApiWrapper…
HOC is just function composition, so if you pass a component in as a prop, you’re essentially apssing in a function…and in that case if you try to use a fulcro component you will have the binding problem that that function solves.
I’m sorry if I misunderstood - do you mean that I should use prim/with-parent-context in my ui-my-map? (https://github.com/pbzdyl/fulcro-google-maps-react-issue/blob/master/src/main/nes/ui/components.cljc#L46-L48)
I don’t know the code, so it is a guess on my part. with-parent-context
takes a parent component, so your ui-my-map
would need to become a function that gets passed this
from the calling component.
actually, you’re not using fulcro components inside of the thing, are you? If it doesn’t have children, then I’m leading you down a bad path 😕
Ah, I see someone else helped you. Sorry, I was a bit busy and was throwing a guess at you without looking very deeply
Actually, someone else helped me with something else 🙂 I didn’t know how to use GoogleAPIWrapper.
Now I’m still stuck as the props are not passed from component using ui-my-map to MyMap component wrapped with GoogleApiWrapper produced component
I tried it with with-parent-context
but props are still not passed to MyMap component: https://github.com/pbzdyl/fulcro-google-maps-react-issue/blob/master/src/main/nes/ui/components.cljc#L46-L51
Ah, I see. Your factory for MyMap is expecting CLJ Fulcro props, but the Maps API is a JS component…so it will send you raw js props
I’m sorry but as I am still learning (and I’m coming from backend development) and I don’t know all the internals in React yet
so, add a normal fulcro factory for MyMap, and then wrap a call to that in a conversion function…then use that conversion function instead of MyMap and it should work:
(def ui-map (prim/factory MyMap))
(defn my-map-wrapper [js-props]
(ui-map (js->clj js-props)))
If you’re going to do interop things, you’re going to need to learn a bit more about the ecosystem…I can’t isolate you from those kinds of details 🙂
I knew it wouldn’t be easy when I read in React docs about higher order components that it’s advanced topic 😉
you have to pass js props to js libraries: https://github.com/pbzdyl/fulcro-google-maps-react-issue/blob/master/src/main/nes/ui/components.cljc#L32
Yes, gmaps contains my wrapper fns for React components from the js library and they are defined using factory-apply
So before applying your suggestions (using a fn as a component and have that fn converting js to clj props) I had my map being rendered but it wasn’t getting any props
Let me commit the new version - unfortunately with the new version the map is not loaded and only Loading placeholder is displayed
This: ∅MyMap Props: {"children" ([]), "loaded" true, "google" {"maps" {…}}} Lat null Lon null
I just put a static map {:lat 37.778519 :lon -122.405640} to ui-my-map-wrapped and I got the props
I think you possibly have some refresh issues…the conversion from clj to js and back again will lose metadata
I fixed it and now the component gets the data but props contain string “lat” and “lon” keys - I fixed it by adding :keywordize-keys true to js->clj
are you seeing a refresh issue???…you don’t have mutations, so I’m not sure why you would (yet)
but wait….the HOC should pass your data through unchanged…so I think my suggestion of the wrapper is not needed.
The GoogleWrapperApi adds logic to trigger gmaps js load. So it first displays Loading placeholder and once the gmap api is loaded and initialised it replaces the placeholder with MyMap component
Now I have this:
(def ui-my-map-wrapped
(let [HOC (GoogleApiWrapper #js {:apiKey "AIzaSyDAiFHA9fwVjW83jUFjgL43D_KP9EFcIfE"}) ;; HOC is a fn: ComponentClass -> WrappedComponentClass
WrappedMyMap (HOC ui-my-map)] ;; WrappedMyMap is a component class that wraps MyMap inside with some added logic for Google API initialization
(utils/factory-apply WrappedMyMap)))
so, depending on what the HOC component is really doing (it should just be proxying through the original props), your factory apply for it should not do a clj->js conversion
and I’m getting:
warning.js:34 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of `d`.
in d (created by nes.ui.components/Stop)
in div (created by f)
in f (created by nes.ui.components/Stop)
in div (created by b)
in b (created by nes.ui.components/Stop)
in nes.ui.components/Stop (created by fulcro.client.cards/ui_23666)
in fulcro.client.cards/ui_23666
I’d put the CLJ props under a key like “cljprops”, and ensure that doesn’t get converted to js…then use the glue to pull it out unmolested
I think that maybe it would be much easier to just create my own Fulcro version of GoogleApiWrapper 🙂
your goal is simply to pass through the unmolested CLJ props through the HOC. Your factory-apply defaults to a recursive conversion of the props.
https://github.com/pbzdyl/fulcro-google-maps-react-issue/blob/master/src/main/nes/ui/utils.cljc#L18
so if you instead had a passthrogh factory for HOC, you’d say something like `#js {“fulcroprops” props}
that would get rid of the warning, and then you can use the glue to pull them back out
Yes, but the initial render will show just loading placeholder (and it will trigger GoogleApiWrapper to load gmaps script)
OH…wait a sec…perhaps the HOC is trying to tack in API data in props somehow? Are you supposed to pass something through to the children?
You should contribute a blog post on integrating with HOC and Fulcro…I’d throw it up on the website 🙂
As a generalization: You could write a function that can do all of that for you. Use goog.object/clone
to clone the props you get, tack in the fulcro props under a key like “fulcroprops” with gobj/add
(react props are read-only so you have to clone them to do that)…it would just be a function that takes a Fulcro component and returns a function that can be used in an HOC
as long as your “made-up” key is not prone to collision, it should then be generally reusable. If you write it, I’d love to have a contrib. perhaps where I’ve got other react utils
I don’t have a blog but I can come up with reusable code for working with HOC and provide some short doc in readme - then we could adapt it to the book or in other way
Hello @tony.kay. I have create a gist covering the HOC topic: https://gist.github.com/pbzdyl/064272bece09cb3464b18d04f7246f50. I will add a reusable factory for working with HOCs later today or during the weekend. Any suggestions/comments are welcome!
Could you open an issue on fulcro github and add a link to it? I don’t have time to do it right now, and Slack history will lose it quickly.
Been playing with form support today, I got it all working decently, but one thing did confuse me.
(fs/entity->pristine* [:phone/by-id id])))))
in http://book.fulcrologic.com/#_selecting_an_entity_for_edit
This is used in the abort, but also in the submit. I don't think that's an error as the comment above that line is seems to acknowledge a difference. And it could be that since a remote + refresh happens the form should update after a successful remote push. But I can't get that to happen. It might be my reads though, as my defquery-entity
does not get hit. Later I noticed that it's surely not a mistake that the submit also requires the pristine->entity*
to get called again as the abort
breaks if I don't
Additional tiny comment that I expected to be able to add-form-config* on a load
. But I could make it work fine without, and that might add overhead/conflate things.I included a manual (df/refresh! this)
in the callback after the transact!
and now the update, abort work and my defquery-entity gets called. Still wonder if the (refresh [env] [[:thing/by-id 42]])
should have been enough.
@bbss :refresh
is about attributes, I'm not sure if idents work there, but AKAIK refresh uses the attribute index to find components and refresh those, idents are not there
@wilkerlucio I see, passing attribute keys of the this/component
passed to transact or of the root does not seem to refresh those either though.
Hi all, I’m working on an existing application that is written in untangled (and om). Is there a guide for upgrading to Fulcro?
it has been so long, that I deleted it from the repository…but it is on the older tagged versions 🙂
actually, you might use this version, in case something evolved…https://github.com/fulcrologic/fulcro/blob/2.4.3/README-fulcro-2.0.adoc
If you have custom networking, that API changed slightly (the signature of the start method), but you might also consider porting to the newer fulcro-http-remote
in networking which allows you to customize some things just via middleware.
If you go all the way to 2.5+, you get to remove all of those #js
and dom props nils as well 🙂
there are some minor differences in how the 2.5 dom behaves, so isolate problems by doing them seperately
mainly it’s just renaming namespace usages. defui
still works the same as it did. Oh, InitialState moved into primitives as well, so some of your protocols will have moved.
I mean, you already did an optimistic update, so the UI should already be correct. What is there to refresh?
By calling refresh!
you’re asking for a remote query to run…that is not what a mutation’s refresh is about.
refresh!
is a function the runs a load. refresh
(the list in a mutation) is the list of things that changed in the optimistic update that are not in the subtree that ran the tx (it is for UI refresh only of alternate UI not in scope of the transaction).
Also, you really should not use refresh!
from within a mutation or a post-mutation…if you need the server to give you back an update of the entity, I’d recommend using returning
on your commit’s remote instead.
@tony.kay it looks like we are on navis/untangled-client "0.6.1"
and org.omcljs/om "1.0.0-alpha47"
- would your links still apply?
fulcro.server
and fulcro.easy-server
…just look for the functions that go missing in one of those two
When you move to 2.5+ the server stuff has dynamic dependencies, so you’ll have to add things like ring to your own project file
and i18n has improved in a way that requires a few fixes (as of 2.4.3, I think)…if you use it, read https://github.com/fulcrologic/fulcro/blob/develop/README-porting-i18n.adoc
Mostly API the same in UI, and actually makes things a lot easier (no more code splitting).
@tony.kay so is there a separate fulcro server dep/package or its namespaces and packaged with everything else?
[fulcro.client.dom :as dom]
should (obviously) be able to be used in a cljc file (because it is a .cljc itself). When I do I get "No such var: fulcro.client.dom/macro-create-element".
it’s only covred in the localized dom, but you need that sort of thing in your own cljc file
I’d love a patch to the book if you feel like it..maybe in the early parts of http://book.fulcrologic.com/#_component_rendering
Yes this works: #?(:clj [fulcro.client.dom-server :as dom] :cljs [fulcro.client.dom :as dom])
. Yes you can use all the 'missing #js' new dom stuff regardless of whether you are using any of the localized css. That is not really clear in the book. It's the least I can do...
I want to deploy a project created with the lein template to Heroku. I have credential secrets that thus far have lived in defaults.edn. Should I lift those into environmental variables, or is there an easy way to get a configuration file into a Heroku build after the fact?