Fork me on GitHub
#reagent
<
2020-12-01
>
GGfpc14:12:52

In reagent how can I pass the background key (with no value) in this jsx?

<RadialBar minAngle={15} label={{ fill: '#666', position: 'insideStart' }} background clockWise={true} dataKey='uv' />

p-himik14:12:06

{:background true}

neilyio19:12:24

What would be an idiomatic way to take the "latest" value from a list of reagent.core/atom? I'm sort of looking for an equivalent of core.async/alts!.

p-himik19:12:49

Not sure what you mean. Atoms store a single value with no timestamp attached. What do you mean by "latest"?

Jason19:12:15

Hello. I'm trying to use hooks to get some buttons to appear over a table row on hover as in gmail. I've never used hooks before, at least not successfully, and I seem to be violating some rule(s) about their use. I'm trying to follow <https://material-ui.com/components/popover/#mouse-over-interaction%7Cthis JS sample (click '<>' for code)> .

(defn row-hover [{:keys [^js classes] :as props}
                 {:keys [id name url policy status ts] :as loc}]
  (let [this-id (str "row-" id)
        [anchor-el set-anchor-el] (react/use-state nil)
        open (boolean anchor-el)
        popover-id (str "popover-" this-id)]
    (reagent/as-element
     [:> TableRow
      {:hover true
       :id    this-id
       :key   this-id
       :aria-owns #(if (open) popover-id js/undefined)
       :aria-haspopup true
       :on-mouse-enter #(set-anchor-el (-> % .-target))
       :on-mouse-leave #(set-anchor-el nil)}
      [:> TableCell [:> Link name]]
      [:> TableCell [:> Link url]]
      [:> TableCell policy]
      (if (= :success (first status))
        [:> TableCell {:align "center"
                       :style {:color "Green"}}
         [:> Icon [:> icons/Check] ]]
        [:> TableCell {:align "center"
                       :style {:color "Red"}}
         [:> Icon
          [:> Badge {:badgeContent (second status)
                     :color        "error"}
           [:> icons/Close]]]])
      [:> TableCell (arco/time-since [ts])]
      [:> Popover {:id popover-id
                   :class-name (.-popover classes)
                   :classes (.-tr classes)
                   :anchor-el anchor-el
                   :anchor-origin {:vertical "top"
                                   :horizontal "right"}
                   :transform-origin {:vertical "top"
                                      :horizontal "right"}
                   :on-close #(set-anchor-el nil)
                   :disable-restore-focus true}
       [:> Grid {:container true}
        [:> Tooltip {:title (str "Edit " name)}
         [:> IconButton {:aria-label "edit"
                         :color      "primary"
                         :class      (.-avatar classes)
                         :on-click   #(rf/dispatch
                                       [::edit-location loc])}
          [:> icons/Edit {:fontSize "small"}]]]
        [:> Tooltip {:title (str "Delete " name)}
         [::> IconButton {:aria-label "delete"
                          :color      "primary"
                          :class      (.-avatar classes)
                          :on-click   #(rf/dispatch
                                        [::delete-location loc])}
          [:> icons/Delete]]]]]])))
Current build error is Uncaught Error: No item {} in vector of length 2 which I'd guess is complaining about the use-state line in the let. Any pointers appreciated.

Lu19:12:42

I’m pretty sure you can’t use hooks within reagent components... but it doesn’t really matter because you can easily replace them with local ratoms..

p-himik19:12:38

You absolutely can use hooks with the latest Reagent - it's in the FAQ.

Jason19:12:08

The objects I want to appear on hover are material ui react components. I see the sample provided in the hooks section https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md#hooks but am unsure how to use these components.

p-himik19:12:20

Sorry, not in the FAQ - here: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md#hooks @jasonhlogic What is react/use-state? Shouldn't it be react/useState?

Jason19:12:27

that fixed the build error but still no render

p-himik19:12:44

Need more details - errors, stacktraces.

Jason19:12:39

...gathering them...

p-himik19:12:18

Just post the topmost one. If there are multiple ones, chances are they're all caused by the first one.

Jason19:12:50

When I reloaded the page, it revealed that the original error had not in fact gone away

p-himik19:12:28

Post the stacktrace.

p-himik19:12:49

Also, replace (open) with open.

Jason20:12:15

Topmost:

Error rendering component (in reagent5)

Jason20:12:31

reagent$impl$component$do_render component.cljs:147 res re_frame_10x.cljs:38 reagent$ratom$in_context ratom.cljs:42 reagent$ratom$deref_capture ratom.cljs:55 reagent$ratom$run_in_reaction ratom.cljs:537 day8$re_frame_10x$mp_render re_frame_10x.cljs:38 React 8 unstable_runWithPriority scheduler.development.js:654 React 6 reagent$impl$batching$run_queue batching.cljs:38 flush_render batching.cljs:87 flush_queues batching.cljs:97 run_queues batching.cljs:77 G__51013 batching.cljs:58 G__48907 re_frame_10x.cljs:90 (Async: FrameRequestCallback) next_tick re_frame_10x.cljs:88 schedule batching.cljs:58 reagent$impl$batching$schedule batching.cljs:124 reagent$ratom$rea_enqueue ratom.cljs:118 handlechange ratom.cljs:408 reagent$ratom$handle_reaction_change ratom.cljs:354 reagent$ratom$notify_w ratom.cljs:102 cljs$core$IReset$resetBANG_$arity$2 ratom.cljs:156 cljs$core$resetBANG_ core.cljs:864 cljs$core$reset_BANG_ core.cljs:4493 <anonymous> fx.cljc:185 re_frame$fx$do_fx_after fx.cljc:56 re_frame$interceptor$invoke_interceptor_fn interceptor.cljc:70 re_frame$interceptor$invoke_interceptors interceptor.cljc:108 re_frame$interceptor$execute interceptor.cljc:201 re_frame$events$handle events.cljc:65 re_frame$router$IEventQueue$process1st_event_in_queue$arity$1 router.cljc:179 re_frame$router$IEventQueue$runqueue$arity$1 router.cljc:198 vec__46269 router.cljc:146 re_frame$router$IEventQueue$fsmtrigger$arity$3 router.cljc:169 G__46260 router.cljc:187 onmessage nexttick.js:218 (Async: EventHandlerNonNull) getSetImmediateEmulator_ nexttick.js:213 nextTick nexttick.js:86 day8$re_frame_10x$inlined_deps$re_frame$v0v12v0$re_frame$router$IEventQueue$runnext_tick$arity$1 router.cljc:187 vec__46220 router.cljc:142 day8$re_frame_10x$inlined_deps$re_frame$v0v12v0$re_frame$router$IEventQueue$fsmtrigger$arity$3 router.cljc:169 day8$re_frame_10x$inlined_deps$re_frame$v0v12v0$re_frame$router$IEventQueue$push$arity$2 router.cljc:102 day8$re_frame_10x$inlined_deps$re_frame$v0v12v0$re_frame$router$dispatch router.cljc:247 day8$re_frame_10x$db$init_db db.cljs:27 day8$re_frame_10x$init_db_BANG_ re_frame_10x.cljs:219 <anonymous> preload.cljs:9 globalEval app.js:594 evalLoad app.js:1687 <anonymous>

Jason20:12:14

there are more errors after that. should i paste those too?

Jason20:12:49

Uncaught Error: No item {} in vector of length 2
    cljs$core$vector_index_out_of_bounds core.cljs:5407
    cljs$core$array_for core.cljs:5431
    cljs$core$IIndexed$_nth$arity$2 core.cljs:5598
    cljs$core$IFn$_invoke$arity$1 core.cljs:5678
    call core.cljs:5498
    res component.cljs:108
    reagent$impl$component$wrap_render reagent.impl.component.js:152
    reagent$impl$component$do_render component.cljs:141
    res re_frame_10x.cljs:38
    reagent$ratom$in_context ratom.cljs:42
    reagent$ratom$deref_capture ratom.cljs:55
    reagent$ratom$run_in_reaction ratom.cljs:537
    day8$re_frame_10x$mp_render re_frame_10x.cljs:38
    React 11
    unstable_runWithPriority scheduler.development.js:654
    React 6
    reagent$impl$batching$run_queue batching.cljs:38
    flush_render batching.cljs:87
    flush_queues batching.cljs:97
    run_queues batching.cljs:77
    G__51013 batching.cljs:58
    G__48907 re_frame_10x.cljs:90
    next_tick re_frame_10x.cljs:88
    schedule batching.cljs:58
    reagent$impl$batching$schedule batching.cljs:124
    reagent$ratom$rea_enqueue ratom.cljs:118
    _handle_change ratom.cljs:408
    reagent$ratom$handle_reaction_change ratom.cljs:354
    reagent$ratom$notify_w ratom.cljs:102
    cljs$core$IReset$_reset_BANG_$arity$2 ratom.cljs:156
    cljs$core$_reset_BANG_ core.cljs:864
    cljs$core$reset_BANG_ core.cljs:4493
    <anonymous> fx.cljc:185
    re_frame$fx$do_fx_after fx.cljc:56
    re_frame$interceptor$invoke_interceptor_fn interceptor.cljc:70
    re_frame$interceptor$invoke_interceptors interceptor.cljc:108
    re_frame$interceptor$execute interceptor.cljc:201
    re_frame$events$handle events.cljc:65
    re_frame$router$IEventQueue$_process_1st_event_in_queue$arity$1 router.cljc:179
    re_frame$router$IEventQueue$_run_queue$arity$1 router.cljc:198
    vec__46269 router.cljc:146
    re_frame$router$IEventQueue$_fsm_trigger$arity$3 router.cljc:169
    G__46260 router.cljc:187
    onmessage nexttick.js:218
    getSetImmediateEmulator_ nexttick.js:213
    nextTick nexttick.js:86
    day8$re_frame_10x$inlined_deps$re_frame$v0v12v0$re_frame$router$IEventQueue$_run_next_tick$arity$1 router.cljc:187
    vec__46220 router.cljc:142
    day8$re_frame_10x$inlined_deps$re_frame$v0v12v0$re_frame$router$IEventQueue$_fsm_trigger$arity$3 router.cljc:169
    day8$re_frame_10x$inlined_deps$re_frame$v0v12v0$re_frame$router$IEventQueue$push$arity$2 router.cljc:102
    day8$re_frame_10x$inlined_deps$re_frame$v0v12v0$re_frame$router$dispatch router.cljc:247
    day8$re_frame_10x$db$init_db db.cljs:27
    day8$re_frame_10x$init_db_BANG_ re_frame_10x.cljs:219
    <anonymous> preload.cljs:9
    globalEval app.js:594
    evalLoad app.js:1687
    <anonymous>

Jason20:12:50

not sure whether that's too much?

p-himik20:12:02

No need for the rest. The stacktrace is unclear - I would try to debug to understand what that 2-element vector is to try to figure out where its usage is incorrect. Because I don't see anything in your code that would result in that error.

p-himik20:12:18

Also, try to limit the scope - your code is not small enough to be debugged efficiently.

Jason20:12:35

the only two-element vector i could see is the useStatereturn value in the let, which was what got me to post my original question

Jason20:12:53

You are correct about scope. Front end code is much more sensitive to that than i am used to. I'm working on it :)

p-himik20:12:02

I don't think that's the right vector - you never get from it anywhere. The destructuring is automatic and uses long indices, whereas your error is because of using a map as an index.

Jason20:12:44

i found it. it was in the calling code. thanks for your help. You mentioned my code scoping. Can you point to any publicly visible samples which you think are correct?

p-himik21:12:14

I don't understand your question. Samples of what?

Jason21:12:44

correctly scoped cljs

p-himik21:12:05

By "limit the scope" I meant reducing the scope within which you have to debug the error, nothing more. It's not CLJS specific in any way.

Jason21:12:00

i was fishing for samples because i assume showing would be simpler than telling

lilactown20:12:31

FYI while the material-UI examples use hooks, they are not required. All they depend on is a value and a callback are passed in that change the value

jaime23:12:31

When testing reagent component, do I have to always call reagent.core/flush in order to trigger rerender? I feel like I don't really need to care if component uses atom or not, I care about event being fired and expect some changes

(ns mydemo.counter-test
  (:require
    [cljs.test :refer [deftest testing is]]
    [reagent.core :as r]
    ["@testing-library/react" :as rtl :refer [screen]]
    [mydemo.counter :refer [counter]]))

(enable-console-print!)

(defn with-component [component body]
  (let [container (js/document.createElement "div")
        container (.appendChild (.-body js/document) container)
        view (rtl/render
               (r/as-element component)
               #js {:container container
                    :baseElement container})]
    (try
      (body view)
      (finally
        (.remove container)
        (rtl/cleanup)))))


(deftest counter-testing
  (testing "should increase by 1 on button click"
    (with-component [counter]
      (fn [view]
        (let [button (.getByRole view "button")
              input (.getByRole view "textbox")]
          (is (= "0" (.-value input)))
          (.click rtl/fireEvent button)
          (r/flush) <--------------------------------------   I have to call this one in order for the input value to change
          (is (= "1" (.-value input))))))))