/reagent-phonecat

(MOVED) - The official AngularJS 'Phonecat' tutorial ported to a ClojureScript + Reagent stack.

Primary LanguageClojureEclipse Public License 1.0EPL-1.0

THIS TUTORIAL HAS MOVED!

It's now here: https://github.com/vvvvalvalval/reagent-phonecat-tutorial/wiki.

Reagent Phonecat

The official AngularJS 'Phonecat' tutorial ported to a ClojureScript + Reagent stack.

This project is based on the Reagent Leiningen template, which has the following workflow:

lein deps # installing the dependencies

lein figwheel # compiling clojurescript and serving the files with a development server
## you can now visit the running app on [localhost:3449/#/](http.//localhost:3449/#/)

## Optional: starting a ClojureScript REPL
lein repl # starting a Clojure REPL
>reagent-phonecat.handler: (browser-repl) # starting the ClojureScript REPL

See here for more information.

You can see the code for each step in the tutorial by git-checking out the corresponding branches (step-1 to step-12). Please note that:

  • step-11 has not been implemented, since I have not found an equivalent of ngResource for ClojureScript
  • step-12 (animations) is currently in a quite experimental state, suggestions appreciated.

About the tutorial

The original tutorial consists of writing a small Single Page App that is a catalog of Android devices, featuring templating, data-binding, AJAX, routing, and some AngularJS-specific topics.

Here are some links to help you navigate efficiently through both implementations:

Implementation overview

Librairies

Design choices

Except for UI state with limited scope, all the state of the application is held in a global atom, that acts notably as a partial copy of the database. Ajax calls are used only to populate and update this atom. While the drawbacks of global state are well-known, I feel there are several things in this configuration that mitigate them:

  • Combined with ClojureScript livecoding capabilities, having all the state in one accessible place makes it easy to debug and reason about your stateful app
  • Reagent cursors allow us to decouple view rendering/interactions from state storage
  • React components enable you to build the view incrementally, with much finer control flow than the one-step controller->view relationship you typically find in Angular apps.

Navigation is done by keeping the current page component (i.e a function) and the associated route params in the state. This does not feel very neat, I'd rather have only the location hash in the state, but from what I've seen I don't think that's easily compatible with secretary currently.

Everything is in one namespace, splitting it felt like an overkill since there are only about 200 LoC at most.

Contributing

This is my first try at Reagent, and many of the choices I made are questionable. Comments, critics and suggestions for improvement are appreciated and encouraged.