Deploying a git subtree to Heroku (or other PaaS)

Most of the common PaaS platforms like OpenShift and Heroku deploy code based on a source in a git repo – you push your local repo containing source to the remote repo on the platform, the build is performed remotely and then deploys the built artifacts.

What if you want to deploy an app that is prebuilt, or you have a git repo that contains various subfolders, and only part of the folder structure in the repo is what you need deployed?

I’ve been experimenting with a simple React app that also has a node.js backend. In hindsight restructuring the source tree to make the app easier to deploy may have been simpler, but it turns out you can push part of your source subtree to a remote repo, like an application deployed to Heroku, using ‘git subtree’:

git subtree push –prefix subfoldername heroku master

This is discussed in this post here.

React Flux Store: addChangeListener is not a function

Using React with Flux, you need to register a callback from your Component so that it can be called when the Store emits an event. For an ExampleComponent and ExampleStore, this might look like:

class ExampleComponent extends Component {

    constructor(props) {
        super(props);
    }

    componentWillMount(){
        ChatStore.on('change', this.handleUserNameChange);
    }
...
}

I’ve seen some examples where a helper function is declared in the Store that registers your Component as a listener, so the call from the Component to register with the Store might look like:

    componentWillMount(){
        ChatStore.registerChangeListener(this.handleUserNameChange);
    }

and in your ExampleStore you’ll declare registerChangeListener() (and similar to remove) like this:

addChangeListener(callback) {
    this.on('change', callback);
}

removeChangeListener(callback) {
    this.removeListener('change', callback);
}

All good so far, but here’s the issue I just ran into:

Uncaught TypeError: _ExampleStore2.default.addChangeListener is not a 
function
 at ExampleComponent.componentWillMount (ExampleComponent.jsx:19)
 at ReactCompositeComponent.js:348

Initially this is confusing, since it’s clear we did already declare addChangeListener, so why is this error saying it’s not a function?

The catch is in how we export the Store. The cause of my issue above was that I had exported it like this:

class ExampleStore extends EventEmitter {
..
}
export default ExampleStore;

This is how you would typically export a module but what we’re trying to do is treat the Store as a singleton instance. To do this the export should be:

export default new ExampleStore();

This approach is described in many Flux related articles (here’s an example), but it’s an easy mistake to miss.

JavaScript ES6 default imports vs named imports

I’d been wondering this for a while. What’s the difference between this style of ES6 import:

import A from './A';

vs

import { A } from './A';

I’ve seen and used both, and had guessed that the { A } syntax is when you’re importing a specific named function from a module? I wasn’t convinced this was correct. It turns out the difference is importing a default export, versus importing using a named import.

This is explained here this SO post here:

http://stackoverflow.com/questions/36795819/when-should-i-use-curly-braces-for-es6-import

Adding react-bootstrap to a React app

Adding Bootstrap to an existing or new React app is not as obvious or easy as you would think, because of Bootstrap’s dependencies on other libraries, like jQuery (and see answers to Quora question here).

The react-bootstrap module is a React specific implementation of Bootstrap that provides JSX components for a number of the Bootstrap provided styles and components, and even layout CSS encapsulated as JSX components like: <Grid>, <Row> and <Col>

Installing it via npm is as simple as:

npm intall --save react-boostrap

You then import what you need from the module like:

import {Bootstrap, Grid, Row, Col} from 'react-bootstrap';

and then you quickly discover that the CSS based layout is not working like you’d expect. If you check the Getting Started section it mentions:

Because React-Bootstrap doesn’t depend on a very precise version of Bootstrap, we don’t ship with any included css. However, some stylesheet is required to use these components. How and which bootstrap styles you include is up to you, but the simplest way is to include the latest styles from the CDN.

Ok. So you can follow their example and load from the Bootstrap (or other) CDN, but what if you want to manage Bootstrap as an npm module too? This question is answered in this post here. What you need is to install bootstrap:

npm install --save bootstrap

and then include it into your main App.jsx with:

import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/css/bootstrap-theme.css';

and you’re up and running. Not that obvious but once you’ve setup this once, probably makes more sense the next time.