This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-12-19
Channels
- # adventofcode (82)
- # beginners (70)
- # boot (34)
- # boot-dev (13)
- # cider (45)
- # clara (4)
- # cljs-dev (3)
- # cljsrn (2)
- # clojure (91)
- # clojure-art (8)
- # clojure-czech (1)
- # clojure-dusseldorf (3)
- # clojure-france (11)
- # clojure-germany (1)
- # clojure-greece (39)
- # clojure-hamburg (1)
- # clojure-italy (24)
- # clojure-norway (2)
- # clojure-spec (7)
- # clojure-uk (31)
- # clojurescript (56)
- # core-async (7)
- # cursive (8)
- # data-science (10)
- # datomic (41)
- # duct (7)
- # emacs (1)
- # events (1)
- # fulcro (83)
- # graphql (6)
- # klipse (1)
- # leiningen (28)
- # lumo (67)
- # off-topic (14)
- # om (9)
- # onyx (3)
- # perun (4)
- # re-frame (22)
- # reagent (11)
- # ring-swagger (2)
- # rum (1)
- # specter (46)
- # sql (13)
- # uncomplicate (17)
- # unrepl (114)
I’m looking at targeted data loads in http://fulcro.fulcrologic.com/guide.html#!/fulcro_devguide.H05_Basic_Loading and I do not understand the part “If you’ve followed our earlier recommendations, then your applications UI is normalized as well,“. What earlier recommendations this refers to? I’ve seen docs about normalizing data, but not avout UI. Have I missed that? And does this apply when app uses UI routing, esp. with multiple routers? I somehow do not see how a component can use targeted load without precisely knowing where in the UI tree it it is located…
@bbktsk So, you read about normalization, so you should know that every possible thing in your database should be in a table, especially anything from a server or that changes.
I.e. all of your components have an ident, which means they are at an assoc-in path like [:table/by-id 3]
, and any field is just one level deeper [:person/by-id 3 :person/name]
So, targeting never needs to go deeper than that. The auto-normalization takes care of the graph of incoming data (and puts it in tables), so the top-level edge can either go into root, or go into a field.
Channel: Fulcro 2.0.0-RC3 on clojars. Not much changed in code, but the Getting Started Guide was updated.
@bbktsk UI routing is a separate topic from load targeting. They are unrelated. Since everything is normalized the structure of your “pure UI” (e.g. routing, layout, etc) isn’t even involved. The good part: You’re almost there! This is the crux and beauty of the system. Keep looking at it. It’s quite simple…just different enough that it takes most people a few tries to grok it.
If I want to load a list of people into person list 4, I might do this:
(df/load :friends Person {:target [:person-list/by-id 4 :person-list/people])
This assumes you’ve got the UI components normalizing into the tables implied. See the Getting Started guide for this exact example in detail. Also, try the YouTube video series. Some of the alternate materials might make it more clear. I happen to think the video guide is the easiest to get started with.
Need help, about semantic-ui-wrapper, I want to use dimmer, the code in http://react.semantic-ui.com:
<Dimmer.Dimmable as={Segment} blurring dimmed={active}>
<Dimmer active={active} onClickOutside={this.handleHide} />
<p>
<Image src='/assets/images/wireframe/short-paragraph.png' />
</p>
<p>
<Image src='/assets/images/wireframe/short-paragraph.png' />
</p>
</Dimmer.Dimmable>
my code:
(f/ui-dimmer-dimmable #js {:as (f/ui-segment) :blurring true :dimmed dimmed}
(f/ui-dimmer #js {:active dimmed
:onClickOutside #(prim/transact! this `[(m/dimmer-dimmed {})])}
(dom/p nil "aaaaaaaaaaaaa")
(dom/p nil "bbbbbbbbbbbbbb")))
but got errors in the console in Chrome:
Warning: Failed prop type: Invalid prop `as` supplied to `a`.
in a (created by qsweb.A0-UI-Components/Edit-Dimmer)
in qsweb.A0-UI-Components/Edit-Dimmer
the :as (f/ui-segment)
case the errors.@tpliliang I’ll accept PRs on that, but the wrappers just push it through to the underlying library.
their docs seem to imply that it should be a class? Perhaps Segment is the right thing? Then again, perhaps a factory function, which would be f/ui-segment
without the parens, as I said above.
Hi all, is there an idiomatic way to handle network requests that should be debounced? For example, the google autocomplete API returns suggestions for places as you type. This should probably be in a remote, but it probably shouldn’t trigger with every keystroke.
@levitanong https://github.com/fulcrologic/fulcro/blob/460c98defce8681324336bdcd7c5fefc0e01a4e5/src/demos/cards/autocomplete.cljc#L64
@tpliliang thank you!
@tony.kay Need help, I want to test websockets client in devcards. So I use:
(defcard-fulcro card1
#_(df/load app :all-ids All-Ids)
All-Ids
{}
{:inspect-data true
:fulcro {:networking cs-net
:started-callback (fn [app]
(wn/install-push-handlers cs-net app)
(df/load app :all-ids All-Ids))}}
)
but the client db cannot be normalized, but if I use ui component's initial-state instead, the normalizing work.
I tried js/console.log in ui component and found if use websockets client, there are 4 times console prints, but only print 1 time when using initial-state. I guess there may be a few different stages for ui render and db normalize, At the db normalize stage, the app cannot get the query result from remote server for using :started-callback
.
How can I do? and How to print the normalized db in the console in the Chorme?@tpliliang Hm. sounds like we need symbols for those?
On your second thing: what do you mean client DB cannot be normalized? Normalization is an action that happens at specific times, and is always tied to UI queries and idents.
If you want to see the normalized db…you’ve already got it in the card (inspect true). You can also use Fulcro Inspect. From the REPL you can access it from the app saved in an atom. The defcard-fulcro
docs tell you how to find the card’s app. The GettingStarted guide shows examples of dumping the DB from a REPL.
Regarding normalization: Cards supply an atom, so if you put data in the card’s data map, it must start out hand normalized. If you leave it empty, the card uses initial state and auto-normalizes.
The rules internally allow for hand-built databases or auto-normalized. The rules are: 1. If you supply no (or empty) state, then UI initial state is pulled (as a tree) and normalized into your db 2. If you supply a non-empty MAP, it will use the UI query to normalize it into an internal atom holding a map 3. If you supply an ATOM (which cards do, even though you write what you want in it as a map), then it takes it as the db state you want (no auto-normalization)
That’s why all of my examples show that first map argument as empty. You can use it to make a database, but you almost always want UI initial state.
ALL: New EAP build of Cursive just dropped!!!! This version contains direct support for Fulcro’s special bits (defsc, defmutation, etc.)!
No more yellow highlighting around things like action
sections of defmutation
! It fully understands those macros and does proper indexing and refactoring on them now.
does it? I did updated today and I didn't see the defmutation
been recognized, had you tested that?
I just wanna make sure, because if it is something is broken on my end
I added this to #announcements with a thanks to Colin…react there to let him know we appreciate it!
Fulcro 2.0.0-RC4-SNAPSHOT pushed to clojars. Has support for refs in fallbacks (as ::prim/ref in fallback parameters). See http://localhost:8081/demos.html#!/cards.server_error_handling/error-handling when running full-stack demos locally…or the source here: https://github.com/fulcrologic/fulcro/blob/d94ebf21ab5fe3e0a8e4f04edc27bfbf54d4297b/src/demos/cards/server_error_handling.cljc#L35
yay!! 😄
@tony.kay I am going through the forms-2.0 sample card with phone book. What I have noticed is that the edits done in the form modifies the entity data directly in the :phone/by-id
which is not optimal if the form for editing the entity and a table displaying the entity are visible at the same time (which might be quite often). Is it an intended design goal or is it just a simplistic demo that doesn’t work on a copy of the entity data?
@piotrek It is the intended design to work on the active data, but keep a checkpoint for reverting. This is because nested forms won’t work right otherwise.
and it doesn’t really matter…you have two copies of data. old and new. preference aside, it isn’t appreciably different
Oh, you’re saying you don’t want the user to see the changes “in place” in the sibling UI
It does however forces you to design the UI in a specific way (e.g. don’t show the list of entities and the entity edit form so they are both visible)
I just spliced the (if (contains? phone ::phone-number) ...)
sexp so I have both the phone numbers list and the edit form both visible
Choices: - Don’t use forms.cljc. Roll your own. It isn’t that hard. It’s just data. But, you will have to invent your own caching scheme - Change your UI design - Adopt the philosophy that things are optimistic, and that the change should be visible…Undo is right there, “save to server” is deferred
The nesting of entities in forms is what dictated the choice. I want you to be able to render the form data. When you have sub-forms you need to be able to write generic mutations that can manipualte state (e.g. add phone number), and you want to write the render code identically to what you’re used to. Try to implement that when the “edited data” is all hidden, and you can’t
I would personally design the UI to not be showing the “table” version of it while editing it.
(or at least rebase forms-2.0 branch on the latest changes so it’s possible to get an up to date local build with forms 2.0?)
eventually. Did you play with it at all? It would be simple to pull the code into your own build and try it out.
I am just playing it directly in the fulcro repo right now but I was thinking about trying it in my simple app where I use the latest 2.0 RC version
If you get it all tuned up, maybe that will get it into production faster in Fulcro 🙂
I wouldn’t count on it - I am a very new to all this so I am doing only some basic stuff for now 🙂
FWIW I've been trying to come to grips with Fulcro specifically for it's application to a traditional CRUD web project
I'm translating a clojure REST API & web 1.0 application to an entirely new implementation using Datomic & an SPA using Fulcro
As an aside, I've almost 100% agreed with everything Fulcro does except (and this is going to seem super finicky) calling the fulcro base namespace 'prim' - it's too much like the English word 'prim' and I would be much happier with an acronym like 'fcp' or similar in the examples (which is what I've been using for my own code in any case)
I've wound up doing my own customised stuff as I can make more assumptions for my use case than what's in the fulcro mainline now
TBH the conventions fulcro brings in terms of data normalisation are far, far more powerful than the forms stuff IMHO
So, loving fulcro for that reason, though the forms stuff as is (while it was the initial hook) isn't why I'm sticking with the learning curve etc
Actually that isn’t an unexpected answer. It’s why I’m wanting to simplify the forms support to just the core state management helpers
yep. I've a different approach to CSS too (I'm a big fan of tachyons and atomic CSS) so I've been combining that with my own form needs to good effect
and routing, I think there's a good story to tell there too, though it's hard to dissociate what I'm doing with what a general case might look like
but arriving at the underlying principles of form data gathering, submission & display would be a great outcome
oh hey, if you were available for code review that would be a service I could totally pay you to do btw
@oliver.mooney I do Fulcro consulting through http://www.fulcrologic.com. Be glad to help.