This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-07-27
Channels
- # admin-announcements (1)
- # aws-lambda (2)
- # beginners (48)
- # boot (231)
- # capetown (1)
- # cider (35)
- # cljs-dev (25)
- # cljsrn (74)
- # clojure (273)
- # clojure-austin (2)
- # clojure-berlin (5)
- # clojure-hk (1)
- # clojure-poland (1)
- # clojure-russia (50)
- # clojure-spec (63)
- # clojure-uk (58)
- # clojurescript (51)
- # cursive (5)
- # datomic (39)
- # defnpodcast (3)
- # dirac (13)
- # editors (6)
- # emacs (3)
- # hoplon (86)
- # jobs (2)
- # lein-figwheel (1)
- # liberator (3)
- # off-topic (10)
- # om (113)
- # onyx (34)
- # protorepl (29)
- # re-frame (2)
- # reagent (8)
- # remote-jobs (1)
- # ring (4)
- # test-check (42)
- # untangled (31)
- # yada (2)
guys apologies I'm sure this is obvious, how can I maintain order with castra calls?
Let's say I have a castra remote end-point to generate a unique token for a given file. If I call (mkremote
repeatedly for each of n files, how can I associate the result of each remote call to a given file in the result cell?
in other words, can I ensure the state cell is updated in the same order as the requests were sent, and if not, is it possible to make the state cell a vector, or map, similar to the loading cell?
actually I guess I can fake it by storing a map and ensuring that my remote call passes an :identifier
back and forth
@adamw: when you call a castra function, it will immediately return a jquery promise which you can associate with each file; the promise, in turn, will invoke a success callback with the result of the remote function that evaluated on the server.
the result of the function, returned through the callback, is not to be confused with the state, which just so happens to piggyback on the http response to the state cell. this is an implementation detail designed to “bind” the client state on the query side of the application to the state on the server.
the state and the result can be the same, if you build your application that way, but they can also differ if you make use of the state-fn that can be passed into the castra middleware. if you supply a state-fn, the state resulting from that function will get synced to the state cell with each http request, while the result of each rpc call will be returned to the call site via the query promise.
1. the result of performing some action (command) on the server, which is a side effect you perform on the world outside the application. This results in possibly a change in the global state of the database. This global state is returned to the client and a javelin cell is updated (a "stem cell"). The client's UI reacts to this change globally. Usually the component that sent the commend has no need to know or care about how the database state will relate to the UI as a whole. This is why rpc fns don't just return a result (it's expected that the part of the program that reacts to changes to the database state will not be part of the piece of program that initiates the command.)
2. errors or exceptions raised by the command on the server. These do need to be handled locally in the component that sent the command, usually. Like if you have a form component that sends a command to the server, if validation fails only the form knows how to deal with that, for example. This is why the rpc fns return the promise. The promise can be used to receive errors and handle them locally in the form component, etc.
so the rpc fn returns a promise that is local to the component, but sets the state of a javelin cell that is part of a larger graph with the latest server state
i want to encapsulate the logic for reacting to changes of the backend server state in the components that convey that information to the user, the UI components
and those UI components are usually not the same ones that send the commands that result in those changes in the backend, like the forms and whatnot
and secondly i want to encapsulate the error handling logic in the components that initiate the commands to the backend
if i can cleanly achieve both kinds of encapsulation then things go very smoothly and components are nicely composeable and docile
the "action" components send commands, which execute synchronously and produce errors synchronously. So a component knows when it did something bad.
the "view" components read their own "queries" (cells) that update asynchronously in response to the changes generated by executed commands
whoever acts on the error
cell doesn't really matter to the "view" components. It might even be another "view" component that displays the errors (e.g. status bar)
i guess the fundamental strategy here is to have two separate channels for the RPC results, one local to the component and one provided from outside
like the mkremote thing takes the stem cell from outside in which it stores the backend state
so the promise is kind of like the sync command execution on the server side, as in it's local to the caller
i guess "globally" is the wrong word, maybe better is "the error cell is for handling errors via inversion of control"
hey, random question
can i not run certain things on prerender?
i got an ajax call erroring out and the error ending up in the rendered markup
oh it would be that i’m not running the server while i’m making the jar
yeah so it renders something that looks ok
but anything that needs the backend won’t be there
the issue is that it now actually puts an error in
like, not a js error
a system message i made
i don’t want it to show up
i don’t want the error either
i have
(def env (j/cell nil))
(ajax.core/GET "/config" {:handler #(reset! env %)
:error-handler #(do (system-message.state/+! "Couldn't connect to the server. Refreshing the page might help.")
(prn %))})
i’ll just wrap that in the prerendering? thing
if it's used in too many places it might get hairy and maybe need to make some abstraction on top of prerendering?
in your app
@micha probably fine for just that
do i need to stick that in a cell?
like (j/cell= (when-not h/prerendering? …))
atm everything else is behind a login form
ah, i see it’s just a value
@micha thanks. Seems like another thing that should go in the wiki someday.
like either it's running in the prerendering phantomjs browser or it's running in the user's browser
aight, i g2g
chat later
later @thedavidmeister !