Saturday, April 22, 2017

"React components, do you need class to do them properly?" -or- "local state, It's a trap!"


So, I'm looking at https://facebook.github.io/react/docs/state-and-lifecycle.html and how React has leveraged the class construct and hierarchy in encapsulating the clock class in the example. I'm wondering, is the class construct necessary, and I'm very much hoping it is not. I'm going to try to re-create the example without using the class and extends and sticking with functional javascript. We already know you can use stateless functional components, but can we use local state in a functional component.

It would seem not entirely, you need a stateful component somewhere in your application. It looks like the right place for this is as close to the root of the application as you can get it, if you want to move toward having a single state atom (which looks extremely beneficial). So how can we re-write the react clock example using a stateless functional component.

<div id="container"> 
<!-- This element's contents will be replaced with your component. --> 
</div> 

function Clock(props) { 
    return <div><h1>Hello, world! </h1> <h2>It is {props.date.toLocaleTimeString()}. </h2></div> 
} 

var App = React.createClass({ 
    getInitialState: function() { 
        return { date: new Date() }; 
    }, 
    render: function() { 
        return <Clock date={this.state.date} />; 
    }, 
    componentDidMount: function() { 
        this.timerID = setInterval(() => this.setState({date: new Date()}),1000); 
    } 
}); 

 
ReactDOM.render( <App /> , 
    document.getElementById('container') 
); 


So, this gets the application state all in one place, in the App class, which we can persist or restore atomically, enabling time travel debugging and keeping us from getting in an inconsistent state. This doesn't necessarily mean you want all state in one place, just that relevant to App.

https://facebook.github.io/react/docs/state-and-lifecycle.html
https://www.safaribooksonline.com/blog/2015/10/29/react-local-component-state/
https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc

https://github.com/reactjs/redux/issues/1385

MERN Series Step 5 - Auth0 React Client Template


Reviewing the link from last time, https://auth0.com/docs/quickstart/spa/react, let's see what the create-react-app scripts get us.

This also led me to the link for the facebook create-react-app scripts: https://github.com/facebookincubator/create-react-app, I'll review and compare that as well in this article.

It looks like the create-react-app script is focused on the client side portion of the app, which makes sense, and the folder structure is somewhat different than that provided by tech-dojo's start repo (https://github.com/tech-dojo/mern, so they're all in one place).

For review, here's the structure tech-dojo gave us:

| .gitignore 
| CONTRIBUTING.md 
| favicon.ico 
| gulpfile.js 
| LICENSE 
| package.json 
| README.md 
| yarn.lock 
+---app 
| | .DS_Store 
| | index.ejs 
| | main.jsx 
| | style.css 
| | 
| +---components 
| | | App.jsx 
| | | 
| | +---articles 
| | | CreateArticle.jsx 
| | | EditArticle.jsx 
| | | Form.jsx 
| | | ListArticles.jsx 
| | | ListArticlesChild.jsx 
| | | ViewArticle.jsx 
| | | ViewArticleChild.jsx 
| | | 
| | +---core 
| | | Footer.jsx 
| | | Header.jsx 
| | | Home.jsx 
| | | Template.jsx 
| | | 
| | \---users 
| | EditUserProfile.jsx 
| | EditUserProfileChild.jsx 
| | Signin.jsx 
| | SigninChild.jsx 
| | SignOut.jsx 
| | Signup.jsx 
| | SignupChild.jsx 
| | 
| +---images 
| | | … 
| | | 
| | \---fav 
| | … 
| | 
| +---services 
| | Authentication.js 
| | 
| \---stores 
| ArticleStore.jsx 
| RestAPI_Helper.js 
| UserStore.jsx 
+---server 
| | express.js 
| | passport.js 
| | seeds.js 
| | server.js 
| | 
| +---config 
| | | config.js 
| | | 
| | \---env 
| | all.js 
| | development.js 
| | local.example.js 
| | production.js 
| | test.js 
| | 
| +---controllers 
| | | .DS_Store 
| | | articles.server.controller.js 
| | | errors.server.controller.js 
| | | users.server.controller.js 
| | | 
| | \---users 
| | users.authentication.server.controller.js 
| | users.authorization.server.controller.js 
| | users.password.server.controller.js 
| | users.profile.server.controller.js 
| | 
| +---models 
| | .DS_Store 
| | Article.js 
| | User.js 
| | 
| +---routes 
| | .DS_Store 
| | article.server.routes.js 
| | routeHelper.js 
| | users.server.routes.js 
| | 
| \---strategies 
| facebook.js 
| github.js 
| google.js 
| linkedin.js 
| local.js 
| twitter.js 
\---tests 
| article.server.model.test.js 
| article.server.routes.test.js 
| user.server.model.test.js 
\---componentTest 
article.test.jsx 
articleStore.test.jsx 
user.test.jsx 
userStore.test.jsx 

This does contain some potentially extraneous items that someone not initially learning React may not need (i.e. articles, users), and yes, I know lots of "may" in there. I am learning React, so I can't tell you that yet.

Facebook's vanilla create-react-app script gives you this structure:

| .gitignore
| package.json
| README.md
|
+---public
| favicon.ico
| index.html
|
\---src
App.css
App.js
App.test.js
index.css
index.js
logo.svg

They have a great section on why to use this for creating your app, and how to customize it in the future if you need to: https://github.com/facebookincubator/create-react-app#why-use-this. This structure seems a bit more simplistic than I'd like, having everything in the src folder, but may be good for getting something up and going quickly.

Installing the auth extensions to the facebook app using create-react-app my-app1 --scripts-version auth0-react-scripts gives the same basic structure, but at least has a components folder under src, and the addition of auth0 stuff.

| .env.example 
| .gitignore 
| package.json 
| README.md 
+---public 
| favicon.ico 
| index.html 
\---src 
| auth.js 
| index.css 
| index.js 
| logo.svg 
\---components 
App.js 
App.test.js 
EditProfile.css 
EditProfile.js 
Home.css 
Home.js 
Login.css 
Login.js 
Site.css 
Site.js 

So, I'll be sticking with my initial layout, and just copy the auth0 stuff from the components folder generated by the auth0 extensions to create-react-app into an auth folder under my components folder, so it will end up looking like this:

| +---components 
| | | App.jsx 
| | | 
| | +---articles 
| | | CreateArticle.jsx 
| | | EditArticle.jsx 
| | | Form.jsx 
| | | ListArticles.jsx 
| | | ListArticlesChild.jsx 
| | | ViewArticle.jsx 
| | | ViewArticleChild.jsx 
| | | 
| | +---core 
| | | Footer.jsx 
| | | Header.jsx 
| | | Home.jsx 
| | | Template.jsx 
| | | 
| | +---users 
| | | EditUserProfile.jsx 
| | | EditUserProfileChild.jsx 
| | | Signin.jsx 
| | | SigninChild.jsx 
| | | SignOut.jsx 
| | | Signup.jsx 
| | | SignupChild.jsx 
| | \---auth 
| | EditProfile.css 
| | EditProfile.js 
| | Login.css 
| | Login.js 

There's also an auth.js in the src folder one layer up from components that I'm copying over also. So that's going to be my basic layout with auth0, next article I'll cover anything needed to integrate and get everything running with the MERN starter project from tech-dojo.

x
x

Sunday, April 16, 2017

Learn to code deal

https://academy.sciencealert.com/sales/pwyw-learn-to-code-2017-google-go?utm_source=sciencealert.com&utm_medium=referral&utm_campaign=pwyw-learn-to-code-2017-google-go_020217&utm_term=scsf-211745

Learn to code package.  I haven't tried anything from these people, I'm going to try this one though, has a lot of languages I want to learn more about.

Friday, April 14, 2017

MERN Series Step 4 - Authentication with Auth0

https://auth0.com/docs/overview
They have a great intro video, watch it.

Our starter project already came with passport, so we'll just need to add passport-auth0 and express-session:
Yarn add passport-auth0 express-session auth0-lock


Looking at the architecture options, SPA+API looks like a natural fit to pursue: https://auth0.com/docs/architecture-scenarios/application/spa-api

You can also use the spa quickstart https://auth0.com/docs/quickstart/spa/react, that looks like it has some scripting that would be useful, I'll review that and compare in the next article.

You may also want to review JWTs as auth0 uses them, and they are beyond the scope of what I'm writing about in this series, I may get into some more detail later, but my focus with this series is not on JWTs.

First step, create a new account with the website name, then select Single Page App for the application type:

This will then present you with a sample project you can download (that will have your keys in it).  I've downloaded mine, it looks like the two files you'll need are in src/utils, with the rest of the code showing how to integrate into your app.  The .env file in the root contains your auth0 clientid and domain.  The code in src/views/Main/routes.js has examples of how to protect routes using react-router.  You can run the project itself using npm start, it just serves up a page with a login control that opens the auth0 login widget. 


Run it and try to log in and it will fail with CORS error.  Take a look at the logs for your auth0 Client (the application)


This means that we'll need to add http://localhost:3000 in order to have our sample auth0 app to connect.  Click on Clients, then on your app (mine is still "Default App") then settings, scroll down to "Allowed Origins (CORS)" and add http://localhost:3000, while you're there add http://localhost:3000/login to the "Allowed Callback URLs" area, as the sample app uses that for where auth0 sends data back to it.  Once you've done that you'll be able to login using one of the providers you've enabled (I enabled google and linked-in since this is a job board), and you should see a lovely landing page with welcoming you by name (nice!), with a logout button.

We'll take this sample app and incorporate it into our main application.  I'll be using a login widget instead of the full page layout of the auth0 sample, but beyond that we'll leave it the same.  We'll also use auth0 for authorization once we get to where we have multiple roles for our app.  Now, since we've logged into our app, you'll be able to see yourself as a user and view details.  Check it out under users:

Sunday, April 9, 2017

MERN Series Step 3 - Which client app

After looking at the two clients, one from generator-webapp and the other from tech-dojo's starter repo, I'm going to go with the app from tech-dojo, as it's structure is laid out for react components and services, vs generator-webapp is pretty generic and I'd have to do all the react setup myself.
Generator-webapp gives you an app folder with fonts, images, scripts and styles, which is fine for your generic client side app.  It also gives you a decent gulpfile to start with, and a tests folder using mocha and chai.
Tech-dojo's MERN starter gives you an app folder with components (with some examples coded, articles, core, and users), images, services, and stores, a gulpfile that I'm not familiar with yet, tests using mocha/chai/sinon with tests set up to run against the components, and you also get test coverage reporting.  On top of that you get the server folder set up to use express, mongoose, passport, and some seed data for the example components.
 
So, basically if you're reading these all in one go, skip everything I did in step one :) I'll be updating the article to reflect this new information and moving on to setting up login next using auth0, because security is hard and I don't have time to stay on top of it, and it’s their job to do so.  
Which brings me to a general point, if something is not part of your core business, don’t write it if you don't have to!  I'm not going to re-write paypal functionality if I want to take payments, nor am I going to write an email service.  Bring in something open source, or buy it if you need to, but only write it if you have to. 

Saturday, April 8, 2017

MERN Series Step 2 - MongoDB and yomern

MongoDB installation guide is located here: https://docs.mongodb.com/v3.0/installation/. I am a big fan of chocolatey, so I'll be using chocolatey command line to install it: choco install -y mongodb.

Some handy mongodb commands:
https://docs.mongodb.com/v3.0/tutorial/install-mongodb-on-windows/#run-mongodb

I'm using tech-dojo's MERN framework, read the docs on tech-dojo's page as there is more to it than just the generator, they have a starter in github:
git clone https://github.com/tech-dojo/mern

The starter app uses mocha/chai/sinon stack for testing, which I prefer over Jasmine/Karma. Once installed, verify the app is working by running gulp serve
Run the unit tests using gulp test. I had one user test fail, but everything else passed.

Choosing a generator/starter project is mainly governed by what you want to use in the project. There are several options out there for MERN type stacks, I chose tech-dojo's because it uses the testing stack I'm interested in, as well as using express and mongodb. Some other options that looked promising:
  • mern-cli from http://mern.io for scaffolding and code generation 
  • Accelerate looks like it might be interesting , but appears to be more than just a generator, I may look at it in detail later. 
  • You could probably also get away with using parts of angular-fullstack generator, but that seems like wasting its potential. If you're going with MEAN stack it's definitely the way to go. 
  • Fountain-webapp also look like it could be good, it's using Karma for testing 
  • Last one I'll list, react-fullstack look very popular, but hasn't been updated in a year. 
This process leaves you with both client and server side set up, so I'll need to look at what's in this client vs what I set up using yo webapp in the previous article. I know I don't like currently having both the client and server in the same git repo, and the tests for both client and server are in the tests folder instead of separated. This makes it more difficult to rev them independently. I'll likely at least be splitting the repo into two and split the tests.

I also noticed a number of deprecated packages during the npm install, I will investigate updating all of these after I get the base scaffolding done.

It looks like the yomern yeoman generator is for creating components of functionality, which seems like it would be quite useful to eliminate boilerplate