Fork me on GitHub
#hoplon
<
2015-10-31
>
micha00:10:56

@thedavidmeister: because loop-tpl only sees the first form in the body

micha00:10:05

you would want to wrap those in a div

micha00:10:08

or a span

micha00:10:12

or something

micha00:10:48

each item in the bindings data must correspond to a single element that will be inserted and removed from the dom

micha00:10:53

in your case it's the input

micha00:10:27

(loop-tpl :bindings [n test-values]
  (span
    (input :value n)
    (br)))

thedavidmeister00:10:49

but i can’t use something like comp

thedavidmeister00:10:52

i have to wrap it?

micha00:10:52

you can wrap in a vector, i believe

micha00:10:04

tat will splice them in

micha00:10:50

i forgot if that worked or not simple_smile

thedavidmeister00:10:05

not ideal to have the DOM need to fit the framework

thedavidmeister00:10:56

(loop-tpl :bindings [n test-values]
      [(input :value n) (br) (text "foo")]))

thedavidmeister00:10:46

i’m definitely learning in baby steps here >.<

thedavidmeister08:10:58

(def test-values
  (cell ["foo" "" "bar"]))

(defn remove-empty-values
  [values]
  (filter seq values))

(defn append-empty-value
  [values]
  (conj values ""))

(defn prepare-values
  [values]
  (append-empty-value
    (remove-empty-values values)))

(swap! test-values prepare-values)

(print test-values)

(e/outer-dom
  (loop-tpl :bindings [n test-values]
      [(input :value n) (br)]))

thedavidmeister08:10:32

that produces a DOM with an empty input first, then foo and bar in subsequent inputs

thedavidmeister08:10:55

if i change “prepare values"

thedavidmeister08:10:04

(defn prepare-values
  [values]
  (append-empty-value values))

thedavidmeister08:10:25

which just doesn’t run filter then i get the empty input last

thedavidmeister08:10:34

which is what I want

thedavidmeister08:10:55

so I’m a bit confused as to how filter and conj interact with a cell

mynomoto11:10:20

@thedavidmeister: yeah, conj insert values last when the collection is a vector and first when it's a list.

thedavidmeister11:10:39

@mynomoto: i do have another q though

thedavidmeister11:10:47

(def state
  (cell [
    {:data "foo"}
    {:data "bar"}]))

(loop-tpl :bindings [i state]
    [(input
      :value i
      :type "text")])

thedavidmeister11:10:05

the value for my input ends up being a string representation of those sets

thedavidmeister11:10:23

how would I get the :data from the state into the input as a value?

thedavidmeister11:10:45

(loop-tpl :bindings [{data :data} state]
    [(input
      :value data
      :type "text")])

mynomoto12:10:43

@thedavidmeister: Yeah, this last one is the way to do what you want. Are you new to clojure too or only to Hoplon?

thedavidmeister12:10:06

it’s a little tricky to know what’s hoplon and what’s me just being a beginner

mynomoto12:10:21

You can always ask here, people are amazingly helpful.

thedavidmeister12:10:35

albeit, often not in my timezone 😉

thedavidmeister12:10:04

i’ve got a list of inputs and i can make a state vector

thedavidmeister12:10:14

and all the sets in that state vector end up in the inputs

thedavidmeister12:10:22

wondering how to go back the other way

thedavidmeister12:10:00

so if i update an input in the DOM, have that value go back into the data in the state cell

thedavidmeister12:10:24

assoc-in looks like it might do the trick

mynomoto12:10:35

@thedavidmeister: there is two ways I would use.

thedavidmeister12:10:35

but i’d need to get the key lined up against the input somehow

mynomoto12:10:42

yeah, assoc is one way. To get the indexes you want to use map-indexed

mynomoto12:10:44

Another would be something more like https://github.com/hoplon/demos/blob/master/counters/src/index.cljs.hl#L10 where you have local cells and can change them.

thedavidmeister12:10:36

yeah, i was thinking about that

thedavidmeister12:10:55

but later i’m going to want to export the state of all the inputs

thedavidmeister12:10:11

or nest it or something

thedavidmeister12:10:29

so the global state like what’s in the todo app example looked OK for that

thedavidmeister12:10:47

it used update-in but i don’t quite grok how to do the indexing yet

thedavidmeister12:10:55

like, as a small example, i want to add a new, empty input to the list of inputs if all the current inputs have data in them

mynomoto12:10:01

Do you have a public repo with the current state of your code?

mynomoto12:10:43

(defc= indexed-state (map-indexed (fn [idx itm] [idx itm]) state))

thedavidmeister12:10:30

yeah i do, but “current state of my code” is basically what i posted

thedavidmeister12:10:35

it’s all foos and bars and messing around atm

mynomoto12:10:54

Give me the link, I will take a look

thedavidmeister12:10:25

@mynomoto: eeeey that indexed thing did an index

thedavidmeister12:10:53

i’m just reading over the todo app now simple_smile

thedavidmeister12:10:01

now that you pointed out the map-indexed i see it in the todo app as well

thedavidmeister12:10:32

that probably would have taken me all of tomorrow lol

thedavidmeister12:10:46

i was just printing % and @% in :change

thedavidmeister12:10:49

to see what that does

mynomoto12:10:58

So % is the argument of the function when we use the #(...) syntax for anonymous functions.

thedavidmeister12:10:26

yeah i knew that much

mynomoto12:10:27

In case of the handlers, it's an jquery event.

thedavidmeister12:10:01

yeah but the event has been changed somehow?

thedavidmeister12:10:08

to be like, clojurified or somethign?

mynomoto12:10:11

So @ is sytax sugar for deref

thedavidmeister12:10:24

or is that just the way the event looks when you print it?

thedavidmeister12:10:16

oh, i just moved it from :change to :keyup

mynomoto12:10:10

It shouldn't change probably printing it cause the changes, try using (.log js/console ...) to check if it is what you expect..

thedavidmeister12:10:27

yeah that makes more sense

thedavidmeister12:10:38

so deref on a jquery event = a value of an input?

mynomoto12:10:41

On Hoplon, deref an event will get you it's value.

mynomoto12:10:52

yeah, that's it.

thedavidmeister12:10:25

so that would work differently for different DOM elements i presume?

thedavidmeister12:10:33

like, inner text for a div or somethign?

mynomoto12:10:02

Not sure about div, but it works for text areas, selects, radio buttons if I'm not mistaken. The inputs demo has some examples.

mynomoto12:10:47

Also since you are learning clojure, not sure if you found this yet: http://jafingerhut.github.io/cheatsheet/grimoire/cheatsheet-tiptip-cdocs-summary.html

mynomoto12:10:05

I have it open on my browser at all times.

thedavidmeister12:10:02

ok, so tomorrow i’m going to try to deconstruct all the things you did in my head

thedavidmeister12:10:29

and figure out how to make the delete key shift the focus to the preceeding input if the input is empty

thedavidmeister13:10:19

@mynomoto: are idx and itm idiomatic for “index” and “item”?

mynomoto13:10:54

@thedavidmeister: not really, there is no real convention for those, I just copied from the example. I usually like full names more.

thedavidmeister13:10:24

uses less brainpower when reading over it later

thedavidmeister13:10:48

oh, except “index” is a function apparently

mynomoto13:10:49

You can use it anyway, on clojurescript there is problems if you use window as a variable name 😕

mynomoto13:10:16

But for clojure functions you can do without having problems.

mynomoto13:10:54

lol, i thought it was surprising when I took hours to find out what was going on 😛

thedavidmeister13:10:35

yeah, i had something similar with trying to use loop-tpl without a wrapper div

thedavidmeister13:10:08

just spinning my wheels

thedavidmeister13:10:32

so, why do we have to deref i in :keyup #(swap! state assoc-in [@i :data] @%)

mynomoto13:10:52

As a rule of thumb you always deref when using a cell on a callback function. The reason is that on Hoplon the ui knows when cell changed to update themselves, but callback functions are just ordinary functions with no knowledge about cells. If they need the value that the cell contains you need to deref it.

thedavidmeister13:10:19

oh, that sounds important

thedavidmeister13:10:25

is that documented somewhere?

mynomoto13:10:55

Not sure, we have been updating the wiki with docs but I don't know the current state.

thedavidmeister13:10:33

the chat has been the most helpful source of info so far

thedavidmeister13:10:44

but the references do help too

mynomoto13:10:47

We had more docs on the old http://hoplon.io probably worth to dig it out and add to the wiki if it was not done yet.

thedavidmeister13:10:57

so, i tried this to get the keyCode from the jQuery object

thedavidmeister13:10:58

(prn (:keyCode %))

thedavidmeister13:10:29

not to be confused with null, lol

mynomoto13:10:12

you probably need (.-keyCode %)

mynomoto13:10:29

javascript objects are not the same as clojure maps

thedavidmeister13:10:47

so what does that do?

mynomoto13:10:48

This is for interop with javascript. If you want to access a property you do (.-property_name obj)

thedavidmeister13:10:24

so .- is something hoplon specific?

mynomoto13:10:35

If you want to call a function you do (.function_name obj arg1 ...)

mynomoto13:10:49

No, that's for clojurescript in general.

mynomoto13:10:39

(.-which %) is what I use for getting the keycode

mynomoto14:10:45

To differentiate between properties and functions. You can have both with the same name on the same object on javascript.

thedavidmeister14:10:06

and is there a hoplon way to trigger events, like a focus

thedavidmeister14:10:16

or would i have to run that through JS too?

mynomoto14:10:00

There is but you need to extend the do! multimethod.

thedavidmeister14:10:24

sounds like something for tomorroe

mynomoto14:10:13

Yeah, small steps that you understand it the way to go I think.

thedavidmeister14:10:49

learned a heap today

mynomoto14:10:17

You are welcome. simple_smile

mynomoto15:10:23

How are you doing?

micha15:10:59

pretty good, how about yourself?

micha15:10:14

lot of traffic in here lately

mynomoto15:10:12

I'm good too. Yeah, maybe the new site is helping?

micha15:10:30

how's work going? i've been pretty busy lately

micha15:10:45

sorry i haven't had much time to hang out

mynomoto15:10:54

I'm changing jobs at the moment, going to another startup try to spread clojure/hoplon to more places simple_smile I also have been busy over the last weeks.

mynomoto15:10:17

You did lots of work on boot over this last week no?

micha15:10:53

the latest changes will make it much easier to implement future improvements and add features without breaking anything

micha15:10:10

because the same binary can load any version of boot now

micha15:10:16

with no compatibility issues

mynomoto15:10:45

Yeah, that's pretty cool!

micha15:10:52

so that should reduce the amount of work needed to integrate fixes or new features

micha15:10:20

i hope to take a short sabbatical in a little while

micha15:10:25

like a month maybe

micha15:10:35

to concentrate on the hoplon stuff

mynomoto15:10:04

What do you want to change/improve?

micha15:10:33

i want to make defelem+ a real thing, and get to the bottom of performance issues

micha15:10:59

the defelem+ thing will require devising some solution to the javelin garbage collection problem

micha15:10:33

and documentation, and things like that

micha15:10:04

maybe work on heroku buildpack?

micha15:10:34

i'll look at the issues and work on anything i find there too

mynomoto15:10:46

Yeah, documentation is important. I will try to help with that. Ask things doesn't scale well enough

micha15:10:05

with boot the wiki has been really successful

micha15:10:15

but we had to seed it with some key articles

micha15:10:31

i think we can do the same thing with hoplon, probably

mynomoto15:10:59

I will try to move what we had on http://hoplon.io to the hoplon wiki. It was not much, but way more than we have now.

micha15:10:29

that would be great, totally

micha15:10:59

it'll be good in the wiki, more people able to edit it

mynomoto15:10:13

The advantage that those had was that I wrote part of it when I was learning. So I did all the drills. Needs some updating but not excessive I think.

mynomoto15:10:24

Yeah, wiki is better for that.

micha15:10:00

yeah i think like people will come in and write a bunch of pages in the wiki while they're learning and find things that confused them

micha15:10:09

when enthusiasm is at its peak simple_smile

micha15:10:37

and over time the documentation converges to this awesome format

mynomoto15:10:27

I was having castra troubles last week trying to update a project to 3.0.0. I will try to debug them, but the crazy thing is that it worked for some usernames and failed for others. Is there a easy way to debug session problems there?

micha15:10:53

which session engine are you using?

mynomoto15:10:57

Practical documentation is the best one. Real problems only simple_smile

mynomoto15:10:02

The castra one

micha15:10:10

that one uses localstorage

micha15:10:16

so that could be an issue?

micha15:10:37

i made that for CORS stuff

micha15:10:56

i was having all kinds of weird issues with cookies being rejected by the browser

mynomoto15:10:08

Not sure, I stopped when I could reliable replicate the problem for one user but others would just work. Session would be nil on some cases

micha15:10:14

the browser doesn't give any way to know why it rejected them

micha15:10:38

does the browser have stuff in localstorage?

micha15:10:45

and does it send it back via headers?

micha16:10:48

also are you sure that the server is sending the session to the client? you should see it in the response headers

mynomoto16:10:50

I will try to pin the issue, but sometimes it didn't.

micha16:10:05

i guess i'd start debugging it by looking at the headers

micha16:10:10

and localstorage

mynomoto16:10:26

Ok. You use localstorage or sessionstorage?

micha16:10:37

localstorage

micha16:10:15

that's so it persists across tabs etc

micha16:10:28

like if you're logged in and you open a new tab you should be logged in there too

micha16:10:42

and logging out of a tab should log you out of all other tabs also

micha16:10:10

i had so many annoying, time consuming problems with CORS and cookies

micha16:10:26

i'd get it working and then some client would have problems

micha16:10:50

and i'd have to go to stackoverflow and try to guess what weird thing i have to do

micha16:10:08

so the castra session middleware bypasses that whole thing

micha16:10:23

since it's only used with castra, that means it's only ever POSTs

micha16:10:41

and castra requires the special CSRF header

micha16:10:08

so i think it's as safe as session cookies

mynomoto16:10:54

Ok, thanks. I will look into it

micha16:10:38

if you have a repo that can demo the problem i can have a look on monday

mynomoto16:10:58

I have to figure out if it's state dependent yet, it sure looks like it. Probably something I'm doing. But thanks for the offer.

micha16:10:02

my pleasure