WebSockets in Grails 3.0
June 10th, 2015
WebSockets are a long-lived, interactive, two-way channel between a client browser and end server that allows ongoing communication without polling.
I’m a server-side guy that happens to be living inside front-end projects. I know my way around jQuery, have gotten aquainted with Bootstrap, and use SASS if I have to do something a bit more than trivial with CSS. But I don’t know Grunt from Bower and, honestly, used npm
for the first time while making this blog post.
My current project has several large JSON objects that need to be presented to the screen. There is a current framework in this app but it doesn’t allow any customization which is not what the customer wanted. I wasn’t looking forward to doing a bunch of DOM manipulation, and the client wouldn’t like how slow it was.
A couple of people pointed me to ReactJS. Again, I’m a server-side guy and all these fancy JavaScript libraries make my head spin. But whatever I was trying to do with events and jQuery wasn’t working, so I gave it a shot. And what do you know? I really liked it. React only has a few surprises, which aren’t so surprising if you understand how it really works.
I put up a demo that is close to my solution. It’s a large JSON object that easily displays it’s records to the screen.
Starting out, in the index.html
file, we simply setup where we want our template:
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8">
<div id="state-info"></div>
</div>
<div class="col-md-2"></div>
</div>
We want to put our content in the state-info
div. So in our JavaScript we simply tell it that:
React.render(<StateInfo />, document.getElementById('state-info'));
Ok, this isn’t really JavaScript but JSX which React uses extensively. As they said, you don’t have to use JSX with React but it does make it easier. A lot easier. What JSX reminds me of is the good parts of XSLT. You read that right. Once I got that through my head, using React and JSX suddenly made a lot of sense.
The above code snippet says “in the state-info
ID insert the StateInfo
tag”. But what is the StateInfo
tag? That is defined earlier in the file as a React class:
var StateInfo = React.createClass({
.....
};
Every React class needs to have a render
method. The whole idea of the render
method is that is only returns XML — with a root and even with other React tags. Here is the meat of StateInfo's
render
:
<div>
<hr />
<div className="row">
<div className="col-md-2" />
<div className="col-md-10">
<h2>{state.name}</h2>
<hr />
</div>
</div>
<div className="row">
<div className="col-md-10">
<StateInfoItem label="Abbreviation" value={state.abbreviation} />
<StateInfoItem label="Capital" value={state.capital} />
<StateInfoItem label="Largest City" value={state['most-populous-city']} />
</div>
</div>
<div className="row">
<div className="col-md-5">{prevButton}</div>
<div className="col-md-2" />
<div className="col-md-5">{nextButton}</div>
</div>
</div>
Note that there are StateInfoItem
tags in there, with attributes on that. In the StateInfoItem
class, those are treated as properties. That whole class is fairly straightforward:
var StateInfoItem = React.createClass({
render: function() {
return (
<dl className="dl-horizontal">
<dt>{this.props.label}</dt>
<dd>{this.props.value}</dd>
</dl>
);
},
});
So those properties are simply inserted into the definition list structure. If we want to change that definition list to something else, like a grid, we just need to change the structure and it will be changed for everything.
Back to the StateInfo
class — you may have also noted the {preButton}
and the {nextButton}
in the output. Those were defined before the return
statement:
var index = this.state.index;
var state = states.states.state[index]["@attributes"];
var prevButton ="";
var nextButton ="";
if (index>0) {
prevButton = <button type="button" className="btn btn-primary" onClick={this.handlePrev}>Prev</button>;
}
if (index<50) {
nextButton= <button type="button" className="btn btn-primary" onClick={this.handleNext}>Next</button>;
}
return (
.....
);
So the prevButton
only exists if the index
more than 0 (i.e. if there is another state after it) and the nextButton
is similar — it only appears if there is another state.
The this.state.index
is not related to the state
object but instead of the state of the StateInfo
class. And the this.handlePrev
and this.handleNext
are methods that play with that state. Here is how all that is defined:
getInitialState: function() {
return {"index": 0}
},
handlePrev: function() {
this.setState({"index":this.state.index-1});
},
handleNext: function() {
this.setState({"index":this.state.index+1});
},
getInitialState
is ran when the object is first created. Since the index
is set to 0, then it will display the first state. Both handlePrev
and handleNext
change the value of index
in state. Then React runs render
again on the new state. That is probably the most important thing about React — it renders an object when its state changes. There is no hidden content — it totally re-renders that object. And (as you can see from the demo) it does it really fast.
I hope this little tutorial gives an idea of how React works. I think it’s a very powerful and mostly straightforward library.
WebSockets are a long-lived, interactive, two-way channel between a client browser and end server that allows ongoing communication without polling.
A method of integrating bower into Gradle to manage JavaScript and CSS dependencies without maintaining copies in the source tree.
This past weekend, I was able to attend and present at the 2015 Nebraska.Code() Conference in Lincoln, along with a few other Object Partners developers. With roughly 500 in attendance from presenters, to attendees, to sponsors, the conference had…
Mike has almost 20 years of experience in technology. He started in networking and Unix administration, and grew into technical support and QA testing. But he has always done some development on the side and decided a few years ago to pursue it full-time. His history of working with users gives Mike a unique perspective on writing software.