Fork me on GitHub
#om
<
2016-08-01
>
mitchelkuijpers12:08:07

Is there anyone here who has played with error handling from serverside reads? I found the function default-extract-errors in om.next which seems to return a list of errors and a result tree but i am not sure how to hook it up

mitchelkuijpers12:08:28

I have the following case someone tries to read a list of something but they could have no permissions to read this list so then I want to show a message that they have insufficient permissions

mitchelkuijpers12:08:10

Oh I think you can use this in the read functions if I read the tests correctly?

anmonteiro12:08:26

@mitchelkuijpers: I haven’t used it or looked too much at it, but I think it’s supposed to be used in merge

anmonteiro12:08:00

i.e. extract the errors from the result whenever you’re merging the remote response

mitchelkuijpers12:08:23

Yeah looks like it

anmonteiro12:08:25

I also think the work on that is not finished, and I believe it’s going to be part of default-merge in the future

mitchelkuijpers12:08:07

Aha that would make sense, I think it is a good idea then to keep the om.next/error responses in my reads and do some custom work for now

mitchelkuijpers12:08:43

we also did some work to create a after-mutate function that reads mutation responses and responds to them en keeps them out of the app state

peeja13:08:20

In old Om, is there ever a good reason to use :opts?

peeja13:08:54

It's just like passing params except it doesn't factor into shouldComponentUpdate, right?

a.espolov14:08:26

people please enlighten me in question is using not optimistic updates in om.next?

hkjels15:08:21

non-optimistic updates would be leaving out the action part of your mutation

a.espolov16:08:13

@hkjels: if you have any example?

hkjels16:08:33

Not really, but what I mean is, when you do your mutation your back-end should return novelty that’s merged back in to your app-state. At that point your view will be updated with the new data

hkjels16:08:09

So, optimistic is just more work on the front-end

krchia20:08:36

how can i add properties to a js object that i initialized in component local state?

anmonteiro20:08:27

@krchia: (goog.object/set the-object “foo” 42)

krchia20:08:55

@anmonteiro: isn’t that the same as (set! the-object “foo” 42)?

anmonteiro20:08:25

that would be (set! (.-foo the-object) 42), which might break with advanced optimizations

krchia20:08:28

i was thinking of (om/set-state! owner the-object (some-function-that-returns-object-with-new-property)

anmonteiro20:08:08

@krchia: so set-state! will completely overwrite the existing state

krchia20:08:11

do i have to do (fn [] (set! object x y) object)

anmonteiro20:08:33

@krchia: you also have doto which might be useful for these cases

anmonteiro20:08:52

;; returns the-object
(doto the-object
  (set! x y))

krchia20:08:08

ohh, interesting

peeja21:08:41

@krchia: I think you're looking for update-state!

krchia22:08:11

@peeja: not sure what’s the difference between update-state! and set-state! - the docs aren’t making it clear for me

peeja22:08:30

update-state! takes a function, like update

peeja22:08:59

set-state! just takes the new value for the state

peeja22:08:49

Ah. What's the thing you're mutating?

krchia22:08:05

are you familiar with d3?

krchia22:08:17

perhaps you might know a better way - i’m just working with the d3.layout.tree structure

krchia22:08:12

just trying to implement this example, where you push new nodes into both the nodes structure and as a children of a parent node

peeja22:08:20

Typically in d3 you're just getting new data an re-drawing your d3 stuff over the existing DOM, correct?

peeja22:08:31

Ah, link?

peeja22:08:32

I would move the generation of the data out of your component entirely

peeja22:08:54

Your component can take in data, then on did-update it can redraw the d3

krchia22:08:58

sorry, what does that mean ?

krchia22:08:12

so i keep it in app-state or a global variable ?

peeja22:08:14

You're generating random data inside the component

peeja22:08:24

Keep it in whoever's calling this component

peeja22:08:49

Just don't complect generating the data with rendering the data

krchia22:08:38

i’m not doing that for now - to make things simple i have a vector of pre-generated data to test it with

peeja22:08:48

Ah, then that makes this easy:

peeja22:08:53

Just pass that data into your component

peeja22:08:33

Each time your component gets different data, it'll re-render. The actual render isn't going to be interesting, but it'll also call will-update, and that's where you call your d3 code from.

peeja22:08:45

(with the new params your component has just received)

krchia22:08:23

did you mean did-update?

peeja22:08:29

Yeah, sorry, that's right

peeja22:08:45

(it could be either, really, but did-update is more appropriate)

krchia22:08:25

ok, hang on a sec while i try this stuff out

krchia22:08:32

i already have my d3 code in did-update

krchia22:08:48

i’m just going to take out the data from the local component state

peeja22:08:05

The trick is that it sounds like you're passing in non-CLJS objects as the data. Is that right?

krchia22:08:23

yeah, should i just apply clj->js only when i’m going to render them ?

krchia22:08:46

and prepare it with clojurescript operations

peeja22:08:58

Hmm, there's all kinds of surprising stuff in here…

peeja22:08:06

Why the go?

krchia22:08:19

yeah, it’s not an exact copy, it’s suppose to be rendering game trees of 2048

peeja22:08:29

Ooh, neat!

krchia22:08:53

perhaps it’s not the right way? using it to imitate setInterval

peeja22:08:55

Oh, I see. Yeah, fair enough, I think that makes sense

krchia22:08:24

it’s super messy, sorry bout that

peeja22:08:44

The reason I'm calling out passing in JS objects as the component's data is that Om depends on being able to = the old params and the new params to see if they've changed

krchia22:08:24

so if i want to (.push some-component-data foo)

krchia22:08:34

what happens?

peeja22:08:47

It won't notice

krchia22:08:00

what’s the idiomatic way of doing this?

peeja22:08:11

You want as much of this to be immutable as you can get away with

krchia22:08:12

push, then set-state or convert back to clj and set state?

peeja22:08:20

I'm not sure what the pushing is for

peeja22:08:42

Oh, I see what you're doing

peeja22:08:53

No, you just want to reimplement this with immutable data

krchia22:08:59

ah, it’s the “add a new node to a random parent” part in the d3 code, because if i don

peeja22:08:14

You don't want to .push onto an existing object, you want to conj onto a vector

krchia22:08:16

don’t push in the children into the parent’s node, then it doesn’t render

peeja22:08:34

Then you want to pass the new vector into the component

krchia22:08:04

so convert it back to clj, then render it using the js data

peeja22:08:07

So, if you want this to run as an animation, you'll want to have something on the outside that re-renders the component every X ms with the new data

peeja22:08:26

convert it back to clj?

krchia22:08:42

sorry, i thought d3.transition will take care of the work

krchia22:08:56

i just need to update the component state

krchia22:08:12

yeah, i store the tree data structure (to be rendered in d3) as an js object

peeja22:08:28

Ah, you know what, to really use Om, you'll want to put the node data structure in the app state, and then kick off something that changes that state over time

peeja22:08:28

So, each tick, the app state atom points to a new tree of nodes, exactly like the last, but with one random node added

peeja22:08:47

Then Om notices that the state atom has changed, so it passes that value into the component

peeja22:08:07

Then the component converts that into more JS-y values (if necessary), and passes that to d3

krchia22:08:15

it works with local component states as well right?

krchia22:08:25

sorry for the slow replies - my hands are kind of bandaged up

peeja22:08:35

Aw, I'm sorry 😞

peeja22:08:41

Yeah, it'll work with component state too

peeja22:08:08

It just means putting the ticking mechanism inside the component (which I guess is what you've done)

peeja22:08:14

That should work fine

krchia22:08:14

yeah, thanks 🙂 you’ve been great

krchia22:08:40

i think i’m going to try that approach - storing the data in clojure data structures, then converting to js data only when d3 needs it

anmonteiro22:08:22

@krchia: I haven’t been following the whole discussion, but for performance you might want to keep JS datastructures

peeja22:08:29

:thumbsup: Good luck!

krchia22:08:02

@anmonteiro: what - i was just about to switch back to my editor!

anmonteiro22:08:04

and deal with the Om diffing part by having a monotonically increasing value in your local state that you increment whenever you mutate the JS object

anmonteiro22:08:31

js->clj and clj->js is heavy on performance

krchia22:08:46

that sounds like an interesting approach, did you consider this approach @peeja

peeja23:08:40

Oh, yeah, that works too.

peeja23:08:23

I tend to stay away from mutation as much as possible until it actually starts hurting 🙂

peeja23:08:31

but that's a reasonable way to handle it