Fork me on GitHub
#om
<
2015-10-22
>
abtv08:10:16

Can anyone give me advice about autosizing textarea? I use TextAreaAutosize component, it do what needed (auto resizing), but every time I type something there is a problem. First symbol from input takes a right position, but then caret position moves to the end of textarea. i use Reagent (reset atom value), but I think it can be some trivial error with React interop.

dvcrn09:10:40

@tony.kay: great wiki page!

dvcrn09:10:43

I have a feeling that :window/size [1920 1200] inside the examples might be related to me asking about something very similar a bit too often 😛

grav12:10:53

I have a working om-next component with a simple query. It’s the root component in the app. What do I have to do if I want to wrap it in a parent component? If I just do (defui MyRoot Object (render [this] ((om/factory MyQueryComp)))), and use that as root, I get an exception Uncaught #error {:message "No queries exist for component path (maps-fun.core/MyQueryComp)", :data {:type :om.next/no-queries}}

dnolen13:10:06

@grav it cannot be the root component if you’re going to wrap it something else

dnolen13:10:15

so that’s just not going to work

grav13:10:22

Sorry, to be more precise, I have it working as a root, but instead I want to wrap it in another component.

dnolen13:10:21

there’s just not enough information for me to know what might be going wrong then.

dnolen13:10:33

as it stands it just sounds like you’re doing something that’s not going to work

dnolen13:10:41

the example is too fabricated.

chedgren14:10:46

grav: Are you asking about nesting components?

grav14:10:02

nesting, not wrapping simple_smile

chedgren14:10:28

'(defui Person static om/Ident (ident [this {:keys [name]}] [:person/by-name name]) static om/IQuery (query [this] '[:name :points])) (defui RootView static om/IQuery (query [this] (let [subquery (om/get-query Person)] `[{:list/one subquery} {:list/two subquery}])))'

chedgren14:10:13

kinda like so? This is from the om.next wiki

grav14:10:16

@chedgren: kinda like so, except I don’t want my parent component to do any querying

chedgren14:10:36

Have you tried the naive approach? with just calling your component from the root?

grav14:10:22

@dnolen: It’s just a matter of nesting a non-nested component, Foo. First, it’s the only component and thus the root, and the query works fine. Then, I try nesting it in some trivial component (like (defui MyRoot Object (render [this] (dom/div nil ((om/factory Foo))))))) and it suddenly gives me an exception related to the component path

grav14:10:47

That gives me an exception Uncaught #error {:message "No queries exist for component path (maps-fun.core/Foo)", :data {:type :om.next/no-queries}}

txus14:10:16

hi there! I have a question about idioms in om.next

txus14:10:25

in my state I have a list of sections

txus14:10:18

and I’d like to add a “view” (now a UI view, but like a data view) over that state, to have for example a piece of data called active-section, where that is the first of thes ections which has :active true

txus14:10:43

same goes for users, I have a list of them and I’d like to have a :current-user which is just a user that has :authenticated true

txus14:10:45

is this a common pattern?

txus14:10:54

I’ve been trying but I haven’t gotten very far

txus14:10:01

(it’s my first day with om.next admittedly)

dnolen14:10:42

@txus that’s actually very easy to do om-next-demo has an example of that, i.e. the currently editing thing is exactly the same problem

dnolen14:10:08

om-next-demo repo on GitHub, very little documentation at the moment

txus14:10:28

oh nice! simple_smile I’ll check that out then

dnolen14:10:29

in general you’ll find little in the way docs, I’m too heads down fixing bugs and wrapping up the design

dnolen14:10:50

there’s some community effort happening here which will probably find it’s way back eventually

txus14:10:59

that’s alright, the om wiki is actually pretty good to get started simple_smile

dnolen14:10:28

@grav you can’t just put something with a query into some random component

dnolen14:10:45

the query path must exist, i.e. *somebody* has to get that subquery

txus14:10:18

@dnolen: I see in the example that your source of truth is a piece of data called :todos/editing, and then you project that into the todos when fetching them, assoc’ing :todo/editing if it’s the one. So you would recommend to have a separate piece of state, such as app/current-user {:user/id “827348728”}, to keep track of the current user right?

dnolen15:10:03

absolutely

dnolen15:10:23

doing it this way prevents all kinds of bugs

dnolen15:10:31

make impossible situations impossible

dnolen15:10:51

in the case of editing, it’s safety measure that guarantees only one thing could every be edited

dnolen15:10:04

and if somehow the impossible thing happens you know where to start looking

txus15:10:13

true, that is a very good thing

dnolen15:10:32

I haven’t had time to talk about this yet

txus15:10:35

I went with that approach then simple_smile now for some reason the reconciler doesn’t seem to normalize my data, but I probably messed something up

dnolen15:10:53

but the fact is that in Om Next you can always get the UI data tree

dnolen15:10:02

this means you have something to test w/o ever looking at anything

dnolen15:10:16

you can always test state transitions w/o QA’ing anything at all

dnolen15:10:34

this is the source of my statement Single Atom + Reified Mutations + Property Based testing = OMFG

dnolen15:10:02

basically the entire history of UI programming has prevented real testability

txus15:10:07

hahha omg that sounds amazing. you could property-based test the heck out of a UI!

txus15:10:35

no more “UI is too complex to apply real testing techniques to it so we’re going to hire a bunch of QAs” simple_smile

dnolen15:10:02

you still need to QA but you shrink the domain by an incredible amount

dnolen15:10:08

right now it’s just one giant crap shoot

dnolen15:10:39

now you can automate thousands of random operations

dnolen15:10:47

and prove only one thing can ever be in the edit state

dnolen15:10:06

well “prove” but you know what I mean

dnolen15:10:13

you don’t need a human clicking around for this

dnolen15:10:25

or f**king Selenium

txus15:10:27

yeah ugh

txus15:10:59

if you keep the button handlers to simple state changes, which is encouraged in om, clicking =~ om/transact!

txus15:10:15

and om/transact! you can automate, so there is almost no possible weird cases you cannot automate

dnolen15:10:31

you can much more than that

txus15:10:45

even receiving invalid/ malformed data from the server you can automate

dnolen15:10:48

[(friend/add {:id 0})]

dnolen15:10:04

you can now test that all friend lists are changed, that all friend counts are augmented

dnolen15:10:15

just by verifying the UI data tree reflects that change

dnolen15:10:41

I have a blog post brewing about this once we get to beta

dnolen15:10:50

I think saying this is huge is a pretty big understatement

dnolen15:10:58

I expect to be immediately copied everywhere

txus15:10:47

that would be great!

txus15:10:55

atm I’m rewriting a messy JS thing into om.next

dnolen15:10:15

well there be dragons for the next couple of weeks at least simple_smile

dnolen15:10:50

and a couple of api things may change, but they will probably be of the search/replace variety

txus15:10:33

that’s alright though, I’ll be on top of it for the next few months! my current client is pretty sold on om for almost everything UI, with plain React as a fallback

txus15:10:25

@dnolen: is the reconciler automatically supposed to normalize plain maps?

dnolen15:10:47

yes, the current wiki pages cover that

dnolen15:10:18

your data always has to be normalized

txus15:10:44

I must be doing something wrong

dnolen15:10:36

@txus did you actually go through the wiki bits? Definitely recommended if you haven't

dnolen15:10:51

if you pass an atom normalization is not automatic

dnolen15:10:58

it’s only automatic if you pass data

txus15:10:03

yeah, I did but it was quite a lot to take in, so maybe I should read them again simple_smile

dnolen15:10:15

you can pass :normalize to the reconciler if you pass an atom

txus15:10:25

yeah, they weird bit is that I pass in just data, and part of the data seems to be normalized in some calls to read, and part of it doesn't

dnolen15:10:31

yeah the tutorials are worth reading a couple of times

dnolen15:10:19

normalization is not automatic, your query and the UI components provide necessary information for that process

dnolen15:10:40

if something is not normalized then that information was not provided in the query

dnolen15:10:19

stuff like this is why parser normalize is all public stuff

dnolen15:10:39

so you can get this right without wasting time bothering with a UI

txus15:10:11

just to make sure, if I have this data: {:app/sections [{:section/id :foo, :section/name :bar}], :app/current-section {:section/id :foo}}, is it enough that the current section references just the id?

txus15:10:25

as long as the Ident is correct

dnolen15:10:40

it’s not enough

dnolen15:10:47

you query has to reflect this

dnolen15:10:18

but I probably wouldn’t organize my data that way

dnolen15:10:28

just put the ident there for :app/current/section

dnolen15:10:40

{:app/sections [{:section/id :foo, :section/name :bar}], :app/current-section [:section/id :foo]}

txus15:10:03

aha, and a vector! or is it irrelevant?

dnolen15:10:14

it’s just a convenience

dnolen15:10:30

because that’s how we build the normalized tables via Ident

dnolen15:10:45

{:section/id {:foo …}}

dnolen15:10:55

if the ident is a vector then we can use get-in for lookups

txus15:10:36

cool. thank you. definitely I need to have a look at that wiki again simple_smile

dnolen15:10:44

there’s nothing magical or special about this convention

dnolen15:10:02

it’s just a convention to make it simpler to do transactions and and projections on the client

dnolen15:10:20

no enforcement here, but not much value in not following it

dnolen15:10:34

Om Next is very much a "fix your problems by fixing the data” approach

txus15:10:35

actually, dereferencing the reconciler helps a lot debugging these things

mhuebert15:10:57

is there a way to add a property to an om/next React class in defui (eg. childContextTypes)?

dnolen15:10:41

and no plans for that either, would need a lot of rationale to venture into allowing fields which are not props or state.

dnolen15:10:30

(or children of course)

dnolen15:10:42

@mhuebert: also stuff like that is machinery that Om can provide itself and has in the past (very similar to shared)

dnolen15:10:55

and little value tapping into the React versions

dnolen15:10:12

they often have terrible assumptions about taking raw JS values

dnolen15:10:45

React has always been treated as a glorified renderer

dnolen15:10:05

about the only thing we do is make sure that pure reusable React components can be dropped in

dnolen15:10:18

but all the weird app structuring tools … not going to touch that stuff or support it

mhuebert15:10:31

@dnolen ok. I’m about to use the om/next reconciler / state-handling stuff for the first time and I’m sure things will be clearer in a few hours. I love the fact that defui outputs a plain React class & that all the lifecycle methods are easy to access - I had loads of trouble with all the various wrappers and all of those headaches have already vanished.

dnolen15:10:11

I think Relay may use context to magically pass tuff around and hide information

dnolen15:10:18

but I think this is utter crap

dnolen15:10:25

via context or something similar

dnolen15:10:33

as it destroys the testing stuff I talk about above

dnolen15:10:48

the fact that you can always get at the whole UI data tree is not something we’re going to part ways with

dnolen15:10:02

and Clojure has eliminated my interest in data hiding

roberto16:10:30

+1 for not interested in data hiding. It feels like a heavy burden is lifted from my shoulders when I don’t have to worry about that.

gary17:10:08

I do Om tutorials at night and then enterprisey monolithic framework server heavy jsp code during the day so I want to write an article comparing the two approaches. Also, an "Om for Enterprise devs" would be a really interesting talk. It's never too early to start working on the proposals for next years conferences

tony.kay17:10:21

@dvcrn: On window/size...yes, that was the inspiration simple_smile

dnolen17:10:51

@gary that would be an interesting talk! simple_smile

bostonaholic17:10:21

(inc <@U050C3ZHQ>)

tony.kay18:10:19

In Om Next: There is nothing technically preventing query parameters from changing the query structure (instead of just going into the grammar as parameters). From Quickstart: "The params method should return a map of bindings. These will be used to replace any occurrences of ?some-var in the actual query." Is the API intention that (set-params!) be used to change things that are targeted at parameters in the query grammar, and (set-query!) should be used when you want to change the structure? Or is it free-for-all whichever you need for the use-case? I can definitely see cases where you'd want some portion of the query to change (add in a join), such that using a parameter would be more surgical...though it is a bit of a misnomer.

dnolen18:10:10

there’s no problem with changing the query structure

tony.kay18:10:53

yeah, I could tell that from the source...just making sure there wasn't anything in the plans that would break that.

dnolen18:10:08

a query may need to change the view completely

tony.kay18:10:27

Yep. Just making sure you were not planning on making set-params! do something that would cause things to break if they were used in a non-params part of the query grammar.

dnolen18:10:59

the whole point of mutable set params & query is that recovers full dynamism if required

tony.kay18:10:12

I'm building docs around playing with the queries, and I don't want to mis-state how things are "meant" to work

tony.kay18:10:34

Yep. I totally get it. Just being careful with names of things when explaining them.

dnolen19:10:04

making lifecycle stuff work is a big pain in the butt - mutability ain’t fun 😛

zane19:10:29

++ to that.

zane19:10:03

While the most pleasant way to do that kind of testing is headless I enjoyed the video I saw somewhere of someone's browser UI iterating through all the potential states their property-based tests were generating.

dnolen19:10:55

@zane right but are you doing headless testing with React by looking at the DOM or something else?

zane19:10:39

Right now I'm not doing either. If I were to try it I'd just test the state transition functions on bare data.

zane19:10:45

Then perform assertions on the results of those transitions.

zane19:10:52

My rendering functions are not usually where my bugs are.

dnolen20:10:11

right that’s the testing model I’m talking about

dnolen20:10:46

pushed fixes for React lifecycle semantics

dnolen21:10:18

ok so I think I may have fixed the obvious problems with set-state! tire kicking of master welcome

dnolen21:10:29

now switching gears to work on unions in queries

dnolen23:10:56

OK union support in queries is pretty mind blowing

dnolen23:10:06

hilariously easy to implement simple_smile

dnolen23:10:33

Om 1.0.0-alpha4 released, unions in queries now supported

tony.kay23:10:41

Hey David, I'm seeing React warnings when I add getInitialState as a method under Object: Warning: getInitialState was defined on om_tutorial$core$ItemViewer, a plain JavaScript class. This is only supported for classes created using React.createClass. Did you mean to define a state property instead? that a known thing? Or am I doing it wrong?

dnolen23:10:57

just a bogus React warning

dnolen23:10:00

doesn’t mean anything

dnolen23:10:09

very annoying

dnolen23:10:22

might change the name of the method to avoid this, but it’s minor thing

dnolen23:10:41

just means more discrepencies between Om Next & React docs

tony.kay23:10:02

Oh, right! I see

dnolen23:10:18

I think this query unions thing will demonstrate just how powerful and flexible the query model is simple_smile

dnolen23:10:24

easy to see building very big apps this way