Fork me on GitHub
#om
<
2017-02-28
>
raspasov04:02:06

@qqq in 6) the callback would do what exactly?

raspasov04:02:10

@qqq I think I mostly understand your question since I had similar questions when I was just starting out with om.next and I think the answer is “it depends” on 1. performance 2. elegance/proper way to store state

qqq04:02:21

@raspasov: I'm not sure exactly.

qqq04:02:36

So SVG does NOT support slider bars, which means I' implementting them myself (since foreign object is broken).

raspasov04:02:49

one thing I’ve ended up doing with similar situation is

qqq04:02:02

So what I'm not sure about is: * the slider location * the "view port" ^^ should the above be global state or local state ?

qqq04:02:08

(please go ahead with what you were saying)

raspasov04:02:10

to om/transact! when the animation/sliding/etc ends

raspasov04:02:39

but DO NOT transact WHILE the animation/draggin is happening since that might case way too many re-renders depending on the case

qqq04:02:21

@raspasov: mouse-move = updating local state mouse-up = do transact so the problem with this is that as I'm dragging the slider around, I need the content inside the window to pan -- this means hacky callbacks + more local state ?

raspasov04:02:24

and just fyi my experience with om.next is mostly with React Native/mobile so it might not apply to your case

raspasov04:02:45

essentially you’re using localState for “transitive” state

raspasov04:02:59

and only at the end of the drag transact! the global state

qqq04:02:05

by "transitive" do you mean "stuff we don't care about if we close the browser an dlose it" ?

raspasov04:02:27

more like “state for the duration of the drag"

qqq04:02:34

this seems awfully hacky, for the slider to do a callback to the parent, which then tells anotther element "yo, change your viewport"

qqq04:02:40

but I can't think of a better way

raspasov04:02:43

that is only “confirmed” aka om/transact!-ed at the end of the drag

qqq04:02:07

alright, as hacky as this is, I think this is the optimal solution; thanks for your insights

qqq04:02:12

anything else I should keep in mind with regards to this?

raspasov04:02:28

your callback at the end of the drag can just directly om/transact! into the global state, no?

raspasov04:02:37

why tell the parent, etc etc

qqq04:02:42

yeah, I don't need a callback at the end

qqq04:02:54

as I'm moving the slider around however, I need the displaybox to pan -- so I need a callback there

raspasov04:02:49

I would try both ways and see if it makes any difference with performance/smoothness/ux etc

qqq04:02:51

Window:
  * Title Bar
  * Vert Slider
  * Actual Content Box
so when I'm dragging over the VertSlider, I need to use local state to update the location of the slider (to display to the screen) however, I also need to pan the contents of Actual Content Box and I believe that requires a callback

raspasov04:02:04

if it does not, better to stick to the “pure” way of just om/transact! everything

qqq04:02:16

That's going to screw up history

qqq04:02:32

I really don't care about every mouse drag.

raspasov04:02:58

also if something is affecting the smoothness of animation there’s om/react-set-state!

raspasov04:02:03

in case you haven’t seen it

raspasov04:02:21

no worries, ttyl

qqq04:02:50

I'm aware of get-state and update-state!

qqq04:02:59

set state just seems like update-state! (fn [_] constant)

raspasov04:02:01

"Perform a stock react setState! outside of the om.next "render loop". Useful for preventing state changes from interrupting animations."

qqq04:02:38

I see, I was confusing react-set-state! with set-state!

qqq04:02:46

if this becomes a problem, I'll look into it

raspasov04:02:42

yes, it’s an optimization but it can be very useful in some cases to prevent choppy animations

matan11:02:24

Hi. Once upon a time I asked about the status of om.next, and by now I see there's already actionable documentation and stuff. Anything I should know about stability and completeness, before getting hands dirty?

matan11:02:39

It looks awesome

danielstockton11:02:38

@matan It's probably not a good idea to use datascript, stick with an atom. Otherwise, officially still alpha but pretty stable and complete. I'm writing a production app in it and haven't hit any blockers.

qqq11:02:21

@danielstockton : I'm just in the process of switching to datascript

qqq11:02:33

but I know very little about omnext and even less about datascript

qqq11:02:51

@danielstockton : what issues did you run into with datascript?

danielstockton11:02:04

I say that because set-query! doesn't work. It's possible to do everything without set-query! though.

danielstockton11:02:03

You are also not going to be able to use compassus and possibly other libraries, although it isn't too hard to roll your own routing.

danielstockton11:02:38

I really wanted to use datascript but it seems like an afterthought at the moment.

qqq11:02:41

I like datascript's query language + transact! model for adding stuff more than I like om.next/s model for querying/adding stuff

qqq11:02:53

but I simply don't know enough about either to know the pros/cons

danielstockton11:02:44

I think it's only set-query! that has problems because it stores the queries in state, which it assumes to be an atom.

danielstockton11:02:09

I wanted to submit a patch to allow storing queries in different state containers but I wanted guidance to increase chances of it being accepted and not sure there is much interest in it at the moment.

qqq11:02:58

lol; can't help you with that

danielstockton11:02:52

Maybe you'd like to +1

qqq11:02:25

so I guess this can be a problem where I have some toggle thingy in the defui

qqq11:02:31

where when I toggle an optino, the query needs to change

qqq11:02:57

it's actually not clear this is a problem with datascript since I can just pass the extra argument as a param, and have d/q handle it

qqq11:02:29

in standard om/next, we want "dynamic queries" since IQuery has to return the actual query

qqq11:02:43

but with datascript, what IQuery returns is an argument that some function consumes before writing a d/q query

danielstockton11:02:46

It's not a problem with datascript. It's a problem with om, because it has to remember what the new query is somehow and at the moment it can only store it in the state (atom).

qqq11:02:13

I'm trying to say: if you're using datascript as backend, you can get dynamic queries even now

qqq11:02:00

because we don't run d/q directly on what IQuery returns; but we have a layer of indirection to process it to decide what to feed to dq

danielstockton11:02:07

You can yes, outside of the set-query! mechanism.

danielstockton11:02:12

That's what I meant to say earlier with "It's possible to do everything without set-query! though." You can update the state directly and handle everything in the parser.

qqq11:02:46

Ah, I see now. Sorry for this, I started using om next 3 days ago and datascript 6 hrs ago, so all is new to me.

danielstockton11:02:41

I just like to point it out because it's not documented anywhere and set-query! is quite a commonly seen feature.

ag21:02:52

hey guys, is there a way to store a om/transact’s uuid in a var, so it can be used later? In my test I need to take state before the mutation and after, compare it and make assumptions

anmonteiro21:02:10

@ag there might be a better way

ag21:02:13

I was thinking if I there’s a way to do something like

(let [t (om/transact! ,,,,
       before (om/from-history t)] )

ag21:02:42

@anmonteiro I’m all ears

anmonteiro21:02:53

you’ll get the old-state and the new-state handed out to you 🙂

anmonteiro21:02:09

for every transaction

ag21:02:51

tx-listen eh? wow. that’s dope

ag22:02:22

@anmonteiro can you advise me now how deal with this "level of indirection”, in tx-listen I compare and do assumptions, but I need the assertions outside of that.

anmonteiro22:02:06

hrm so probably tx-listen is not what you’re looking for

ag22:02:09

e.g.:

(defscpec mutation-test
  (prop/for-all [gen-data my-gen]
        (let [reconciler (om/reconciler {:tx-listen (fn [env tx] ,,, check )) :state gen-data}
       ;;; what now?    
))

anmonteiro22:02:57

is this only for writing generative tests?

anmonteiro22:02:29

I wouldn’t use om/transact! in generative tests

anmonteiro22:02:37

just build a parser and call it directly

ag22:02:43

no I mean, it doesn’t matter, I just used defspec as an example

ag22:02:57

doesn’t have to be gen-test of course

anmonteiro22:02:05

I think we need to take a step back

anmonteiro22:02:30

Om Next abstracts things in the parser for a reason

anmonteiro22:02:49

so my question is why would you want to break that abstraction?

ag22:02:49

so, I need to test mutation, right? The best way of doing that is to compare the state before and after mutation, right?

anmonteiro22:02:16

OK so then we go back to what I was trying to say

anmonteiro22:02:21

mutations are just data

anmonteiro22:02:36

so just construct a om.next/parser and pass it some mutation data

anmonteiro22:02:48

you can choose what state you pass to the parser call

anmonteiro22:02:06

and you can hold on to a deref of that thing before you call the parser so you can do comparisons later

anmonteiro22:02:11

is there anything I’m missing?

ag22:02:52

so you’re saying that I don’t really have to call om/transact! in order to test the mutation?

anmonteiro22:02:04

@ag did you ever read this? ^

ag22:02:35

so in that doc, there’s no explicit om/transact! call, right?

anmonteiro22:02:57

since transactions are eventually fed to the parser

anmonteiro22:02:14

so just test the stateless part of your system

ag22:02:24

still not getting it ;(

ag22:02:14

so, let’s say I have ux-table, and a mutate let’s call-it sort! I need to test how it works, when it’s transacted it should change things in the state, let’s say it adds information about which column is sorted

anmonteiro22:02:36

maybe this is what you’re missing

ag22:02:37

now, I need to make sure that the other stuff in the state remains intact

anmonteiro22:02:27

when you call (transact! this [(launch/missiles!)]), the transact! function will eventually call (parser your-env-including-state '[(launch/missiles!)])

anmonteiro22:02:56

so you can just call the parser yourself

anmonteiro22:02:10

and whatever environment you want there to be

anmonteiro22:02:36

(let [state (atom {:foo :bar})
       parser (om/parser {:read … :mutate …})
       old-state @state]
  (parser {:state state} '[(some/mutation! {:mutation :args})]))
;; test new-state -> @state

anmonteiro22:02:57

@ag is this clearer? ^

anmonteiro22:02:03

what are you still missing?

ag22:02:31

I think I started getting it… daaaamn. I was doing it wrong ;(

ag22:02:37

shit… om/parser is a tough. 😉

ag22:02:56

Thanks Antonio!

hlolli22:02:22

om/parser has in my opinion equal corrolation between lack of documentation and lack of users knowledge, in inverse ratio to it's importance.

anmonteiro22:02:53

I don’t disagree

ag22:02:58

Well, good news - I learned something. bad news - I have bunch of tests to rewrite.

hlolli22:02:34

in my company Im learning re-frame, because majority voted against om.next. I'm filled with disappointments about how fanatical some of the re-frame users can be about the features they have, when I'm shaking my head thinking "it's all possible/done the same in om.next with less fancier names, less fancy readme and less hyped technology".

hlolli22:02:47

I don't say fanatical. But I believe there's much misunderstanding surrounding om.next, that became very clear to me on last :clojureD. Maybe I write an article about the parallels between om.next and re-frame when I've got the juice of re-frame.

ag22:02:54

Reframe and Reagent were the first React frameworks I got to use when I started learning Clojurescript a few months ago. And it felt nice.

ag22:02:16

Then I checked Om.Next - it felt awesome.

ag22:02:21

for awhile

ag22:02:32

soon I felt miserable 😉

ag22:02:33

Now every day I have these moments when I feel like “wow, this is so AWESOME!”. And sometimes I feel completely lost

hlolli22:02:59

I feel like programming om is like playing golf, one hole it's the most fun sport in the worl, the next hole I throve my driver into the river and leave the course.

adambrosio23:02:16

Personally I wouldn’t be working with om if it weren’t for #untangled, I don’t think I would want to work with something that has to make your write your own parser to get a web application going.

hlolli23:02:39

actually a very valid point, especially in a team.

anmonteiro23:02:55

I disagree, but then again, it’s the thing about personal opinions

anmonteiro23:02:35

having the ability to write parsers a la carte is, among other things, what makes Om’s testability so great

anmonteiro23:02:54

it’s also what allowed us to do a lot of fancy stuff at Ladder and it’s part of what I’m gonna be talking about at Clojure/West 🙂