top | item 7906777

(no title)

w01fe | 11 years ago

Engineer @ Prismatic here. I'm happy to answer any questions about the post or our experiences with the rewrite.

discuss

order

dkersten|11 years ago

An Om question: what do you store in the app state and what do you store in component local state?

In my own application, I started off storing everything in app state, using local state only for short-lived transient data, but over time I found that having a bunch of information like what tab is currently visible in the app state became difficult to manage and made the app state a nightmare. So now I like to keep a strict separation: app state is basically my model - the data being processed (if I were writing a text editor, its the document being edited) and local state is everything else: which dialog is open, which tab is selected, button toggle state, mouse state etc (in a text editor, whether bold is selected, whether I'm in print preview mode or edit mode, etc). Basically app state is what is being processed and local state is how to process or display it. This separation also means that the app state is what gets synced with the server. I like to think of it as "if its something I might want to persist in the database, then it lives in app state, if its something I would never want in the database, then it lives in local state"

I'm curious what other peoples experience with this is.

Another Om question: how do you sync state between client and server, or how do you handle communication?

I looked at how om-sync does this (using tx-listen to automatically sync changes), but ended up building a more traditional request/response model using sente[0] and having my app ask for sub-trees of my app state as needed. Again, just wondering about peoples experience with this and different approaches tried.

[0] https://github.com/ptaoussanis/sente

w01fe|11 years ago

We're still figuring out exactly where the boundary lies, but our current approach is much like yours -- view state that's purely local to a component goes in local state, and everything else goes in app state. This feels more natural, but means you lose some of the nice benefits of things like replay/undo for this local state.

For client/server, we've started building up some nice abstractions around our API (like fetching more data in a generic paginated list stored in a cursor), but the write side is still mostly manual. We're trying to use the same API for iOS and web, which probably prevents us from doing some fancier things that continue the same architecture back into the server.

dustingetz|11 years ago

I put viewmodel state with the app state - my app state basically is viewmodel state, domain state source of truth is the database really, so you need to do ajax to traverse the domain object graph, its not stored on the client.

Just like you want to control a react.dom.input, you also may want to control a tabstrip. Maybe you have some biz logic that says "When you click save, select the next record, and if record.type===2, select the third tab". You never know in advance what state needs to be controlled from the top, I found myself refactoring my viewmodel state higher and higher.

The mouse state is never going to be controlled from the top, so that is component local state.

RoboTeddy|11 years ago

It sounds like you're differentiating between model state and view model state.

I haven't used Om yet, but a potential approach could be to maintain two stateful objects: one for the model (e.g. stuff that you'd persist permanently), one for the view model (e.g. which tab is selected).

If you wanted your app to come back to exactly the same state after a page reload, you could persist the model in databases, and the view model in browser local storage.

cnp|11 years ago

#1 is a great question that I've been curious about as well, particularly for larger UI's

Arcanum-XIII|11 years ago

Maybe a stupid question, but since I didn't see anything about that : what kind of database do you use, and how is it with Clojure ? React + ClojureScript seem a given for me on the interface side, especially with core.async and the other possibility, but I'm a bit more weary for the server side, and that's one of the last showstopper I have.

And, how do you go for teaching new comer on the project ? I do suppose you don't only hire Clojure or functional dev, so the transition part seem very interesting, especially with Om getting more (deserved) attention !

ds_|11 years ago

This is also something I'm curious about, particularly how migrations are managed within a team. Most of the solutions I've seen require writing plain SQL in migration files which you name yourself. It's simple but I miss the productivity of DjangoORM or ActiveRecord for example. Or do most people use a schema-less database?

presty|11 years ago

not talking for OP

most popular databases have native libraries developed by the community (postgres, redis, mongo, etc)

but since Clojure runs on top of the JVM, you can probably access any database through the Java World

stu_k|11 years ago

What do your "templates" look like, and how easy they are to edit? In Montage we've kept our templates as close to plain HTML documents as possible, and the CSS experts/designers we've worked with have really appreciated how easy it is to understand.

I'm wondering if this is an issue for you (or perhaps everyone is comfortable enough with the ClojureScript/Om syntax that this isn't a problem)?

bguthrie|11 years ago

Strategically, how did you approach the rewrite? It sounds like you had a significant amount of frontend code; replacing everything at once can be risky. Did you choose specific pages and work your way in, or scrap everything and work your way from the inside out?

fdsary|11 years ago

I'm a Javascript/Python/Ruby professional, and have made a few really swell SPA's in JS.

But my dream is to be a really good Clojure(Script) lisp programmer. I'm not so good at any lisp, but have went thru a couple of books, try to do every tutorial and to play in the LightTable instarepl and implement things that I can easily do in JS.

How can I, who am far from a lisp pro, get a job in a lisp/clojure shop? I think by doing something 8h/day in a team is the best way to learn, but of course no one will hire you if you slow down the rest (at least in the beginning).

lsb|11 years ago

How do you deal with propagating events through the system? If I'm clicking Follow as people are following and unfollowing, how does that number change?

loganlinn|11 years ago

Clicking follow mutates the global app data. Changes to the app data causes the entire application to re-render, and React pushes those changes out to the DOM.

So, to answer your question, we don't propagate events :)