Fork me on GitHub
#om
<
2016-03-27
>
anmonteiro11:03:17

@donavan: try using db->tree instead of (into [] (map #(get-in st %)) (get st key))

donavan11:03:31

Ah! Merci... My understanding of what's going on is the problem then! Though now I see another issue... do ids need to be unique across all react components? Unlike, say, SQL where an index is unique per table?

cjmurphy11:03:19

Yes need to be unique across all components. Or that's what I've always assumed since reading the Kanban demo. Your initial data for instance probably has lots of say {:id 10}. The algorithm that gets your data normalized in the first place would certainly have an easier job if all the numbers were unique. But I'd be keen to know the real reasoning behind this requirement.

donavan12:03:29

It seems to me to be a React requirement . I get a lot of react.inc.js:18780 Warning: flattenChildren(...): Encountered two children with the same key, '$1'. Child keys must be unique; when two children share a key, only the first child will be used. One for each key that is duplicated across sub-components even though they are of differing component types. (edited grammar and removed backticks from error msg)

cjmurphy13:03:52

I missed the word React before. So here: (def simple-svg-tester (om/factory SimpleSVGTester {:keyfn :id})), :keyfn is what React gets.

cjmurphy13:03:15

But React does not need them to be unique across your whole app-data - that's an Om Next default db format requirement.

donavan14:03:08

It does seem to be a React requirement (caveat: I'm learning React via Om!) http://facebook.github.io/react/docs/reconciliation.html#keys Though they need to be unique amongst siblings, which is exactly what I did as I worked through my dummy data, each sibling (of differing component types) got the same key id from 1...n. I was thinking like SQL indexes, i.e. unique per table/type! It seems to me that Om doesn't have the requirement because things are identified by [:key id] and not just by id. Though you still can't have the same key (component type) and id as then the the app state map will eat all but the last one when assoc'ed in (if that's how it adds to the normalised map, that is)

haywood15:03:07

you can inspect the dom to see the keys om gives to components

haywood15:03:41

in my experience it works the same way as react, where the id is prefixed with a component name, like how you described

frank16:03:51

is there an easy way to add to the normalized app state? right now I'm adding a row to the db and then adding an ident elsewhere in two separate swaps

frank16:03:08

(defmethod mutate 'people/add-person [{:keys [state ast]} _ params]
  {:action (fn []
             (let [id (random-uuid)]
               (swap! state assoc-in [:people/by-id id] (merge params
                                                               {:db/id id}))
               (swap! state update :people conj [:people/by-id id])))})

anmonteiro16:03:46

@frank: you definitely don't need to swap! twice

anmonteiro16:03:34

(swap! state
  (fn [st]
    (let [st' (assoc-in st [:people/by-id id]
                (merge params {:db/id id}))]
      (update st' :people conj [:people/by-id id]))))

anmonteiro16:03:06

the two operations are still required, though

frank16:03:38

yeah swapping twice is silly

frank16:03:33

ah so two operations are still required.

donavan16:03:12

@haywood, I just changed all my dummy data keys to be unique. It all renders correctly now. I looked at the React IDs and all the components have a $null in them, should they have the component name in them as you say?

haywood17:03:40

interesting

haywood17:03:45

that doesn't seem right

haywood17:03:03

looking at the react id for a nested element in my toy app looks like reactid=".0.1.$tiles$core$Grid_[=2tiles/grids 3].$tiles$core$TilesRow_[=2tiles/grids 3 =2rows 0].$tiles$core$Tile_[=2tiles/grids 3 =2rows 0 =2tiles 6]"

haywood17:03:20

are you using defui?

haywood17:03:11

oh sorry, was responding to @donavan

haywood17:03:27

it is correct

haywood17:03:36

are there any 'easy' tasks that need to be done in om.next, that a mild beginner could tackle?

haywood17:03:43

I'd love to contribute @anmonteiro

anmonteiro17:03:30

@haywood: there is something

anmonteiro17:03:42

there's this macro, invariant

anmonteiro17:03:14

we have talked about using it more in the code, where it makes sense, just like React does it

anmonteiro17:03:31

to help catch rookie mistakes

anmonteiro17:03:18

things like validating query grammar

anmonteiro17:03:28

detecting if queries are correctly composed

anmonteiro17:03:35

those are all useful things

cjmurphy17:03:05

@donavan: Those $null mean React is not able to get a key to use for your component. This is not particularly a problem unless you have many components together at the same level. But it is possible to have no $null for any components - a clean slate. React needs to know the function (example: {:keyfn :id}). Then the function needs to be in your query - i.e. be what is passed in as props.

donavan17:03:26

@cjmurphy: @haywood Ok, I do have {:keyfn :id} as the second arg to om/factory... I'll have to have a look in the morning. Thanks for all the help. simple_smile

tomjack20:03:24

wondering how to go about 'polling a remote' to keep results fresh

tomjack20:03:59

for now I have (om/set-query! this {:params {}}) in my component to redo all the sends

tomjack20:03:19

I could hang onto the cb in send, but it seems I will never be told to stop polling

anmonteiro20:03:32

@tomjack: using websockets, I suppose?

tomjack20:03:56

no, polling an existing REST endpoint

anmonteiro20:03:54

you can still push it to the edge by polling the REST somewhere and calling om/merge! on the results

tomjack20:03:46

yeah, thinking about that. I guess I need to keep track of "which data still needs polling" myself if I want to stop polling when that data is no longer needed

tomjack22:03:59

toy example: /lists returns todo list ids, /lists/:id/todos returns a list's todos. we should only poll /todo-lists/:id/todos for those lists which are currently being rendered

tomjack22:03:12

I guess TodoList can use componentDidMount, componentWillReceiveProps, and componentWillUnmount to communicate with some process which keeps track of the active lists, does the polling, and merges the novelty

tomjack22:03:37

but this means the thing doing the polling doesn't see the actual remote queries. fine in my case, but, hmm