Fork me on GitHub
#reagent
<
2018-03-08
>
eoliphant01:03:01

anyone using secretary for routing.? I’m trying to figure how to set a route programatically

justinlee01:03:29

I use it in combination with accountant for html5 history routing

eoliphant01:03:31

yeah I’ve got a project that was created with the luminus starter, have a few routes, etc setup with the goog.History stuff. Working fine when I say click to “#/help”, but don’t see say an api where I can programatically (go "help") or something

justinlee01:03:55

I think you do (secretary/dispatch! path)

justinlee01:03:09

with accountant you do (accountant/navigate! path)

eoliphant01:03:32

ok. let me try that, I’m just getting back to this, but I think when I tried it, the route function fired but the url didn’t change

gadfly36101:03:44

If you wanted to do it manually, you could

(defn set-hash! [hash]
  (set! (.-hash (.-location js/window))
        (str "#" hash)))

gadfly36101:03:12

I use secretary and do it that way ... I dont bother with the built in stuff lol

eoliphant01:03:57

yeah window.location was where I was going next lol

eoliphant03:03:00

ah heck, now I just remember the other problem I was having lol. so, anyone using it with re-frame? i’m trying to figure out the best way to make all that work together. I have a say a :current-page key in the db, when you first hit the app it’s set to :login. in my login sucess handler event, I want to set :current-page :home. So that works fine of course, and my ‘top’ render function displays the current page, etc etc. But the url hasn’t changed at that point. So i guess that’s the real question. Should be calling (set-hash..) or (dispatch.. as a co-effect or something ?

mikerod03:03:52

@eoliphant you can also ask about re-frame in #re-frame and you may get more insight. If it is re-frame oriented of a question. Just in case you didn’t know

eoliphant03:03:24

yeah i just thouught I should maybe post it there lol

gadfly36103:03:43

@eoliphant I'd create a new effect (not a coeffect)

gadfly36103:03:02

(defn- scroll-to-top! []
  (.scroll js/window 0 0))

(defn- set-hash! [hash]
  (set! (.-hash (.-location js/window))
        (str "#" hash)))

(rf/reg-fx
 :set-hash
 (fn [hash]
   (set-hash! hash)
   (scroll-to-top!)))

eoliphant03:03:50

ah, havent really messed with my own effect handlers so far. ok cool thx. So though, that would be ‘called’ from the map returned by an event-fx ?

eoliphant03:03:26

one more quick question 😉 this my current handler

(reg-event-db
  :set-active-page
  (fn [db [_ page]]
    (assoc db :page page)))
That I’m going to change to a -fx, with this update of the db + a :set-hash key/val. so all good. But my routes dispatch the same event.
(secretary/defroute "/login" []
                    (rf/dispatch [:set-active-page :login]))
so is that going to cause some sort of infinite event loop?

gadfly36103:03:58

I'd separate them. Have an event-fx that sets just the hash ... And then have your route dispatch to set the active page like you have it

eoliphant03:03:36

ah right ok, that makes more sense

athomasoriginal15:03:42

Hey all, I have a question about dynamic children and passing keys: In React, one could do this:

var ResultList = () => (
      <ul>
        {this.props.results.map(function(result) {
           return <ResultItem key={result.id} result={result}/>;
        })}
      </ul>
);

var ResultItem = () => (
      <li>return {this.props.result};</li>
);
Notice that ResultItem in ResultList is being passed a prop of key but the ResultItem itself does not specify how to use the key prop? How would a similar pattern be done in reagent?

athomasoriginal15:03:32

hmmm it seems that the way to make this happen would be

(defn result-list 
   []
   [:ul
     (for [item items)
        ^{:key (:id item)}
        (result-item )])

athomasoriginal16:03:41

Do I have to use the meta macro or is it possible to pass :key as an argument like in react? For example:

(for [item items)
    (result-item {:key (:id item) } )])

curlyfry16:03:54

@tkjone As far as I know, using the meta variant is the idiomatic/most common way of doing this

curlyfry16:03:16

From https://reagent-project.github.io/

(defn lister [items]
  [:ul
   (for [item items]
     ^{:key item} [:li "Item " item])])

athomasoriginal16:03:13

Yeah, I saw that way of doing it..it just struck me as out of place considering that it looks so different from how arguments would be passed, but I can see that it is just an idiom I would need to get used to

curlyfry16:03:31

I'm a lot more used to reagent than react at this point, but I quite like the separation. 🙂 The :key is metadata that react uses for optimization, and the arguments to the function/component are the ones that it actually uses to render itself.

curlyfry16:03:36

Also, a heads up: You'll want to use square brackets rather than parens when calling reagent components to avoid unneeed re-rendering: https://github.com/reagent-project/reagent/blob/master/docs/UsingSquareBracketsInsteadOfParens.md

jmckitrick16:03:58

What’s the best way to run a reagent app in production? I’ve always started with a full-stack template, but this is just a re-frame app, so there’s no jetty built in.

justinlee16:03:36

@tkjone I suspect it is done that way because “props” are optional in the reagent paradigm. If the first argument is a map, then it is treated as “props”. I suspect the meta variant is done so that you can skip the props map if you need to.

athomasoriginal16:03:23

That makes sense. Its one of those React->Reagent things I need to wrap my head around

athomasoriginal16:03:30

The distinction is actually nice

athomasoriginal16:03:03

Because I imagine it would be odd for beginner to see that key is passed as a prop, but never explicitly used in the component it is being passed to

justinlee16:03:48

@jmckitrick I don’t think there is anything specific to reagent in terms of running it in production. I will run mine on express but that’s because I have a JS api server already.

justinlee16:03:16

yes i agree, the way key is used is strange

justinlee16:03:16

I actually hate that reagent calls itself a “simple react binding” or whatever it says on the readme. Reagent is quite complicated and subtle. The code you write is elegant, but pretending it is simple is a mistake.

jmckitrick16:03:45

@lee.justin.m I guess my question is how to start the project in production mode locally. Silly question, I know, but I’ve not deployed front-end-only apps before.

justinlee16:03:40

well that’s more a question of what tool chain you are using. i use shadow-cljs, so I’d ask for a release build, which will create a javascript bundle that I can just copy to the public resouces directory of an express server

justinlee16:03:54

lein should have some way of doing a release too.

justinlee16:03:40

if you use jetty, I think some folks like to make an uberjar, which zips up your built code and all static resources (html, images, etc..).

justinlee16:03:09

I don’t use java if i can help it so you’ll have to do some investigation on that

jmckitrick16:03:15

Ah, I think I found something…

jmckitrick16:03:26

I appreciate your help!

camachom19:03:23

hello! running into some issues getting a component to re-render based on state changes

camachom19:03:14

the value of the input field is re-rendered (using reagent form), but the :class key seems to only run once.

justinlee19:03:18

@mcama200 are you sure the state is getting updated the way you think it is? try sticking a (js/console.log error) as the first line of the let block just to make sure

camachom19:03:27

yeah I gave it a try. It only logs onMount. However, I can see the state changing by printing it in a parent component and checking out the atom in my repl

justinlee19:03:03

how are you calling input?

justinlee19:03:00

this should work. you are derefing the state ratom in your render function, so any update to any part of the state ratom should cause input to re-render

camachom19:03:45

okay cool i'll give it a try

camachom19:03:19

i gave it a try. brakes the form

camachom19:03:34

the readme suggest you use ()

camachom19:03:00

the second paragraph under "important note"

justinlee19:03:51

i don’t know what that’s doing. this is something specific to reagent-forms.

justinlee19:03:00

maybe somebody else can weight in

camachom19:03:33

thanks for your help!

justinlee19:03:55

oh. change those calls to inputs to use square brackets

justinlee19:03:21

same thing with the dropdown