Simple Async With RxJS

I had a previous project that involved a lot of asynchronous javascript code. I wasn’t entirely pleased with the result but it worked. “I wish things could be a little simpler.” I kept saying to myself. The part of the application in question was a piece that grabbed data from a API call returning xml. That data had to be parsed and then inserted into a database. I used hyperquest to make the API call, xml-stream to parse the xml response and sequelize for the database logic.

The Problem

xml-stream emits events while parsing and sequelize uses promises during it’s querying. Having that work together and be readable/maintainable was a challenge.

Read More

Node.js and Docker Using Host Volumes

A previous post, Nginx and Node.js with Docker, I created a Node.js Docker container that copied source files inside a Docker image. It’s a challenge to change any of the files in the Node.js Docker container since it’s baked into the Docker image. A different approach would be to mount a host folder in the Docker container. This way I can edit/add/delete files which would be reflected in the Docker container. The idea is to create a bare Node.js server that I can conintue to develop.

Full source code for this example docker-nodejs-unbaked

Read More

React With react-engine

Previously I wrote an article about rendering react server side with seo. It was an experiment that worked but needed improvement. Lately I’ve been using react-engine to render react views client and server side. It’s a rendering engine for express that uses react-router.

I wanted to use the same react components in my previous example and modify as little as possible.
The demo will display a html select element with a list of categories. Once a category is selected a list of products, within that category, will be displayed. The select element change will fire-off an api call to get the products.

Here’s the routing I am using:

1
2
3
4
5
6
7
8
9
10
var React = require('react');
var Router = require('react-router');
var AppHandler = require('./handlers/AppHandler.jsx');
var ProductHandler = require('./handlers/ProductHandler.jsx');
var Routes = (
<Router.Route name="app" path="/" handler={AppHandler}>
<Router.Route name="products" path="/products/:category" handler={ProductHandler} />
</Router.Route>
);

I had to change AppHandler to use a new component, Layout, which serves as the main html template.

Here’s the AppHandler:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var React = require('react');
var Router = require('react-router');
var Layout = require('../components/Layout.jsx');
var AppHandler = React.createClass({
render: function() {
return (
<Layout {...this.props} >
<Router.RouteHandler {...this.props} />
</Layout>
);
}
});
module.exports = AppHandler;

I pass all the properties into Layout and also into the RouteHandler. The RouteHandler is where the active route will be rendered. I use spread attributes to pass properties.

Here’s the Layout component:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var React = require('react');
var CategoryList = require('./CategoryList.jsx');
var Layout = React.createClass({
render: function() {
return (
<html>
<head>
<meta charSet='utf-8' />
<title>{this.props.title}</title>
</head>
<body>
<CategoryList categories={this.props.categories} />
{this.props.children}
</body>
<script src='/bundle.js'></script>
</html>
);
};
});
module.exports = Layout;

I’ll be displaying the CategoryList component in all the views. An important part is the {this.props.children} which represents the children of the Layout component. In this case it’s the RouteHandler.

##server-side setup

  1. Require node-jsx to allow node to require jsx files.
  2. Create a template engine using react-engine.
  3. Register the template engine for jsx files.
  4. Set the template/view directory.
  5. Set jsx as the default view engine.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Make jsx file requirable by node.
require('node-jsx').install();
var express = require('express');
var app = express();
var path = require('path');
// Create the template engine with react-engine.
var engine = require('react-engine').server.create({
reactRoutes: path.normalize(path.join(__dirname, '/src/Routes.jsx'))
});
// Registers the template engine for jsx files.
app.engine('.jsx', engine);
// Set the template/view directory.
app.set('views', path.normalize(path.join(__dirname, '/src/handlers')));
// Set jsx as the view engine.
app.set('view engine', 'jsx');
// Set the custom view
app.set('view', require('react-engine/lib/expressView'));

Rendering the views on the server is easy. Pass the url and any data the view requires. Here’s an example of rendering the main route:

1
2
3
4
5
6
7
8
var express = require('express');
var router = express.Router;
router.get('/', function(req, res) {
res.render(req.url, {
title: 'Welcome!'
});
});

##client-side setup

  1. Require the react-router routes.
  2. Require all view handler files. For this example I used require-globify which allows you to require files with globbing expressions. I use browserify which is why this step is necessary.
  3. Set boot options.
  4. Boot!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var Routes = require('./Routes.jsx');
var Client = require('react-engine/lib/client');
// Include all view handler files.
require('./handlers/*.jsx', { glob: true });
// Boot options
var options = {
routes: Routes,
// Supply a function that can be called to resolove the file that
// was rendered.
viewResolver: function(viewName) {
return require('./handlers/' + viewName);
}
};
// Boot when you are ready! The DOMContentLoaded event is fired when
// the initial HTML has been completely loaded without waiting for
// stylesheets, images and subframes to finish loading.
document.addEventListener('DOMContentLoaded', function onLoad() {
Client.boot(options);
});

I created a github repo react-flux-routing-seo-revisited for this example.

Source Maps With Node.js

Using source maps when generating ES5 code from ES6 has proved to be very helpful in my development. When debugging I want errors to reference the source files not the generated files. I use babel to generate ES5 code from ES6 and source-map files. I also use source-map-support for referencing stack traces in the source file.

For this example I’ll create a simple ES6 class that extends EventEmitter and will emit a success event. I’ll purposely misspell the word emit and check if the error references the source file.

My ES6 files will be in a directory named lib. The generated ES5 and source map files will be in a directory named dist.

In my ES6 class I need to include the source-map-support library and call its install() in the construtor.
Here is the ES6 class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { EventEmitter } from 'events';
import { install } from 'source-map-support';
export class EmitStuff extends EventEmitter {
constructor() {
super();
install(); // Required for source-map-support
}
tryMe() {
this.emitt('success', 'It works!');
}
}
export default EmitStuff;

Here is the entry point that uses the EmitStuff class I created. It uses the ES5 generated file.

1
2
3
4
5
6
7
8
var EmitStuff = require('./dist/emit-stuff');
var emitStuff = new EmitStuff();
emitStuff.on('success', function(response) {
console.log(response);
});
emitStuff.tryMe();

Here is the build step that will generate ES5 code and source-map files into the dist directory from the ES6 code in the lib directory.

1
babel out-dir dist lib --source-maps

Now when I run my entry point file I get the following:

1
2
3
4
5
6
7
8
node index.js
/emitstuff/lib/emit-stuff.js:11
this.emitt('success', 'It worked!');
^
TypeError: undefined is not a function
at EmitStuff.tryMe (/emitstuff/lib/emit-stuff.js:11:8)
....

The error points to the source file!

I created a github repo, source-maps-with-node for this example.