ReactJS – Flux with AltContainer

At my current employer,  I’ve been leading the team in our rich client side applications by using the ReactJS library.  ReactJS is very component oriented in design and has been quite flexible to use (as well as very fast!).

There are quite a few ways to architect out a ReactJS solution, as ReactJS is a ‘library’ vs. a ‘framework’.   Facebook recommends using the Flux Architecture when building ReactJS applications.   Keep in mind that ‘Flux’ is a pattern vs. another library or framework itself.  Many in the ReactJS community use Redux, and Redux is fine, however when looking for a solution for our projects we were quite pleased at the functionality that AltContainer provides.   Together with the react-router, it solves 90% of our project needs.

The core pieces to understanding of the Flux Architecture is to get a good understand of how it wants you handle your application view state.  Often times in applications we will retrieve data from the server, modify that data inside the view – and then resubmit that data back to the server.   Andrew Ray gives a good simple summary of what Flux is in his blog post ‘Flux for Stupid People‘ (quite a harsh title, but oh well!).   One of the keys is that data flows in one direction.  AltContainer provides a simple paragraph of Flux that should suffice for this article:

What is flux?

Flux is an application architecture for building complex user interfaces. It eschews MVC in favor of unidirectional data flow. What this means is that data enters through a single place (your actions) and then flow outward through their state manager (the store) and finally onto the view. The view can then restart the flow by calling other actions in response to user input.

(ref: http://alt.js.org/guide/ )

From here on out, I’m going to just describe how I built a screen that I thought best describes how ReactJS with Flux works, this article is not meant to be a walk-through tutorial.   (I recommend reading more on SurviveJS for a more tutorial deep dive).

An Example Workflow

Let’s take a look at the view I’ve built:

EditDoctor

This doesn’t look like much I know, but I’m going to focus on the ‘Facilities’ part of this screen.   In this application a doctor can have many facilities.  The data is brought down to the client, we fetch the initial data for the view by wiring up a call to our ‘Action’ in the react-router:   (by the way, I’m temporary using the hosted WordPress site and it appears it doesn’t support any code snippet formatting, so please bear with me!)

path:"edit-doctor/:doctorId", 
component:EditDoctor,
onEnter:next => AdminDoctorsActions.getDoctor(next.params.doctorId)

Already you can notice that we fetch our data through our ‘Actions’ – a core component of AltContainer.   Rather easy follow – when the path is matched, we load the ‘EditDoctor’ component with the data from our ‘getDoctor’ call.

Our ‘EditDoctor’ view is rather straight forward:

import {Component} from 'react';
import AltContainer from 'alt-container';
import ShowWhen from 'components/ShowWhen';

import AdminDoctorsStore from 'stores/AdminDoctorsStore';
import EditDoctorDetails from './EditDoctorDetails';

export default class EditDoctor extends Component {
    render() {
        return (
            <AltContainer store={AdminDoctorsStore}>
                <ShowWhen prop="doctor">
                    <ShowWhen prop="specialties">
                        <ShowWhen prop="facilities">
                            <EditDoctorDetails />
                        </ShowWhen>
                    </ShowWhen>
                </ShowWhen>
            </AltContainer>
        )
    }
}

Just to understand what is happening here – the AdminDoctorsAction fetches the data and dispatches to the store when the data is ready.

First we generate the actions

class AdminDoctorsActions{

    constructor(){
        this.generateActions(
            'getDoctorWithSpecialtiesSuccess'
        );
    }
export default alt.createActions(AdminDoctorsActions);

Then we create our action (simplifying the ajax call here…)

getDoctor(id) {
    return (...).
then(axios.spread((doctorsResponse, specialtiesResponse, 
facilitiesResponse) =>{
        this.getDoctorWithSpecialtiesSuccess({
            doctor: doctorsResponse.data,
            specialties: specialtiesResponse.data,
            facilities: facilitiesResponse.data
        });
    }));
}

The key piece here is that after the data is retrieved, we call the ‘getDoctorWithSpecialtiesSuccess’ – which dispatches the data (as you can see we are using Promises with our AltContainer).

Inside the store we bind to the actions as follows:

class AdminDoctorsStore {
    constructor() {
        this.bindActions(AdminDoctorsActions);
}

getDoctorWithSpecialtiesSuccess(data) {
    this.setState({
        doctor:data.doctor,
        specialties: data.specialties,
        facilities: data.facilities
    });
}
export default alt.createStore(AdminDoctorsStore, 'AdminDoctorsStore');

Rather straightforward right ?  The data is fetched by the action, it’s dispatched, the state is set inside the store via the setState call and the data is passed down to the view.  We have clear and clean separation of concerns.

So, let’s get back to the view for a moment, as we touched upon, we loaded the EditDoctor component, which wrapped our store state around a child component called ‘EditDoctorDetails’.  Here are the main pieces of that view (I’m using a few libraries for react-bootstrap, but I won’t go instead the details of that here):

<CheckboxGroup
    ref="cbg"
    value={_.map(this.props.doctor.facilities,
            (facility) => facility.id.toString())}
    onChange={this.facilitiesCheckboxChanged.bind(this)} >
    <label>Facilities</label>
    
{this.props.facilities.map(option => ... )}
</CheckboxGroup>

The state that is passed down to the view is now converted to readonly ‘props’ on the view.  This falls in line with the Flux concept of ‘one-way’ data.  The data is ‘bound’ to the view.  At first, coming to ReactJS from another library such as ‘Knockout’ or ‘Angular’ (I’ve used both extensively) is the initial ‘why do I need to use ‘map’ inside by view’.  Well, let me say, that quickly I found that using  javascript vs. some other expression library is much more straightforward – for now, you can think of the map as a ‘ng-repeat’.

The Checkbox list is able to bind the values from the model (this.props.doctor.facilities) and then all the checkboxes in the this.props.facilities.

Now, what happens when the user checks or unchecks any of the facilities ?  Keep in mind, you cannot alter ‘this.props’ – which is what you might first think you should do if you have a MVC background.  Another options might be to try to take the ‘props’ and then in the component constuctor, bind them to a state value.   You *could* do this, but then you would be missing out on the key features of Flux in my opinion.   So there is a dilemma, right ?   Let’s walk through the Flux/AltContainer way – and you’ll see that I do not have to alter ANY of the code for the view for this update!

As you notice, I am listening to changes made to the checkboxes here:

onChange={this.facilitiesCheckboxChanged.bind(this)}

Let’s take a look at the ‘facilitiesCheckboxChanged’ function:

facilitiesCheckboxChanged(e){
    AdminDoctorsActions.setFacilitiesFor(this.refs.cbg.getCheckedValues(), 
             this.props.facilities, this.props.doctor);
}

Yes… that is all there is to it  :)  We are able to get all the currently checked items, along with the facilities and doctor, and send those back to the action to handle setting the model (again, this.props.doctor.facilities).

This time around is even simpler than when I fetched the data from the server, as I need an action defined, but the action does nothing but pass through to the store itself, so in this case all I need to do is update my action to include the bindings:

class AdminDoctorsActions{
    constructor(){
        this.generateActions(
            'getDoctorWithSpecialtiesSuccess',
            'setFacilitiesFor'
        );
    }

The action ‘setFacilitiesFor’ is generated automatically then, so now I just need the logic inside my store:

class AdminDoctorsStore {
setFacilitiesFor([facilityIds, facilities, doctor]){
    doctor.facilities = _.reduce(facilityIds, (facilitiesFor, id) => {
        let facility = _.find(facilities, {id:parseInt(id, 10)});
        if(facility){
            facilitiesFor.push(facility);
        }
        return facilitiesFor;
    }, []);

    this.setState({
        doctor: doctor
    })
}

Presto! – I set the doctor.facilities inside the store, which is handling my view state, make sure the collection has the correct values and the call setState on the doctor.   The data is then passed back to the view which re-renders it, showing the correctly checked facilities.

As you can see, once this pattern is understood, it provides tremendous power and flexibility.  Our team has really enjoyed working with ReactJS, and I attribute most of that to the ease in which you can create components and the joy of using the Flux architecture with AltContainer.

Thanks for take the time to read this article, if you have any questions or even areas of improvement, feel free to post your thoughts!

Until next time – happy ReactJS programming!

 

 

 

Using Grunt with DurandalJs/RequireJs

One of the things I have quickly learned when using DurandalJS is that most often when learning about how to do things within Durandal, the real answer is to look into either KnockoutJS or into RequireJS.

In my last project we used DurandalJS and I was very pleased. However, the one piece I wasn’t very satisfied with was using Weyland. Since I was unable to use server side bundling, I need some solutions.

When I started, I was looking for some help on this, and now that I have a solution in place, I wanted to share back what approach I took and what worked well for me.

I have created a gist that highlights the Gruntfile and the packages I used.   Additionally it includes the optional Visual Studio ‘post-build’ code that was used:

https://gist.github.com/sgentile/11254289

I hope this helps others out there as well!

 

 

Javascript Inheritance

I’m always looking for a good solid javascript inheritance approach that fully supports javascript prototypical inheritance.  The one I’m going to show today will use Object.create – so if you are supporting older browsers, you will want to make sure you have the es5-shim in your project (which I highly suggest having anyway!).

Let’s create a scenario, where we have base ‘Vehicle’ and we’ll show how to extend that with a ‘Car’ object.

Vehicle:

function Vehicle(name) {
this.name = name;
}

Vehicle.prototype.getDescription = function(){
return this.name;
}

Vehicle.prototype.getType = function(){
return ” is a vehicle”;
}

Car

function Car(name, model){
Vehicle.call(this, name); //this will inherit all the instance properties
this.model = model; //add additional instance properties
}

Car.prototype = Object.create(Vehicle.prototype);  //very important as we want to inherit the prototype properties as well!

Now let’s say that we want to override the getType call for Car:

Car.prototype.getType = function(){
return “this is a car!”;
}

We can also extend an existing base (aka super call)

Car.prototype.getDescription = function(){
Car.prototype.getDescription.call(this) + ” is my favorite car!”;
}

That covers prototype/javascript inheritance – again, if you are using IE8, etc… you will need the es5-shim as Object.Create isn’t supported!

Simple Dojo Example – require, declare (class), and modules

I’ve been exploring the Dojo Toolkit this weekend after looking at some examples that Cesium (Sandcastle example) ships with.  There are many good examples and tutorials on the Dojo website to get yourself familiar with Dojo and up to speed.  Dojo has been around for quite some time, but it’s evolved – at the time of this writing I’m using version 1.9.

I’m a fan of RequireJs  – so to see that Dojo is built upon the same AMD concept as RequireJs is quite intriguing to me!  RequireJs allows for better structured JavaScript using concepts such as ‘dependency injection’ that many OO programmers are aware of.

Let’s jump into an example of how to use Dojo!  My example is built on two dojo tutorials (Introduction to AMD Modules and Classy Javascript).  To keep things simple and interesting, I’m using NodeJS to run this sample.  (All the source code for this post can be pulled down from my github repository).

Just to get this out of the way – let’s get our environment setup.  If you haven’t already, make sure you have NodeJs installed.  Keep in mind, NodeJs isn’t required to actually run this code, you can use any web server.   Create a new directory – ie. ‘modules’ and then enter the command ‘npm install connect’.  Node Connect is a simple and quick way to fire up a web server.  You should now see a ‘node_modules’ directory inside our modules folder.  The next step is to create our server – created a server.js file in the modules folder.  The code should look like this:

var connect = require('connect');
connect.createServer(
        connect.static(__dirname)
        ).listen(8080);
console.log('server running on port 8080');

Node makes it quite easy to get up and running, so this should be enough for our web server!  Let’s move on to what we came here to do!

As mentioned above, you can get the source code from my github repo – but lets take a look at the project structure:

image

As you can see, I have a ‘app’ folder with two javascript files.  The index.html will contain the code to run our simple example.  Let’s take a look at our index.html file:

<html>
    <head>
        <link rel="stylesheet" href="style.css" media="screen">
        <script>
    dojoConfig = {
        async: true,
        packages:[{
            name:"app", location:"/app"
        }]
    };
</script>
        <script src="//ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js"></script>
        <script>
            require([
                    "app/counter", "app/logger"
                ], function(counter, Logger){
                var logger = new Logger();
                logger.log(counter.getValue());
                counter.increment();
                logger.log(counter.getValue());
                counter.decrement();
                logger.log(counter.getValue());
            });
        </script>
    </head>
    <body>
    </body>
</html>

As you can see, I’m supplying our main dojo.js file via CDN.  The next section here in the script tags is our application (normally I’d even have this code in a separate .js file – but for now this will suffice).  We wrap our code up in our ‘require’ statement.  The first part of this is an array of strings for each dependency our application has.  In this case, we have a dependency on ‘counter’ and ‘logger’ (we do not use ‘.js’ as this will make them non-AMD modules).  The function that follows matches our two dependencies and provides access to that code, ‘counter’ and ‘Logger’.  In this example we can see that one is a ‘static’ object whereas the other is an object we will create. As you can see, this helps keep our code rather clean, the rest of the code.

Let’s take a look at the ‘counter.js’ code first – as it’s the simplest to follow:

define(function(){
    var privateValue = 0;
    return {
        increment: function(){
            privateValue++;    
        },
        decrement: function(){
            privateValue--;
        },
        getValue: function(){
            return privateValue;
        }
    }
});

Dojo provides some good structure for us to create our modules.  In this case, we are wrapping our code in a ‘define’ function which tells Dojo this is a module and will be accessible from our application.   Dojo will handle loading and injecting this module into our main application. 

The second module this application uses is our ‘logger.js’ file.  This code takes a next step by wrapping our code in an object, aka class:

define(function(){
    var privateValue = 0;
    return {
        increment: function(){
            privateValue++;    
        },
        decrement: function(){
            privateValue--;
        },
        getValue: function(){
            return privateValue;
        }
    }
});

The define in this example has some additional dependencies.  All four of these dependencies comes from the dojo framework.  This really shows how modular dojo is and how easy it is to cleanly separate your apps concerns  (Initially when building this application, I had this code in the index.html, then refactored it out to keep the index.html code very clean!).

This code introduces a second concept – that of ‘declare’.  To understand and see how to use ‘declare’ – take a look at the Dojo ‘live docs’ definition.  This particular object will expose a ‘log’ function.  Other libraries try to mimic a ‘class’ definition (aka Typescript, Backbone, etc..) whereas I believe through Dojo’s ‘declare’ it’s more in line with how most people write javascript today.   Since we aren’t creating the object in this code nor returning an object literal, the ‘return declare’ will allow the caller to instantiate the object. 

The live docs link above to declare provides good documentation with several examples.  I appreciate the inheritance and mixin capabilities of declare.

This should wrap up this post – I hope to share more as I further explore using Dojo with Require.  If you have any questions or feedback please share!

(Just a side note: I’ve been using KnockoutJS on several applications and recommend taking a look at the DurandelJS framework that creates a RequireJS/AMD application structure around KnockoutJS – you can see the power of using RequireJs/AMD).

KnockoutJS & ASP.NET Mvc Partial View Loading

Recently I’ve needed to dynamically load ‘partial views’ that are bound to KnockoutJS view models.  The application is a single page app approach, composite application where I’m loading a particular view.

Retrieving the ‘partialView’ is rather simple with ASP.NET Mvc:

image

This is rather straightforward.   I make the call to retrieve the template with a jQuery ajax call:

image

I create my viewmodel, and my viewmodel has a property with the partialViewName defined – ie. self.partialViewName = “_SomePartialView”;

This works very well so far – I have some caching of the html partial, although I might remove this and just takes a more server side ‘get’ ‘varybyparam’ caching on the controller action.

Previously I had an approach like this:

<div data-bind=”with: myViewModel”>
@Html.Partial(“_SomePartialView”)
</div>

Which I still believe works good for one or two scenarios – but the number of viewmodel objects (I have 20+ views here getting loaded) let me change my approach to more of a ‘load on demand’.  I’m pretty happy with this!

Update: one of my concerns that I meant to research and apply here is the impact of loading vm’s to the same dom node with applyBinding and memory leaks.

A good response to this on stack overflow: http://stackoverflow.com/questions/10048485/how-to-clear-remove-observable-bindings-in-knockout-js/10049722#10049722

So what I do for this is use the ko.cleanNode prior to re-applying this binding to the same node:

image

Simple Quick Git Common Actions

Create Branch:

Switch to a new branch:

git checkout -b branch-name

Shows the branch your on highlighted by *

git branch

Add files – marks any files to be added

git add .

Check-in changes

git commit -a -m “message”   //I always use the -a even with the git add . usage

Merge (to master)

switch back to the branch you want to merge to

git checkout master

specify the branch you want to merge from

git merge branch-name

optional – remove that branch

git branch -d branch-name

to completely abandon a branch:

git branch -D branch-name //only if you really screw things up

Revert – or rather we can still undo the changes easily by having Git check out the previous commit with the checkout command (and a -f flag to force overwriting the current changes):

git checkout -f

 

Extra Content

Heroku

This is definite OT but to add a few bonus items:)

Initial creation (this assumes you setup heroku):

heroku create --stack cedar
Deploy:
git push heroku master
(if using rails: heroku run rake db:migrate)

Static Properties and Methods with Coffeescript

class Person
   @test: (input) ->
      return input
   @staticProperty : 10
   @get: ->
     return {name:'Steve'}
   nonStatic: ->
     return "non static"

console.log Person.test 'Hello World'  #result is 'Hello World'
console.log Person.get() #result is object
console.log Person.staticProperty   #result is 10

#console.log Person.nonStatic()  this is an error
person = new Person()
console.log person.nonStatic() #result is 'non static'

Should be fairly explanatory:)