This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-09-21
Channels
- # alda (1)
- # bangalore-clj (1)
- # beginners (7)
- # boot (88)
- # carry (2)
- # cider (8)
- # cljs-dev (60)
- # cljsjs (2)
- # cljsrn (45)
- # clojure (255)
- # clojure-belgium (5)
- # clojure-boston (1)
- # clojure-dusseldorf (3)
- # clojure-greece (49)
- # clojure-italy (10)
- # clojure-russia (30)
- # clojure-spec (78)
- # clojure-uk (11)
- # clojurebridge (1)
- # clojurescript (80)
- # cursive (14)
- # datomic (33)
- # defnpodcast (4)
- # devcards (2)
- # dirac (15)
- # editors (23)
- # emacs (5)
- # events (11)
- # funcool (1)
- # hoplon (1)
- # juxt (1)
- # luminus (2)
- # mount (7)
- # off-topic (15)
- # om (152)
- # om-next (2)
- # onyx (17)
- # parinfer (1)
- # proton (38)
- # re-frame (35)
- # reagent (110)
- # rum (3)
- # spacemacs (3)
- # specter (51)
- # test-check (2)
- # testing (5)
- # untangled (234)
Just a general question, I am kind of running into problems with the way om.next handles getting remote data. I just read some code of untangled and that makes a lot more sense to me. Is it possible to use that stuff without completely using untangled?
I mean the way it sends a mutation to load a remote field
@mitchelkuijpers not sure that anybody has tried. just looking through the code it doesn’t appear that it has any strict expectations that an untangled application is being used. you would have to set up your networking to support the data fetch api, which given the amount of time we spent getting it right, I probably wouldn’t recommend just from an effort/benefit tradeoff perspective. I’d definitely be curious to hear what others in the channel think
@mitchelkuijpers So, Untangled exists because Om next has some complexity to it that we believe has a reasonable general-purpose solution. In particular, the need to write a parser is a trade-off that Untangled believes is too costly from a general engineering perspective.
At the end of the day, what you have to do (in your parser or in your database) is transform the raw database objects into a shape that will work for your tree. In Untangled, we prefer those transforms happen on user-driven events in a direct data manipulation manner (easy to reason about, lower cost on rendering overhead, generally easier).
Loads in Om Next are always some sequence of: mutate something in app state to track that you are loading, return remote
from the parser, get/merge the data (typically over top of the place where you marked that you needed to load), etc. It's the same thing over and over, but you end up peppering that logic about in a parser.
Untangled wraps the need to do the above sequence in load-data
and load-field
. They do what you're going to have to do in Om Next...they just make it less work. They also deal with the potential problems of out-of-order completion, parallel queries for the same object (asking for different attributes), deep merge, and other issues that would normally show up in your program as bugs that would be mysterious to you.
So, I don't have much interest in supporting the use case of "what can I pick out of Untangled?" The answer is: nothing useful. The main advantage of untangled is reducing the central complexity of Om Next: removing the need for a parser and lots of networking/load logic.
There are trade-offs, and there are missing features that still need added, but we're having great success with it. The problems we've run into (and others using it commercially) have been easy to work with, or resulted in extensions to the framework.
Aha that makes sense, I'll try it out and maybe switch over then. Thank you for your detailed answer much appreciated! @tony.kay
I also gave a talk at an Unsession in Seattle that is up on YouTube that details some more rationale
https://www.youtube.com/watch?v=TU9hWTZcKy0&index=3&list=PLVi9lDx-4C_Qsgm8JC1VyMevV9DVj-dCh
I've been doing what I can to make it approachable. Lots of demands on my time, but I do understand that there is a hurdle to Om Next and Untangled. Trying to get people over the hump. This stuff really is so nice to work with. There are "easier" front-end things to get started with, but as soon as you try to do something "real" the easy goes away.
We just had our company hackday - I used untangled and I surprised myself by how amazingly fast and easy it was to work with now that I (mostly) get it.
Yeah I was coding something up last night from scratch and was just flying and giggling maniacally about my super-powers 😉
I will try it @tony.kay I have had some big problems with the way remote reads work with vanilla om.next. But it mostly solves a lot of other problems. We are moving away from re-frame to om.next and maybe untangled 🙂
@mitchelkuijpers At the very least: with Untangled you write Om Next code: you just avoid the overhead of writing a parser and a bunch of plumbing. Worst case is you abandon Untangled and write a parser...so you really have nothing to lose
Damn it.. Now I have to migrate some code
I guess you are right
And if you abandon it, well, then you "get to play" with process-roots
to fix your UI queries for your server, and implement your own remote loading scheme, etc. 😉
Is this still the case? IMPORTANT: NOT READY FOR USE. Clone TodoMVC from github as a template instead
or can I try the template?
Yeah that is exactly what I am fighting with
especially the cb
that sometimes needs a query and sometimes does not need a query
Awsum I will test it with you then
Cool I would like that
I just want to test some stuff out
Aha won’t use that but that’s pretty cool
I love heroku
I am going to eat dinner and then I will play around with it, thank you so much for your time @tony.kay
having trouble with server code refresh, but it mostly works. Feel free to check it out, and you can just pull as I work on it
@tony.kay Nice thnx ^^
@tony.kay do I need to make a index-dev.html in the resources folder?
I have it working nvm
Very impressed so far.. This could have saved me a lot of time
yeah, it is nice to work with. Turns out my problem was with intellij. pushed a few minor patches to project file, but otherwise it should be pretty good
The InitialAppState idea is pretty damn nice
It seems like you pretty much only write mutates and run txes to get remote data am I correct in assuming that?
Cool website btw
I made one myself
No worries, only cost me 5 minutes. untangled will probably save me hours
What is the main pattern to load data? just put it in the componentWillMount?
there are 4 files. One for specs, one for devcards, one for production, and one for dev
Aha cool i will pull them in
it is possible to put them in componentWillMount, but I have not needed to. Another option is you can write a mutation that uses the helper functions load-data-action
to emit a remote request from any arbitrary mutation.
So, imagine your app just loaded: use started-callback
to get initial server state. Then you nav to some page you want to lazy load data for. Make a nav mutation that checks app state for the data, and if it is missing issues a load-data-action
call from the :action of the mutation.
Yeah we currently use secretary, so that would fit very nice
yeah, with secretary, you just pass the app
to transact!
to trigger your nav mutation
I have to plug this into a existing re-frame codebase so I will probably do it like that
you have to be running all three figwheel builds (the -D options in the instructions)
Oh I have just started it on the repl
Works fine
I actually use ohai-emacs from Bodill
you should be able to just call (start-figwheel)
and it will start up everything
or you can call it with a vector of build id strings eg: (start-figwheel [“dev”])
I will probably put untangled in our boot.build. Would you ever be interested in a boot option for the template?
Yeah works like a charm @adambros
i wouldnt mind, just shoot a PR on untangled-template whenever you got it
ill be updating it once tony figures out what he wants with his version
Cool will put that on my todo list
yeah, boot is on the TODO list, but none of us use it (yet), and we don't have the horsepower to maintain it. So at present any Boot pointers will be included sort of as documentation YMMV
Sure I wouldn’t mind helping out
I’ll have todo it anyways
Am I correct in assuming that I could just use my own endpoint on which I have an om/parser running which returns transit?
Oh. The error handling mechanism establishes some standards...which are undocumented
You'd probably want to dupe the unhappy path stuff, but it is a small amount of stuff
No problem.. we are currently using catacumba but figuring out how to integrate will not be hard I think
I guess I have a nice weekend project
no, the server stuff is all convenience except for some of the error handling formats that Untangled expects at the network layer. Easy enough to emulate
Oh I see the code
That stuff is trivial to reuse
Cool I don’t see any roadblocks, thank you so much for convincing me
Yeah I already found that, I can simply install ring middleware in catacumba
welcome. I think a lot of ppl still see Untangled as a competing framework to Om Next...we're just trying to make it easier
Yeah, I also saw it that way
I’ll tell it to everyone 😉
@ethangracer Did you just patch post-sweep?
@mitchelkuijpers thanks! Word of mouth doesn't hurt 🙂
@tony.kay are you talking about the story in jira? I’m pretty positive we fixed it ages ago, I haven’t seen mutation symbols in app state for quite some time
yeah I marked it as already fixed
not sure when but I think it happened during a data fetch refactor
just FYI, I fixed the related network bug where the app stops trying to do network ops when it gets a malformed response
didn’t even realized that was a thing
thanks 🙂
ohh yes
awesome. yeah that was a pain
excellent
also meant to ask, given the om is going to beta soon, where are we with untangled going to “beta”?
it would be nice to have more docs but the code itself feels pretty solid
do we have protocol tests for todomvc?
ok, I can write those up pretty quickly in the near future
and definitely want to add more to the ref guide as well
config env vars
untangled datomic migrations
list goes on
I have a problem where my server gives me 500 with a load-field and then the client keeps trying eternally
i try to run this: (f/load-field this :users :fallback 'users/server-down)
and this is my query
(query [this]
[:id
[:current-user '_]
{:users (om/get-query User)}])
I added that because I thought that might solve the issue
componentDidMount
lol yeah that is my mistake
yeah you are right
you have to have an ident for load-field to work, and you have to implement the server bit correctly. 500 is all you too 🙂
No that is because the query is invalid
I implemented the server bit
Aha ok
So I should not need it?
Ah ok I’ll read it
Ah now I get it.. It is for loading extra data of certain entities with a id, so for example to get the posts of a user
lazy load stuff you didn't know you needed yet, related to something you already have
Yeah saw that
I'm trying to reset my app state on user log out and getting an Invariant Violation: malformed Ident.
error. I'm using the same state that I'm initializing the app with, so I'm kinda confused at what the difference would be resetting the state as opposed to initializing it. Would the difference have to do with me initializing with a data structure (which is denormalized) as opposed to an atom?
You guys are great rubber duckies. I'm thinking that I need to swap it with the normalized state, not the denormalized one I initialized it with. And I can probably use tree->db
to normalize my initial state.
That could be. I'll give that a shot. Where would I put the code to unmount and remount the root?
default db format vs custom format. Not general enough for Om, and initial app state isn't available in a general sense liek it can be with Untangled
@tony.kay Is this what you had in mind for remounting?
(defn remount-app! []
(let [reconciler (:reconciler @app)]
(om.next/remove-root! reconciler (gdom/getElement app-mount-point))
(om.next/add-root! reconciler ui/Root (gdom/getElement app-mount-point))))
https://github.com/untangled-web/untangled-client/blob/master/src/untangled/client/core.cljs#L65
If you do your remount (with a reset-state in the middle), that is what I was talking about
yeah, looking over the code to refresh my memory. What you're suggesting (with a reset-state using db->tree) will likely work fine.
Technically, it would work "better" to do this through a mutation, and just include a root query key as a follow-on read
you can do a swap! on state in a mutation, query the Root query and initial app state to make the normalized "new" state