Fork me on GitHub
#re-frame
<
2016-06-09
>
escherize10:06:37

How do you know where in the app-db to put state for a component that's currently editing something?

escherize10:06:57

Like when a component is currently building up some datastructure

escherize10:06:10

and I want the state in the app-db rather than a local ratom

escherize10:06:59

Let's say I have a component that has some semi-transient state. Is there a best practice for where those semi-transient things should go?

seantempesta10:06:09

@escherize: ha. depends what you mean by semi. I’m inputing individual keystrokes into the app-db (for searching) and it’s going pretty well

escherize10:06:34

Let's say I have an "address card" or something with a few fields.

escherize10:06:43

Then I make a new one.

escherize10:06:59

I've half edited the card, where should that stuff go?

seantempesta10:06:12

I’d put it in app-db

escherize10:06:17

haha, me too

escherize10:06:29

but where if that makes sense

seantempesta10:06:34

My goal is to be able to restore the exact UI for a user from local-storage

escherize10:06:02

let's say I have this app-db:

{:addresses [{:name ...}...]}

seantempesta10:06:16

Well, if you were keeping your address card info in [:address-card] maybe put it in [:address-card :temp]?

seantempesta10:06:38

you can only have one “in-progress” address card, right?

escherize10:06:58

let's say, for the sake of argument that I can have n in-progress cards.

escherize10:06:16

maybe :editing? should go into one of the addresses.

escherize10:06:28

that may possibly break my db schema though.

seantempesta10:06:05

hmm, yeah there’s not really one right way to do this. I’m only using the app-db for UI state. I’m storing everything else in datascript and that’s made things a hell of lot simpler

escherize10:06:14

(def address (s/either {:editing? true, s/Any s/Any} {---address schema---}))

seantempesta10:06:21

I used to worry how to store the app state and now it’s always easily accessible

escherize10:06:40

That's an interesting approach

seantempesta10:06:57

Yeah, it’s quite wonderful really (IMHO).

seantempesta10:06:13

Especially because Posh can make all of your queries reactive

escherize10:06:24

you should make a todomvc 😄

seantempesta10:06:50

well, Posh has one for sure, but I don’t think they are using re-frame

escherize10:06:02

you're right they're not.

seantempesta10:06:40

I mean, I wish I could claim I’ve done something unique, but I’m just putting posh queries in my subscriptions

seantempesta10:06:00

(register-sub
  :participants-all
  (fn [_ _]
    (let [ds-query (q-tx @shared-db
                         [['_ :participant/firstName]
                          ['_ :participant/lastName]
                          ['_ :participant/photo]
                          ['_ :participant/dateAdded]]
                         '[:find [(pull ?e [:db/id
                                            :participant/firstName
                                            :participant/lastName
                                            :participant/photo
                                            :participant/dateAdded]) ...]
                           :where [?e :participant/firstName]])]
      (reaction @ds-query))))

seantempesta10:06:14

stuff like that

seantempesta10:06:12

then my app-db schema is super simple. {:search-query “asdf” :current-group 2 … }

escherize10:06:47

so you could just put that data where it would eventually go.

seantempesta10:06:07

not sure I’m following you?

seantempesta10:06:29

like in the app-db?

escherize10:06:39

or rather into your datascript db

seantempesta10:06:43

well, not really. that’s why I switched to datascript.

escherize10:06:47

sorry for the shifting sands 🙂

seantempesta10:06:01

I kept realizing I needed the data to be represented in different ways, but didn’t want to repeat it

escherize10:06:21

what are you building, out of curiosity?

seantempesta10:06:27

I got tired of re-writing all of my subscriptions because later on I’d realize the data was better stored in a different format

seantempesta10:06:46

it’s a membership database for after school programs, non-profits and schools.

seantempesta10:06:53

(super sexy I know)

escherize10:06:15

at least you get to use the sexiest tools right

seantempesta10:06:29

and I feel blessed for that

seantempesta10:06:44

I used to have to write in C#!

seantempesta10:06:43

I plan on open sourcing the general app I’m building. It’s been a pain to get this all running with react native, so if I can help someone else out I’ll be happy. Doubtful that will be anytime soon though. Sorry!

seantempesta10:06:33

Anyway, getting back to your question, if you stored that data in datascript then it’d be a lot easier. You’d have an address entity with a field pointing to an edited version. So then when you’re displaying the card you’d get both back and then it’s pretty obvious what you want to show in the UI.

seantempesta10:06:10

(keep in mind I’ve clearly drunk the kool-aid w/r/t datascript…and everything clojure related for that matter)

escherize11:06:47

Yeah I've dipped my toe in the datascript pool, but havn't jumped in (yet?).

fasiha14:06:53

@seantempesta: tell me more about re-frame + datascript! I'm using datascript to store data & run queries, but the connection is stored inside re-frame's app-db. And entirely by coincidence, because of that setup, all the UI stuff is in app-db, while my actual data is in datascript. Are you also storing the conn in re-frame app db?

fasiha14:06:53

That feels a little clunky because the subscription that returns the connection (an atom containing the actual db) has to be smarter than usual: I can't just return (reaction (:conn @db)) because the Datascript atom doesn't change "value" (only the object it references), and the reaction never returns

fasiha14:06:11

So I have this helper key in app-db, called :conn-heartbeat with an integer value, and whenever I transact on the Datascript db (changing it), I just inc the :conn-heartbeat. The subscription that returns the Datascript conn depends on both :conn and :conn-heartbeat, and returns both, so my views get hydrated with the Datascript conn properly

fasiha14:06:21

Seems really lame to me … ?

fasiha14:06:25

But it's working 😄

roberto19:06:38

if I needed something with a lifecycle, like a datascript connection, I would probably create a component for that. https://github.com/stuartsierra/component

roberto19:06:54

but that requires some more thought and maybe a re-architecture of your app