This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-08-30
Channels
- # admin-announcements (10)
- # beginners (7)
- # boot (216)
- # cider (10)
- # cljs-dev (3)
- # clojure (71)
- # clojure-denmark (2)
- # clojure-italy (3)
- # clojure-seattle (1)
- # clojurescript (124)
- # cloxp (1)
- # code-reviews (5)
- # core-matrix (2)
- # cursive (34)
- # datomic (3)
- # editors (1)
- # hoplon (201)
- # immutant (2)
- # jobs (3)
- # ldnclj (7)
- # off-topic (3)
- # re-frame (19)
- # reagent (76)
@benzen Thanks I’m converting some code that is currently working differently but I think that will solve my scenario. Still would be interesting to know how to interact with dom nodes in Reagent. The only info I could find is this but it seems old since it references cloact: https://github.com/reagent-project/reagent/issues/5
@jonaskello: I’m also interested in learning about ‘ref’ support in reagent. You can sometimes use id’s instead but that’s not very idiomatic React IIUC. Let me know if you learn anything interesting in this area
@jonas I managed to solve my current scenario with a combination of event.target to get the td and getElementById to get the div. I agree the getElementById does not seem like the correct way to do it in react, not even sure it will work in all situations? I’ll keep looking for a more correct way to reference the div and post if I find it..
@jonaskello: This seems to work: (.findDOMNode js/React (-> this .-refs .-myRef)) where my component has a ref set on one of the DOM nodes, for example [:p {:ref “myRef”}]
@jonas That seems like a good way… I’m new to clojurescript so I’m a bit unsure how the (-> this .-refs .-myRef) part works… if I try it, figwheel tells me “this” is an undeclared Var… I guess “this” is a clojurescript reference rather than a js reference in this context?
Do I need to use with-meta and component did mount to get a reference to this?
@jonaskello: Yes, it would go in :component-did-mount
@jonas: i always wince when I see the the with-meta
form of adding lifecycle methods. Are you aware of this method:
https://github.com/Day8/re-frame/wiki/Creating-Reagent-Components#form-3-a-class-with-life-cycle-methods
No, wait! Ignore. I've read further now.
@jonas Thanks for the snippets! I’ll see if I can make it work in my scenario
@mikethompson: Would Form-3 not work in this case? Never mind, saw the second example had it now
Hi all, nearly managed to wire up a sample Reagent app presenting data from an atom in a Highcharts chart. Updating the atom works find, but the Highchart binding doesn’t fire when the atom is updated. If I force a refresh via figwheel by updating code, the graph does get updated. Any pointers - I think I’m closer to understanding the basics.. https://gist.github.com/paulspencerwilliams/0b9a9d00869ec9107d4a
@paulspencerwilliams: try to deref chart-config in graph-container
right now, no rendering function depends on chart-config data, so reagent won’t re-render them when you touch chart-config atom
@darwin: yeah, that’s what I thought, but couldn’t see how to trigger it. The token deref didn’t work, but I think it’s the right general direction.
but there is probably a better solution, you want tell highcharts to update itself, without discarding whole dom element and building up from scratch again
@jonas The examples are really close, only I need to use .findDOMNode in an onclick handler, which means I need a reference to “this” in the onclick handler… Not sure how to get that….
@darwin: I was reading https://github.com/Day8/re-frame/wiki/Creating-Reagent-Components which is nearly there, but it isn’t quite sinking in.
@jonaskello: as-this?
@darwin Aha, and that is a built-in macro in clojurescript?
Thanks, did not know that
@darwin: suppose, in a way, I want a component that on change doesn’t ‘return html’ but rather invokes a JS function.
@darwin: but maybe that’s me thinking imperatively.
@paulspencerwilliams: I would recommend building your component as two reagent components, an outer wrapper responsible for creating highcharts element via :component-did-mount as you do now, but not passing in data, and an inner component responsible for feeding it with data, using some highchart api call on existing element, the inner component should deref your data source, do the clj->js work and call the api as a side effect of its rendering
reagent/react are smart enough to keep your outer component living between render calls to the render function of the inner component (because no inputs changed for that outer component)
in figwheel case, whole dom tree will get rendered from scratch, because r/render-component is called when figwheel re-evaluates the source
@darwin: can use chart.series[0].update etc (http://stackoverflow.com/questions/16407901/highchart-series-update-in-javascript) to update Highcharts, but again, this is getting a component to run JS rather than returning HTML, and it seems only atoms referenced in returning HTML will cause the component to be re-referenced.
@paulspencerwilliams: in your inner render function you should do both, return hiccup and (as a side effect) run some js code (call chart’s update method)
causing side effects in your render functions is not nice, but that’s the way how to deal with mutable js-world
@darwin: suppose the constraint I’ve been focused on is the JS references the html returned in hiccup, but the JS will execute before the hiccup is executed, and thus the html element won’t exist at the time.
@darwin: think you’ve hit the nail on the head there - I’m using Highcharts mutably.
by the time inner render function is called, the outer component already exists in the dom (component-did-mount already executed), that is how react works
right, i’ll try this then.
btw. that inner render function should be a fn returning hiccup, not a static array of hiccup markup
yeah, understood; and cheers!
I’m pretty sure this approach will work, you can show me your updated code and I can point out mistakes, if any
@darwin: I have something working! -> https://gist.github.com/paulspencerwilliams/0b9a9d00869ec9107d4a
@darwin: not using your exact solution, but the approach of causing token side effect.
@paulspencerwilliams: that works, but you are possibly re-creating highcharts element every time from scratch (don’t know if the library is smart enough to apply only changes if the element already exists)
@darwin: apparently so. First step was getting it ‘working’. Second step is to use this approach : chart.series[0].update({ pointStart: newSeries[0].pointStart, data: newSeries[0].data }, true);
Difficulty is this approach requires having a reference to the chart.
suppose mixing mutable JS components isn’t the best introduction to react / reagent 😉
:component-did-update and other functions are passed calling react component as a parameter, you can ask it to give you root dom node
okay, thanks. For info, this is a learning exercise rather than commercial ‘get it done’ exercise, so I really am looking for idiomatic / clean ways to implement
here is how I do wrapping of mutable thing in reagent component in my project: https://github.com/darwin/plastic/blob/master/cljs/src/main/plastic/main/editor/render/inline_editor.cljs#L46
ideal situation is to end up with a reagent component which is wrapping that js-thing, so that users of the component can treat it as normal reagent component and don’t have to keep special assumptions (about side-effects) in their mind
agreed.
Dumb question maybe but what exactly does js/$ do?
@paulspencerwilliams: js is a “magic” namespace in clojurescript referencing the toplevel js object (window in browsers and I believe process in Node). So js/$ in cljs is the same object you would get if you were to write $ in a js console. Presumably it’s the jQuery object.
@jonas: gotcha; thanks
Having a side-effect here gives me some pause - https://gist.github.com/paulspencerwilliams/0b9a9d00869ec9107d4a#file-core-cljs-L49
some pause?
pause for thought?
I should read above, looks like there is a discussion around this. And yeah, seems like it should be tucked in a different place
agreed, so holding reference to Highcharts instance is the thing to do. On updating due to atom changing should js invoke series update of Instance?
I can see Higcharts.charts[0] working for single chart apps and exploring the problem, but not idiomatic. If this was replaced with an in-component reference to the instance, then maybe this is the way forward.
it’s a great blog post though.
@gadfly361 Cheers for snippet, interested in swapping .highcharts and js/$ calls around and need to explore dom-node too. Away from computer now but will look asap. Thanks for effort and to @darwin too. Learning React through an abstraction isn't the easiest, but I'm really enjoying it.
@gadfly361: don’t expect much (yet)