More Related Content
Similar to EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5 (20)
EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5
- 1. Copyright © 2016 M/Gateway Developments Ltd
EWD 3 Training Course
Part 41
Building a React.js-based
QEWD Application
(e) Building out a login sequence
Rob Tweed
Director, M/Gateway Developments Ltd
Twitter: @rtweed
- 5. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
- 6. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
Initially
Initial Title Display the form No Content
- 7. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
On login error
Initial Title Display the form No Content
Display Error
- 8. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
On Successful
login
Hello {{user}}
title
Hide the form Display
Content
- 9. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Send username
& password as EWD
message
- 10. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Send username
& password as EWD
message
To QEWD
Back-end
- 11. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
From
Back-end
Handle response
- 12. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Error response
received:
Display Error
- 13. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Success response
received:
Re-render
- 14. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Pass down
Username as
prop
- 15. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Pass prop to
Signal successful
login
- 16. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Pass prop to
signal that
content should
be displayed
- 17. Copyright © 2016 M/Gateway Developments Ltd
So let's build out the components
In ~/qewd/www/react-demo1
- 18. Copyright © 2016 M/Gateway Developments Ltd
MainPage.js
"use strict"
var React = require('react');
var Title = require('./Title');
var Content = require('./Content');
var Login = require('./Login');
var jQuery = require('jquery');
window.$ = window.jQuery = jQuery;
var controller;
var MainPage = React.createClass({
getInitialState: function() {
return {
status: 'initial',
}
},
componentWillMount: function() {
controller = require('./MainPage-controller')(this.props.controller, this);
},
render: function() {
console.log('Rendering MainPage');
return (
<div>
<Title
controller = {controller}
username = {this.username}
/>
<Login
controller = {controller}
loggedIn = {this.loggedIn}
/>
<Content
controller = {controller}
content = {this.content}
/>
</div>
);
}
});
module.exports = MainPage;
- 19. Copyright © 2016 M/Gateway Developments Ltd
MainPage.js
"use strict"
var React = require('react');
var Title = require('./Title');
var Content = require('./Content');
var Login = require('./Login');
var jQuery = require('jquery');
window.$ = window.jQuery = jQuery;
var controller;
var MainPage = React.createClass({
getInitialState: function() {
return {
status: 'initial',
}
},
componentWillMount: function() {
controller = require('./MainPage-controller')(this.props.controller, this);
},
render: function() {
console.log('Rendering MainPage');
return (
<div>
<Title
controller = {controller}
username = {this.username}
/>
<Login
controller = {controller}
loggedIn = {this.loggedIn}
/>
<Content
controller = {controller}
content = {this.content}
/>
</div>
);
}
});
module.exports = MainPage;
Initial state
variable value
- 20. Copyright © 2016 M/Gateway Developments Ltd
MainPage.js
"use strict"
var React = require('react');
var Title = require('./Title');
var Content = require('./Content');
var Login = require('./Login');
var jQuery = require('jquery');
window.$ = window.jQuery = jQuery;
var controller;
var MainPage = React.createClass({
getInitialState: function() {
return {
status: 'initial',
}
},
componentWillMount: function() {
controller = require('./MainPage-controller')(this.props.controller, this);
},
render: function() {
console.log('Rendering MainPage');
return (
<div>
<Title
controller = {controller}
username = {this.username}
/>
<Login
controller = {controller}
loggedIn = {this.loggedIn}
/>
<Content
controller = {controller}
content = {this.content}
/>
</div>
);
}
});
module.exports = MainPage;
props passed
to child
components
- 21. Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.js
module.exports = function (controller, component) {
controller.log = true;
component.loggedIn = false;
component.username = '';
component.content = '';
controller.on('error', function(responseObj) {
alert('Error: ' + responseObj.message.error);
});
controller.on('login', function(responseObj) {
if (!responseObj.message.error) {
console.log('Logged in!');
component.loggedIn = true;
component.username = responseObj.message.name;
component.content = 'User has logged in - ready to display some content for the user!';
component.setState({
status: 'loggedIn'
});
}
});
return controller;
};
- 22. Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.js
module.exports = function (controller, component) {
controller.log = true;
component.loggedIn = false;
component.username = '';
component.content = '';
controller.on('error', function(responseObj) {
alert('Error: ' + responseObj.message.error);
});
controller.on('login', function(responseObj) {
if (!responseObj.message.error) {
console.log('Logged in!');
component.loggedIn = true;
component.username = responseObj.message.name;
component.content = 'User has logged in - ready to display some content for the user!';
component.setState({
status: 'loggedIn'
});
}
});
return controller;
};
Response
from back-end
handled in this
top component
- 23. Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.js
module.exports = function (controller, component) {
controller.log = true;
component.loggedIn = false;
component.username = '';
component.content = '';
controller.on('error', function(responseObj) {
alert('Error: ' + responseObj.message.error);
});
controller.on('login', function(responseObj) {
if (!responseObj.message.error) {
console.log('Logged in!');
component.loggedIn = true;
component.username = responseObj.message.name;
component.content = 'User has logged in - ready to display some content for the user!';
component.setState({
status: 'loggedIn'
});
}
});
return controller;
};
Initial values
passed as
props to child
components
- 24. Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.js
module.exports = function (controller, component) {
controller.log = true;
component.loggedIn = false;
component.username = '';
component.content = '';
controller.on('error', function(responseObj) {
alert('Error: ' + responseObj.message.error);
});
controller.on('login', function(responseObj) {
if (!responseObj.message.error) {
console.log('Logged in!');
component.loggedIn = true;
component.username = responseObj.message.name;
component.content = 'User has logged in - ready to display some content for the user!';
component.setState({
status: 'loggedIn'
});
}
});
return controller;
};
New values
passed as
props to child
components
if login is
successful
- 25. Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.js
module.exports = function (controller, component) {
controller.log = true;
component.loggedIn = false;
component.username = '';
component.content = '';
controller.on('error', function(responseObj) {
alert('Error: ' + responseObj.message.error);
});
controller.on('login', function(responseObj) {
if (!responseObj.message.error) {
console.log('Logged in!');
component.loggedIn = true;
component.username = responseObj.message.name;
component.content = 'User has logged in - ready to display some content for the user!';
component.setState({
status: 'loggedIn'
});
}
});
return controller;
};
State value
changed to
trigger
re-render of
this component
and its child
components
- 26. Copyright © 2016 M/Gateway Developments Ltd
Title.js
var React = require('react');
var controller;
var Title = React.createClass({
componentWillMount: function() {
controller = require('./Title-controller')(this.props.controller, this);
},
componentWillReceiveProps: function(newProps) {
this.updateHeading(newProps.username);
},
render: function() {
console.log('Rendering Title');
return (
<h2>
{this.heading}
</h2>
);
}
});
module.exports = Title;
- 27. Copyright © 2016 M/Gateway Developments Ltd
Title.js
var React = require('react');
var controller;
var Title = React.createClass({
componentWillMount: function() {
controller = require('./Title-controller')(this.props.controller, this);
},
componentWillReceiveProps: function(newProps) {
this.updateHeading(newProps.username);
},
render: function() {
console.log('Rendering Title');
return (
<h2>
{this.heading}
</h2>
);
}
});
module.exports = Title;
Fires if props
have changed
Does not fire
on initial render
- 28. Copyright © 2016 M/Gateway Developments Ltd
Title-controller.js
module.exports = function (controller, component) {
component.heading = 'My QEWD React Demo';
component.updateHeading = function(username) {
if (username !== '') {
component.heading = 'Welcome, ' + username + ', to ' + component.heading;
}
};
return controller;
};
- 29. Copyright © 2016 M/Gateway Developments Ltd
Login.js"use strict"
var React = require('react');
var controller;
var Login = React.createClass({
getInitialState: function() {
return {
status: 'initial',
}
},
componentWillMount: function() {
controller = require('./Login-controller')(this.props.controller, this);
},
render: function() {
console.log('rendering Login');
if (this.props.loggedIn) {
return (
<div></div>
);
}
return (
<table id="loginTable">
<tbody>
<tr>
<td>Username: </td>
<td><input id="username" /> </td>
</tr>
<tr>
<td>Password: </td>
<td><input id="password" type="password" /> </td>
</tr>
<tr>
<td colSpan="2">
<button
id="LoginBtn"
onClick={this.LoginBtnClicked}
>
Login
</button>
</td>
</tr>
</tbody>
</table>
);
}
});
module.exports = Login;
- 30. Copyright © 2016 M/Gateway Developments Ltd
Login.js"use strict"
var React = require('react');
var controller;
var Login = React.createClass({
getInitialState: function() {
return {
status: 'initial',
}
},
componentWillMount: function() {
controller = require('./Login-controller')(this.props.controller, this);
},
render: function() {
console.log('rendering Login');
if (this.props.loggedIn) {
return (
<div></div>
);
}
return (
<table id="loginTable">
<tbody>
<tr>
<td>Username: </td>
<td><input id="username" /> </td>
</tr>
<tr>
<td>Password: </td>
<td><input id="password" type="password" /> </td>
</tr>
<tr>
<td colSpan="2">
<button
id="LoginBtn"
onClick={this.LoginBtnClicked}
>
Login
</button>
</td>
</tr>
</tbody>
</table>
);
}
});
module.exports = Login;
On successful
login, display
nothing
Form disappears
- 31. Copyright © 2016 M/Gateway Developments Ltd
Login.js"use strict"
var React = require('react');
var controller;
var Login = React.createClass({
getInitialState: function() {
return {
status: 'initial',
}
},
componentWillMount: function() {
controller = require('./Login-controller')(this.props.controller, this);
},
render: function() {
console.log('rendering Login');
if (this.props.loggedIn) {
return (
<div></div>
);
}
return (
<table id="loginTable">
<tbody>
<tr>
<td>Username: </td>
<td><input id="username" /> </td>
</tr>
<tr>
<td>Password: </td>
<td><input id="password" type="password" /> </td>
</tr>
<tr>
<td colSpan="2">
<button
id="LoginBtn"
onClick={this.LoginBtnClicked}
>
Login
</button>
</td>
</tr>
</tbody>
</table>
);
}
});
module.exports = Login;
Otherwise,
display the form
- 32. Copyright © 2016 M/Gateway Developments Ltd
Login.js"use strict"
var React = require('react');
var controller;
var Login = React.createClass({
getInitialState: function() {
return {
status: 'initial',
}
},
componentWillMount: function() {
controller = require('./Login-controller')(this.props.controller, this);
},
render: function() {
console.log('rendering Login');
if (this.props.loggedIn) {
return (
<div></div>
);
}
return (
<table id="loginTable">
<tbody>
<tr>
<td>Username: </td>
<td><input id="username" /> </td>
</tr>
<tr>
<td>Password: </td>
<td><input id="password" type="password" /> </td>
</tr>
<tr>
<td colSpan="2">
<button
id="LoginBtn"
onClick={this.LoginBtnClicked}
>
Login
</button>
</td>
</tr>
</tbody>
</table>
);
}
});
module.exports = Login;
JSX Click handler
- 33. Copyright © 2016 M/Gateway Developments Ltd
Login-controller.js
module.exports = function (controller, component) {
component.LoginBtnClicked = function(e) {
var username = $('#username').val();
var password = $('#password').val();
if (username === '') {
alert('You must enter a username!');
return;
}
if (password === '') {
alert('You must enter a password!');
return;
}
controller.send({
type: 'login',
params: {
username: username,
password: password
}
});
};
return controller;
};
- 34. Copyright © 2016 M/Gateway Developments Ltd
Login-controller.js
module.exports = function (controller, component) {
component.LoginBtnClicked = function(e) {
var username = $('#username').val();
var password = $('#password').val();
if (username === '') {
alert('You must enter a username!');
return;
}
if (password === '') {
alert('You must enter a password!');
return;
}
controller.send({
type: 'login',
params: {
username: username,
password: password
}
});
};
return controller;
};
Define the
Login button's
click handler
- 35. Copyright © 2016 M/Gateway Developments Ltd
Login-controller.js
module.exports = function (controller, component) {
component.LoginBtnClicked = function(e) {
var username = $('#username').val();
var password = $('#password').val();
if (username === '') {
alert('You must enter a username!');
return;
}
if (password === '') {
alert('You must enter a password!');
return;
}
controller.send({
type: 'login',
params: {
username: username,
password: password
}
});
};
return controller;
};
Send the username
and password to
the ewd-xpress
Back-end
The response is
handled in the
Parent component
- 36. Copyright © 2016 M/Gateway Developments Ltd
Content.js
var React = require('react');
var controller;
var Content = React.createClass({
componentWillMount: function() {
controller = require('./Content-controller')(this.props.controller, this);
},
componentWillReceiveProps: function(newProps) {
this.updateContent(newProps.content);
},
render: function() {
console.log('Rendering Content');
return (
<div>
{this.content}
</div>
);
}
});
module.exports = Content;
- 37. Copyright © 2016 M/Gateway Developments Ltd
Content.js
var React = require('react');
var controller;
var Content = React.createClass({
componentWillMount: function() {
controller = require('./Content-controller')(this.props.controller, this);
},
componentWillReceiveProps: function(newProps) {
this.updateContent(newProps.content);
},
render: function() {
console.log('Rendering Content');
return (
<div>
{this.content}
</div>
);
}
});
module.exports = Content;
Simply display
the value of
this.content each
Time it renders
- 38. Copyright © 2016 M/Gateway Developments Ltd
Content.js
var React = require('react');
var controller;
var Content = React.createClass({
componentWillMount: function() {
controller = require('./Content-controller')(this.props.controller, this);
},
componentWillReceiveProps: function(newProps) {
this.updateContent(newProps.content);
},
render: function() {
console.log('Rendering Content');
return (
<div>
{this.content}
</div>
);
}
});
module.exports = Content;
Use the
componentWillReceiveProps
life-cycle method to
update the content
whenever re-rendering
occurs
- 39. Copyright © 2016 M/Gateway Developments Ltd
Content.js
var React = require('react');
var controller;
var Content = React.createClass({
componentWillMount: function() {
controller = require('./Content-controller')(this.props.controller, this);
},
componentWillReceiveProps: function(newProps) {
this.updateContent(newProps.content);
},
render: function() {
console.log('Rendering Content');
return (
<div>
{this.content}
</div>
);
}
});
module.exports = Content;
The
componentWillReceiveProps
life-cycle method will
invoke a method named
this.updateContent
We'll define it in the
content-controller module
- 40. Copyright © 2016 M/Gateway Developments Ltd
Content-controller.js
module.exports = function (controller, component) {
component.content = component.props.content;
component.updateContent = function(newContent) {
if (newContent !== '') {
component.content = newContent;
}
};
return controller;
};
- 41. Copyright © 2016 M/Gateway Developments Ltd
Content-controller.js
module.exports = function (controller, component) {
component.content = component.props.content;
component.updateContent = function(newContent) {
if (newContent !== '') {
component.content = newContent;
}
};
return controller;
};
Here's the
this.updateContent
Method
It just updates
this.content
Within the controller,
instead of this we
refer to component
- 42. Copyright © 2016 M/Gateway Developments Ltd
Finally the back-end Module
• This must handle the login message that is
sent from the browser when the Login
form button is clicked
• It must validate the username and
password
• For simplicity, we'll just hard-code the valid
values
– In a real-world app, you'd authenticate against
a database or using a dedicated API
- 43. Copyright © 2016 M/Gateway Developments Ltd
Finally the back-end Module
• It's advisable to repeat any browser-side
validation at the back-end
– A malicious user might attempt to send a login
message via the JavaScript console
• We'll authenticate the user and prevent an
already-logged in user from logging in
again
- 44. Copyright © 2016 M/Gateway Developments Ltd
Back-end module
module.exports = {
handlers: {
login: function(messageObj, session, send, finished) {
if (session.authenticated) {
finished({error: 'You have already logged in'});
return;
}
if (messageObj.params.username === '') {
finished({error: 'You must enter a username'});
return;
}
if (messageObj.params.password === '') {
finished({error: 'You must enter a password'});
return;
}
if (messageObj.params.username !== 'rob') {
finished({error: 'Invalid username'});
return;
}
if (messageObj.params.password !== 'secret') {
finished({error: 'Invalid password'});
return;
}
session.authenticated = true;
finished({
ok: true,
name: 'Rob'
});
}
}
};
~/qewd/node_modules/react-demo1.js
- 45. Copyright © 2016 M/Gateway Developments Ltd
Back-end module
module.exports = {
handlers: {
login: function(messageObj, session, send, finished) {
if (session.authenticated) {
finished({error: 'You have already logged in'});
return;
}
if (messageObj.params.username === '') {
finished({error: 'You must enter a username'});
return;
}
if (messageObj.params.password === '') {
finished({error: 'You must enter a password'});
return;
}
if (messageObj.params.username !== 'rob') {
finished({error: 'Invalid username'});
return;
}
if (messageObj.params.password !== 'secret') {
finished({error: 'Invalid password'});
return;
}
session.authenticated = true;
finished({
ok: true,
name: 'Rob'
});
}
}
};
~/qewd/node_modules/react-demo1.js
Repeat the
Browser-side
Validation
Return an error
object if it fails
- 46. Copyright © 2016 M/Gateway Developments Ltd
Back-end module
module.exports = {
handlers: {
login: function(messageObj, session, send, finished) {
if (session.authenticated) {
finished({error: 'You have already logged in'});
return;
}
if (messageObj.params.username === '') {
finished({error: 'You must enter a username'});
return;
}
if (messageObj.params.password === '') {
finished({error: 'You must enter a password'});
return;
}
if (messageObj.params.username !== 'rob') {
finished({error: 'Invalid username'});
return;
}
if (messageObj.params.password !== 'secret') {
finished({error: 'Invalid password'});
return;
}
session.authenticated = true;
finished({
ok: true,
name: 'Rob'
});
}
}
};
~/qewd/node_modules/react-demo1.js
Here's our simple
hard-coded validation
Username must be
'rob' and password
must be 'secret'
- 47. Copyright © 2016 M/Gateway Developments Ltd
Back-end module
module.exports = {
handlers: {
login: function(messageObj, session, send, finished) {
if (session.authenticated) {
finished({error: 'You have already logged in'});
return;
}
if (messageObj.params.username === '') {
finished({error: 'You must enter a username'});
return;
}
if (messageObj.params.password === '') {
finished({error: 'You must enter a password'});
return;
}
if (messageObj.params.username !== 'rob') {
finished({error: 'Invalid username'});
return;
}
if (messageObj.params.password !== 'secret') {
finished({error: 'Invalid password'});
return;
}
session.authenticated = true;
finished({
ok: true,
name: 'Rob'
});
}
}
};
~/qewd/node_modules/react-demo1.js
Set the session
authenticated
property
- 48. Copyright © 2016 M/Gateway Developments Ltd
Back-end module
module.exports = {
handlers: {
login: function(messageObj, session, send, finished) {
if (session.authenticated) {
finished({error: 'You have already logged in'});
return;
}
if (messageObj.params.username === '') {
finished({error: 'You must enter a username'});
return;
}
if (messageObj.params.password === '') {
finished({error: 'You must enter a password'});
return;
}
if (messageObj.params.username !== 'rob') {
finished({error: 'Invalid username'});
return;
}
if (messageObj.params.password !== 'secret') {
finished({error: 'Invalid password'});
return;
}
session.authenticated = true;
finished({
ok: true,
name: 'Rob'
});
}
}
};
~/qewd/node_modules/react-demo1.js
Return a user name
in the response object
This simple example uses
a hard-coded value: 'Rob'
- 49. Copyright © 2016 M/Gateway Developments Ltd
That should be it!
• Re-bundle it using Browserify in the
normal way
• Try running it!
- 51. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
Initially
Initial Title Display the form No Content
- 53. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
On login error
Initial Title Display the form No Content
Display Error
- 54. Copyright © 2016 M/Gateway Developments Ltd
Successful login
Username: rob ; password: secret
- 55. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
On Successful
login
Hello {{user}}
title
Hide the form Display
Content
- 57. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Send username
& password as EWD
message
- 58. Copyright © 2016 M/Gateway Developments Ltd
Login-controller.js
module.exports = function (controller, component) {
component.LoginBtnClicked = function(e) {
var username = $('#username').val();
var password = $('#password').val();
if (username === '') {
alert('You must enter a username!');
return;
}
if (password === '') {
alert('You must enter a password!');
return;
}
controller.send({
type: 'login',
params: {
username: username,
password: password
}
});
};
return controller;
};
Define the
Login button's
click handler
- 59. Copyright © 2016 M/Gateway Developments Ltd
Login-controller.js
module.exports = function (controller, component) {
component.LoginBtnClicked = function(e) {
var username = $('#username').val();
var password = $('#password').val();
if (username === '') {
alert('You must enter a username!');
return;
}
if (password === '') {
alert('You must enter a password!');
return;
}
controller.send({
type: 'login',
params: {
username: username,
password: password
}
});
};
return controller;
};
Send the username
and password to
the ewd-xpress
Back-end
The response is
handled in the
Parent component
- 60. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Send username
& password as EWD
message
To Back-end
module:
react-demo1.js
- 61. Copyright © 2016 M/Gateway Developments Ltd
Back-end module
module.exports = {
handlers: {
login: function(messageObj, session, send, finished) {
if (session.authenticated) {
finished({error: 'You have already logged in'});
return;
}
if (messageObj.params.username === '') {
finished({error: 'You must enter a username'});
return;
}
if (messageObj.params.password === '') {
finished({error: 'You must enter a password'});
return;
}
if (messageObj.params.username !== 'rob') {
finished({error: 'Invalid username'});
return;
}
if (messageObj.params.password !== 'secret') {
finished({error: 'Invalid password'});
return;
}
session.authenticated = true;
finished({
ok: true,
name: 'Rob'
});
}
}
};
~/qewd/node_modules/react-demo1.js
Here's our simple
hard-coded validation
Username must be
'rob' and password
must be 'secret'
- 62. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
From
Back-end
Handle response
- 63. Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.js
module.exports = function (controller, component) {
controller.log = true;
component.loggedIn = false;
component.username = '';
component.content = '';
controller.on('error', function(responseObj) {
alert('Error: ' + responseObj.message.error);
});
controller.on('login', function(responseObj) {
if (!responseObj.message.error) {
console.log('Logged in!');
component.loggedIn = true;
component.username = responseObj.message.name;
component.content = 'User has logged in - ready to display some content for the user!';
component.setState({
status: 'loggedIn'
});
}
});
return controller;
};
error handler displays
alerts
- 64. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Error response
received:
Display Error
- 65. Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.js
module.exports = function (controller, component) {
controller.log = true;
component.loggedIn = false;
component.username = '';
component.content = '';
controller.on('error', function(responseObj) {
alert('Error: ' + responseObj.message.error);
});
controller.on('login', function(responseObj) {
if (!responseObj.message.error) {
console.log('Logged in!');
component.loggedIn = true;
component.username = responseObj.message.name;
component.content = 'User has logged in - ready to display some content for the user!';
component.setState({
status: 'loggedIn'
});
}
});
return controller;
};
login handler deals
with successful
logins
- 66. Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.js
module.exports = function (controller, component) {
controller.log = true;
component.loggedIn = false;
component.username = '';
component.content = '';
controller.on('error', function(responseObj) {
alert('Error: ' + responseObj.message.error);
});
controller.on('login', function(responseObj) {
if (!responseObj.message.error) {
console.log('Logged in!');
component.loggedIn = true;
component.username = responseObj.message.name;
component.content = 'User has logged in - ready to display some content for the user!';
component.setState({
status: 'loggedIn'
});
}
});
return controller;
};
New values
passed as
props to child
components
if login is
successful
- 67. Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.js
module.exports = function (controller, component) {
controller.log = true;
component.loggedIn = false;
component.username = '';
component.content = '';
controller.on('error', function(responseObj) {
alert('Error: ' + responseObj.message.error);
});
controller.on('login', function(responseObj) {
if (!responseObj.message.error) {
console.log('Logged in!');
component.loggedIn = true;
component.username = responseObj.message.name;
component.content = 'User has logged in - ready to display some content for the user!';
component.setState({
status: 'loggedIn'
});
}
});
return controller;
};
State value
changed to
trigger
re-render of
this component
and its child
components
- 68. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Success response
received:
Re-render
- 69. Copyright © 2016 M/Gateway Developments Ltd
MainPage.js
"use strict"
var React = require('react');
var Title = require('./Title');
var Content = require('./Content');
var Login = require('./Login');
var jQuery = require('jquery');
window.$ = window.jQuery = jQuery;
var controller;
var MainPage = React.createClass({
getInitialState: function() {
return {
status: 'initial',
}
},
componentWillMount: function() {
controller = require('./MainPage-controller')(this.props.controller, this);
},
render: function() {
console.log('Rendering MainPage');
return (
<div>
<Title
controller = {controller}
username = {this.username}
/>
<Login
controller = {controller}
loggedIn = {this.loggedIn}
/>
<Content
controller = {controller}
content = {this.content}
/>
</div>
);
}
});
module.exports = MainPage;
props passed
to child
components
- 70. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Pass down
Username as
prop
- 71. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Pass prop to
Signal successful
login
- 72. Copyright © 2016 M/Gateway Developments Ltd
React.js Design
Main Page
Title / Banner Login Form Content
React.js Mechanics
Pass prop to
signal that
content should
be displayed
- 73. Copyright © 2016 M/Gateway Developments Ltd
And so we have a working demo!
Username: rob ; password: secret