How To Use Facebook Login with React and Babel


TL;DR: You can check out the complete application at this Github repository


Update (2015-12-17): This post is out of date. I will update this post for React 0.14, soon.

I have a side project that uses React and Babel which I needed to use Facebook Login. Unfortunately, I had to figure it out myself because I couldn’t find good documentation.

I’ve created this blog post so those who want to do the same thing don’t have to suffer like me. Hopefully, Google managed to index this page for you to find me.

I will go through a step-by-step process . You will likely need to customize this process for your application. This is just a bare bones example.

Let’s start by setting up your Facebook Account.

Setup Your Facebook Application

Login to your Facebook Developer Account

Go to https://developers.facebook.com/products/analytics/, and login to your account.  

You should see something similar to the screenshot below when you click on the “My Apps” link

001_create_facebook_app

Create a New App

When you click on the “Create a New App” button, the website should show a popup similar to the screenshot below.

002_create_a_new_app

Give you project a name, and category.

I name my project “React Login POC”, and assigned it to the category “Apps for Pages”.

Move Back to the App Dashboard

After you create your app, you can go to the dashboard to configure it. I have provided a screenshot of what my dashboard looks like.

003_app_dashboard

Choose Platform

When you click on the “Choose a Platform” button on the dashboard, the website will present you with the following options.

004_choose_platform

Choose the website option.

Setup the Site Url

You now have to configure the site url for your app. I choose to host my application at http://localhost:3000. I have provided a screenshot below.

006_site_url

How you setup your site url will determine how you build your gulp workflow later.

Go the Advanced Settings

Go to the settings page for your application and click on the Advanced tab.

007_advanced_settings

Setup the Redirect URI

Enable “Embedded Browser OAuth Login”, and include the same host information you provided for the site url as one of the options for “Valid OAuth redirect URIs”.

008_redirect_uri

Setup the Project

Now that we have configured our facebook app, we can start to build the react application. Let’s start my setting up the project.

I will assume that you are using linux.

Create a directory for the project and change to the directory:

Initialize the directory as a node project:

Install (a) gulp, (b) jasmine, (c) browserify, (d) eventemitter, (e) run-sequence, (f) vinyl-source-stream, (g) gulp-connect, (e) opn, and (f) react with the following commands

Create the following folder structure

  • src
  • app

with the following commands

We will place our react code in src, and the generated code in app.

Build the Gulp Workflow

I modified the gulp workflow from gulpfile that I made for the project in my last blog post.

This workflow uses gulp-connect and opn to start a webserver and open a web browser after successfully building the application.

We have to do this because the Facebook makes us register a suite url and redirect uri with them in order to use their Facebook Connect SDK.

If we tried to run the application directly from the file system then Facebook would deny our attempt to authenticate with them.

Build the React Application

Generate the Facebook Login Button

Facebook provides an easy way to generate a Facebook Login Button.

Go to the following webpage to generate a Facebook Login Button: https://developers.facebook.com/docs/facebook-login/web/login-button

009_generate_fb_button

Make sure to enable the logout button because we will use that feature in our application.

When you click on the “Get Code” button, you will see the following popup.

010_javascript_code

We will use and modify the provided code to suite our react application.

Build the Facebook Login Button in React

Facebook provided us with the following code snippet as part of the facebook login button process.

We will use this in our React Component to build our Facebook Button.

Create the file src/FacebookButton.jsx with the following contents:

This component will do several things:

  • It will display a facebook login button based on what we generated above
  • When we login, it will show us our name
  • When we logout, it will remove our name

Notice that we provided a FB module to the constructor, and that we use it to respond to events. We will need to setup the mechanism where we can provide this component with the FB module through dependency injection.

Create the Main React Component

Every application has a main component that bootstraps the application.

The following code servers that purpose.

Create the file src/Main.jsx with the following contents

Create the Index Page

When we generated the login button, Facebook provided us with the following code snippet.

We have to modify this a bit to get our Facebook Button to work properly.

Create app/index.html with the following contents:

I am eagerly loading the javascript sdk instead of dynamically loading it because I need to make sure that the FB module is available when I inject it into FacebookButton.

Execute the Application

We can now run our application with gulp.

Once gulp completes, it should open a browser and display the webpage. It should looks something like this:

login_before

When you click on the “Log In” button, the webpage will open a popup for you to enter your username and password.

facebook_login

After you successfully, login then you will have to grant the application permission to access your profile information.

facebook_permission

Once you click “Okay”, you should see the welcome message with your name, and the “Log Out” button.

login_after

Conclusion

This is not a particularly elegant way of doing it. I’m sure that there are much better ways, but it does get the job done. Hopefully, you can use it to build something that suites your needs.

How to Build React Applications with Node.js, Jasmine, Babel, and Gulp


TL;DR: you can find the entire code at my github repository.


Facebook’s React has completely changed the way that I write applications. From my perspective, most javascript frameworks unnecessarily force you into particular programming styles. For example, I often hear people tell me to do things the “angular way” (whatever that means).

This isn’t necessarily a bad thing. Programming standards enable team development. However, I believe that the software architect or the team itself should develop those standards. Framework designers do not know your particular needs and concerns.

In the end, framework designers try to solve their problems. They do not generally care to solve your problems. Many times our problems will overlap with their problems, but it becomes incredibly hard to development when they do not.

We do not always know what designs work at different stages in our software lifecycle; so, we need to have as much control over the design of our applications as possible

In my opinion, React has a much better design simply because it makes much less assumptions.

Consider Angular 1.x. While it is a great framework, it also has an all or nothing philosophy. It is very hard to use it’s data-binding feature without also using its controllers, directives, modules, etc …

React only concerns itself with views.

This makes it possible to create a customized architecture around my particular use cases.

I created simple todo application that demonstrates how you can do this.

I would like to use this blog post to demonstrate in a step-by-step way to build it.

First let’s describe the use case for the application.

Gather the Requirements

Suppose we have the following requirements for our todo application

Use Case 1.0: Add List Items

We expect to give a list item to the application. The application should store this list item, and provide visual feedback that it has stored it.

Use Case 1.1: Detect Invalid List Items

We consider an empty string as invalid input. If we give invalid input we expect the system to detect it and give some visual feedback to the user about it.

Use Case 2.0: Remove List Items

We expect the application to allow us to remove items. The application should provide some visual of all the list items, and it should expose some way to remove individual list items.

When we remove a list item, the application should provide some visual feedback about removing the list item.

Decide on an Tool Set

In order to build the application, we need to make some initial design decisions.

For this tutorial, I decided to build the application in the following tools:

  • React + Babel for views
  • Node.js for the main application
  • Jasmine for testing
  • Gulp for building the application

Setup the Project

I will assume that you are using linux.

Create a directory for the project

change to the directory

Initialize the directory as a node project

Install (a) gulp, (b) jasmine, (c) browserify, (d) eventemitter, (e) run-sequence, and (f) vinyl-source-stream with the following commands:

Create the following folder structure

  • src/common
  • src/model
  • src/view
  • test
  • app

with the following commands

We will put (a) our react code in the “src/view” folder, (b) our node code in the “src/model” and “src/common” folders, (c) our jasmine tests in the “test” folder, and (c) our application into the “app” folder.

Build the Model

Let’s encapsulate the algorithms that fulfill these uses cases into a single node.js module.

Create the following file: src/model/TodoListModel.js.

TodoListModel references another node file called Guid. By design, we force the caller of TodoListModel.addItem to provide a guid as an argument.

I did this to make unit testing easy. We will illustrate unit testing in the next section.

Create the following file: src/common/Guid.js

Create the Unit Tests

We need to validate that TodoListModel actually implements our use cases correctly. We will create separate jasmine specs for each use case.

Create Tests for Use Case 1.0

We want to verify that the model obeys the following constraints when we add list items:

  • The model adds the list item properly when we add one list item
  • The model adds list items properly when we add two list items
  • The model fires events that informs subscribers that the model has added a list item

Create test/AddListItems.spec.js with the following contents to validate that our model obeys the rules for “Use Case 1.0”.

Create Tests for Use Case 1.1

We want to verify that the model obeys the following constraints when we add add list items:

  • Detect when the caller does not provide a valid list item
  • Detect when the caller does not provide a valid guid
  • Verify that the model fires the proper events for an invalid input

Create test/DetectInvalidListItem.spec.js

Create Tests for Use Case 2.0

We want to verify that the model obeys the following constraints when we try to remove items:

  • The model properly removes one item
  • The model properly removes 2 of three items
  • The model fires the proper events when it removes items

Create test/RemoveListItems.spec.js

Execute Unit Tests

We will use gulp to execute our unit tests.

In the main directory, create gulpfile.js with the following contents

Change the NODE_PATH to include ./src. This will ensure that model/TodoListModel.js and common/Guid.js are discoverable.

Our gulp file will now execute our jasmine tests by default. Let’s run it and see the result.

Build the Gulp Workflow

Now that we have a working model let’s build the application. I want to have a very simple deployment. I would like the entire application to run using this html.

I want bundle.js to bootstrap the entire application for index.html.

Let’s modify gulpfile.js to support this.

This will browserify all our react code (which we have not created yet) and package it into bundle.js in the app folder. Further, gulp will use babel to transpile our react code into ES5 javascript. We want to use babel with react because it will provide us with a better syntax than standard javascript.

Build the Views

Create src/Main.jsx with the following contents.

This code shows that we have a UI with three general components:

  • A message component
  • An input component
  • A list component

Further, each component takes a TodoListModel instance as an argument to it’s constructor.

Let’s build out each component one at a time.

Create a MessageArea Component

Create src/view/MessageArea.jsx

Create InputArea Component

Create src/view/InputArea.jsx

Create a TodoList Component

Create src/view/TodoList.jsx

ListBox.jsx creates several ListItems components as children.

Let’s create the component definition.

Create src/view/ListItem.jsx

Build the Application

We can now run gulp.

This gulp build uses babel to transpile the ES6 code into standard javascript and browserfys it into bundle.js in app.

You can open index.html in a browser to execute the application. It should look something like this:

Screenshot - 09162015 - 06:20:49 PM

Conclusion

I know that this project is very artificial. I only want you to take away the principles. You ultimately have to make decisions for you applications. Architecting your projects like this may or may not make sense for you.

How To Automate Jasmine Tests for Typescript with Gulp

I have a gulp workflow that I’d like to share with the javascript community. This workflow automates the compilation of typescript and tests the generated code with Jasmine.

Why Another Workflow?  

I personally like to build my own workflows whenever possible.

I know that advanced editors like Visual Studio have tools that automate a lot. However, I feel that software development is too complicated for a single workflow to automate everything.

IMO, there are simply too many details in software development. At some point, you always need to do something custom. 

Enter Gulp

I feel that gulp has the best approach to creating workflows, currently.

Gulp has a massive collection of plugins that you can reuse for common tasks, and you can stitch various plugins together programmatically.

Creating the Workflow  

I will provide a step-by-step walk-through that shows how to use the linux command line to setup a project. You may not be able to use this process if you use something like Visual Studios to setup your typescript applications.

Create the Folder Structure

Create the following folder structure

  • src/ts
  • src/js
  • spec

with the following commands

We will put our typescript code in src/ts, our generated javascript code into src/js, and our jasmine tests into spec.

Setup the Project

Initialize the directory as a node project.

Install node plugins

Create a custom node module

We will need to take the contents of the generated javascript file that typescript produces and evaluate it in the jasmine files. In order to make this easier, we will create a helper module called __require.js in the root folder.

By design, we will place all generated javascript code under src/js. If we had an alternate location then we would have to reflect that in __require.js.

Alter NODE_PATH

In order to make __require.js discoverable by node, we can change the NODE_PATH environment variable to include the current directory

Create Program and Unit Tests

Create a Set class with Typescript at src/ts/Set.ts

This Set class is a very naive implementation of a basic set for the sake illustration.

Place the following Jasmine code under spec/Set.spec.js

These lines of code in Set.spec.js deserves some explaining:

By design, node modules need to follow the commonjs format. If you “require” a file that does not follow the commonjs format then node will return an empty object.

Since Typescript does not actually generate code that obeys the commonjs format, we need to create a method for us to get the generated code into the scope of a jasmine test.

I created __require.js because it makes it very easy to include the contents of a file under the directory I designated as generated code.

Create Gulp Tasks

We now have everything in place to execute our workflow. Create gulpfile.js under the root directory with the following contents.

This workflow will do the following:

  • compile all typescript code in the src/ts directory
  • place the generated javascript code in the src/js directory
  • run all jasmine tests in the spec directory

runSequence will make sure that your workflow will compile all the Typescript files first before gulp runs the unit tests. If we did not use runSequence then gulp would run the tests concurrently with the compilation.

In order to initiate this workflow we simply have to execute gulp from the directory like so:

Conclusion

In practice, there are many different ways of creating workflows. I don’t claim that this is somehow the best or only way to do it.

I hope that this particular example can help you build a workflow that works best for you.