React.js – AppDividend https://appdividend.com Latest Code Tutorials Wed, 17 Apr 2019 20:04:43 +0000 en-US hourly 1 https://wordpress.org/?v=5.1.1 https://appdividend.com/wp-content/uploads/2017/08/cropped-ApDivi-32x32.png React.js – AppDividend https://appdividend.com 32 32 React Material UI Example Tutorial https://appdividend.com/2018/11/13/react-material-ui-example-tutorial/ https://appdividend.com/2018/11/13/react-material-ui-example-tutorial/#comments Tue, 13 Nov 2018 10:05:13 +0000 http://localhost/wordpress/?p=2181 React Material UI Tutorial With Example From Scratch

React Material UI Example is today’s leading topic. It is the React components that implement Google’s Material Design. Material Design layouts encourage consistency across platforms, environments, and screen sizes by using uniform elements and spacing. Material-UI supports the latest and stable releases of across all the browsers and platforms. They also support Internet Explorer 11. You don’t need to […]

The post React Material UI Example Tutorial appeared first on AppDividend.

]]>
React Material UI Tutorial With Example From Scratch

React Material UI Example is today’s leading topic. It is the React components that implement Google’s Material Design. Material Design layouts encourage consistency across platforms, environments, and screen sizes by using uniform elements and spacing. Material-UI supports the latest and stable releases of across all the browsers and platforms. They also support Internet Explorer 11. You don’t need to provide any JavaScript polyfill as we manage unsupported browser features internally and in isolation. Let us take the React Material Example Tutorial From Scratch.

If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.

React Material UI Example

Let us first install React.js using the following commands.

#1: Install React.js

npx create-react-app materialui
cd materialui
npm start

 

React Material UI Example

If you are facing any issue on compiling then, please create a .env file on the root and add the following line of code.

SKIP_PREFLIGHT_CHECK=true

#2: Install Material-UI

Type the following command to install Material-UI.

npm install @material-ui/core --save

# or

yarn add @material-ui/core

Now, modify the following code inside the App.js file.

// App.js

import React, { Component } from 'react';
import Button from '@material-ui/core/Button';

class App extends Component {
  render() {
    return (
      <Button variant="contained" color="primary">
        Welcome Material UI
      </Button>
    );
  }
}

export default App;

Save the file and go to the browser and you can see that we have successfully integrated the Material UI.

#SVG Icons

You can install the prebuild SVG icons using @material-ui/icons package.

npm install @material-ui/icons --save

# or

yarn add @material-ui/icons

#Fonts

You can include the stylesheets inside the index.html file.

<link rel="stylesheet"
  href=“https://fonts.googleapis.com/css?family=Roboto:400,500" />
<link rel="stylesheet"
  href=“https://fonts.googleapis.com/icon?family=Material+Icons" />

We can use the buttons as well as icons using the following code.

// App.js

import React, { Component } from 'react';
import Button from '@material-ui/core/Button';
import Bookmarks from '@material-ui/icons/Bookmarks';

class App extends Component {
  render() {
    return (
      <Button variant="outlined" color="primary">
        <Bookmarks></Bookmarks>
          Chaper 2
      </Button>
    );
  }
}

export default App;

You can use material.io/tools/icons to find a specific icon. When importing an icon, keep in mind that the names of the icons are PascalCase.

Notable props for the Button component include:

  • variant: The visual style of the component, either containedoutlined, fab, or empty for the default link-style.
  • color: One of primarysecondary, or default, which is the same color as if it’s left empty. We’ll cover the customization of these colors later.
  • mini: If the variant is set to fab (floating action button), then the size of the button is reduced.

#Navbar

Let us create a component inside the src folder called Navbar.js and add the following code.

// Navbar.js

import React from 'react';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';

const NavBar = () => {
    return(
        <div>
        <AppBar position="static">
            <Toolbar>
                React Material UI Example
            </Toolbar>
        </AppBar>
        </div>
    )
}
export default NavBar;

Now, import Navbar.js component inside the App.js component.

// App.js

import React, { Component } from 'react';
import Button from '@material-ui/core/Button';
import Bookmarks from '@material-ui/icons/Bookmarks';

import Navbar from './Navbar';
class App extends Component {
  render() {
    return (
      <div>
        <Navbar />
        <Button variant="outlined" color="primary">
          <Bookmarks></Bookmarks>
        </Button>
      </div>
    );
  }
}

export default App;

Now, you can see that we have implemented the basic design of the Navigation bar.

#TextField

Add a following code inside the App.js file.

// App.js

import React, { Component } from 'react';
import Button from '@material-ui/core/Button';
import Bookmarks from '@material-ui/icons/Bookmarks';

import TextField from '@material-ui/core/TextField';
import Navbar from './Navbar';

class App extends Component {
  render() {
    return (
      <div>
        <Navbar />
        <Button variant="outlined" color="primary">
          <Bookmarks></Bookmarks>
        </Button> <br />
        <TextField
          placeholder="Placeholder here"
          label="Basic TextField" />
      </div>
    );
  }
}

export default App;

Save the file, and you can see the textbox. The TextField, we have imported from @material-ui/core/TextField, behaves like the standard React input component.

#Cards

Create one file called Card.js inside the src folder. Add the following code inside the Card.js file.

// Card.js

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import IMG from './MZ.png';

const styles = {
  card: {
    maxWidth: 345,
  },
  media: {
    height: 140,
  },
};

function MediaCard(props) {
  const { classes } = props;
  return (
    <Card className={classes.card}>
      <CardActionArea>
        <CardMedia
          className={classes.media}
          image= {IMG}
          title="Contemplative Reptile"
        />
        <CardContent>
          <Typography gutterBottom variant="h5" component="h2">
            Zukerberg
          </Typography>
          <Typography component="p">
            Lizards are a widespread group of squamate reptiles, with over 6,000 species, ranging
            across all continents except Antarctica
          </Typography>
        </CardContent>
      </CardActionArea>
      <CardActions>
        <Button size="small" color="primary">
          Share
        </Button>
        <Button size="small" color="primary">
          Learn More
        </Button>
      </CardActions>
    </Card>
  );
}

MediaCard.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(MediaCard);

Save the file and import the Card.js file inside the App.js file.

// App.js

import React, { Component } from 'react';
import Button from '@material-ui/core/Button';
import Bookmarks from '@material-ui/icons/Bookmarks';

import TextField from '@material-ui/core/TextField';
import Navbar from './Navbar';
import MediaCard from './Card';

class App extends Component {
  render() {
    return (
      <div>
        <Navbar />
        <Button variant="outlined" color="primary">
          <Bookmarks></Bookmarks>
        </Button> <br />
        <TextField
          placeholder="Placeholder here"
          label="Basic TextField" />
        <MediaCard />
      </div>
    );
  }
}

export default App;

#Theming

Material-UI uses the JavaScript-based approach to theming its components called CSS-in-JS. With the help of this approach, CSS classnames are generated using JavaScript objects. 

To pass the styles object into our component, we will use the withStyles function to return the higher-order component that gives our classnames as a prop called classes.

const MyComponent = (props) => {
  const classes = props.classes;
  return (
    <div className={classes.container}>
      // stuff
    </div>
  );
}

export default withStyles(styles)(MyComponent);

Creating the custom theme

To create a custom theme, use a createMuiTheme function and pass its return value to a MuiThemeProvider element at root of your App.

import { createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles';

const theme = createMuiTheme();

const App = props => (
  <MuiThemeProvider theme={theme}>
    // your app
  </MuiThemeProvider>
);

Now, all children of a MuiThemeProvider have the uniformly customizable style!

createMuiTheme function usually takes the object to define a theme:

const theme = createMuiTheme({
  palette: {
    primary: '#e89eef',
    secondary: '#336b87'
  }
});

All colors, including a primary and the secondary colors we used earlier in the tutorial, are all themeable. The full range of options can be found in the official theming documentation. Material-UI is a great way to add the polished look and feel to the controls of your React web application with little effort.

Finally, React Material UI Example Tutorial is over.

 

The post React Material UI Example Tutorial appeared first on AppDividend.

]]>
https://appdividend.com/2018/11/13/react-material-ui-example-tutorial/feed/ 3
React CRUD Example | MERN Stack Tutorial https://appdividend.com/2018/11/11/react-crud-example-mern-stack-tutorial/ https://appdividend.com/2018/11/11/react-crud-example-mern-stack-tutorial/#comments Sun, 11 Nov 2018 20:23:48 +0000 http://localhost/wordpress/?p=2141 React CRUD Example Tutorial From Scratch

React CRUD Example | MERN Stack Tutorial is today’s leading topic. This article’s goal is to explain the by making the CRUD application. Most applications are CRUD applications. If you don’t know what CRUD is, it’s short for Create, Read, Update and Delete. This application is also called a MERN Stack application because we are using MongoDB, Express, […]

The post React CRUD Example | MERN Stack Tutorial appeared first on AppDividend.

]]>
React CRUD Example Tutorial From Scratch

React CRUD Example | MERN Stack Tutorial is today’s leading topic. This article’s goal is to explain the by making the CRUD application. Most applications are CRUD applications. If you don’t know what CRUD is, it’s short for Create, Read, Update and Delete. This application is also called a MERN Stack application because we are using MongoDB, Express, React, and Node.js tech stack. This article will show you the steps to create an app where the user can create new business, fetch that business, edit business and delete business using React.js. Let us understand the basics of React.js.

If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.

What is React?

React.js is UI Library and not a complete Framework like Angular. React is the JavaScript library for building user interfaces. It is maintained by Facebook, Instagram and a community of individual developers and corporations. You can find its official documentation here.

Why use React?

React.js allows you to express how your app should look at any given point in time. React will automatically manage all UI updates when your underlying data changes. When the data changes, React conceptually hits the “refresh” button and knows to only update the changed parts. The main reason to use React for your next project is following.

  1. Fast Learning Curve.
  2. Reusable Components.
  3. Fast render with Virtual DOM.
  4. Clean Abstraction.
  5. Redux: A State Management Library For Complex UIs.
  6. Great Developer Tools.
  7. React Native: You can build a cross-platform native mobile application for Android or iOS.

Who uses React?

Aside from Facebook and Instagram, many well-known companies use React including Dropbox, PayPal, Netflix, Airbnb and many more.

MERN Stack Tutorial

We will use the following Technologies with its version.

  1. MacOS (Mojave)
  2. Node v10.11.0
  3. NPM v6.4.1
  4. MongoDB shell version v3.6.3
  5. MongoDB version v3.6.3
  6. React.js version 16.6.1

React CRUD Example

Create a new React app using the following command.

#1: Install React Application

npx create-react-app reactcrud
cd reactcrud
npm start

 

React CRUD Example

If you are facing any issue on compiling then, please create a .env file on the root and add the following line of code.

SKIP_PREFLIGHT_CHECK=true

Go to this URL: http://localhost:3000/

 

MERN Stack Tutorial

Now, install the Bootstrap 4 Framework using the following command.

yarn add bootstrap

# or

npm install bootstrap --save

Import the Bootstrap CSS Framework inside our project.

Modify the code inside the src >> App.js file.

// App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';

class App extends Component {
  render() {
    return (
      <div className="container">
        <h2>React CRUD Tutorial</h2>
      </div>
    );
  }
}

export default App;

Save the file and go to the browser and you can see that we have successfully integrated bootstrap 4 in our react application.

#2: Configure React routing

Type the following command to install the react- router-dom module. If you want to find more information about the react-router-dom module, then you can follow this documentation.

yarn add react-router-dom

# or

npm install react-router-dom --save

Go to the index.js file and Wrap the BrowserRouter object around the App.js component.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';

import App from './App';
import * as serviceWorker from './serviceWorker';

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

serviceWorker.unregister();

Now, create three components.

Inside the src folder, create one directory called components and inside that folder, make three components.

  1. create.component.js
  2. edit.component.js
  3. index.component.js
// create.component.js

import React, { Component } from 'react';

export default class Create extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Create Component!!</p>
            </div>
        )
    }
}
// edit.component.js

import React, { Component } from 'react';

export default class Edit extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Edit Component!!</p>
            </div>
        )
    }
}
// index.component.js

import React, { Component } from 'react';

export default class Index extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Index Component!!</p>
            </div>
        )
    }
}

Now, add the navigation bar in our React CRUD example. Write a following code inside the App.js file.

// App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';

import Create from './components/create.component';
import Edit from './components/edit.component';
import Index from './components/index.component';

class App extends Component {
  render() {
    return (
      <Router>
        <div className="container">
          <nav className="navbar navbar-expand-lg navbar-light bg-light">
            <Link to={'/'} className="navbar-brand">React CRUD Example</Link>
            <div className="collapse navbar-collapse" id="navbarSupportedContent">
              <ul className="navbar-nav mr-auto">
              <li className="nav-item">
                  <Link to={'/'} className="nav-link">Home</Link>
                </li>
                <li className="nav-item">
                  <Link to={'/create'} className="nav-link">Create</Link>
                </li>
                <li className="nav-item">
                  <Link to={'/index'} className="nav-link">Index</Link>
                </li>
              </ul>
            </div>
          </nav> <br/>
          <h2>Welcome to React CRUD Tutorial</h2> <br/>
          <Switch>
              <Route exact path='/create' component={ Create } />
              <Route path='/edit/:id' component={ Edit } />
              <Route path='/index' component={ Index } />
          </Switch>
        </div>
      </Router>
    );
  }
}

export default App;

Save the file and go to the browser.

 

React CRUD Tutorial

#3: Create the bootstrap form

Write the code to generate the bootstrap form inside the create.component.js file.

// create.component.js

import React, { Component } from 'react';

export default class Create extends Component {
    render() {
        return (
            <div style={{marginTop: 10}}>
                <h3>Add New Business</h3>
                <form>
                    <div className="form-group">
                        <label>Add Person Name:  </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <label>Add Business Name: </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <label>Add GST Number: </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <input type="submit" value="Register Business" className="btn btn-primary"/>
                    </div>
                </form>
            </div>
        )
    }
}

 

MERN Stack Example

#4: Submit the Form

Okay, now we have three fields.

  1. person name
  2. business name
  3. gst number

So we need to create four functions that can track the values of the textbox and set that state according to it. Also, the fourth function will send the POST request to the node express server.

Now, first, we will define the constructor and set the initial state and then also bind this to the different events inside the constructor.

Then define the different functions with each input text values. So when the user types inside the textbox, we set the state according to it.

So, let say, the user is typing the person name inside the textbox, we are changing the state value of person name. Finally, same for all of the inputs and when we submit the form, we get the values from the state and send to the POST request.

// App.js

import React, { Component } from 'react';

export default class Create extends Component {
  constructor(props) {
      super(props);
      this.onChangePersonName = this.onChangePersonName.bind(this);
      this.onChangeBusinessName = this.onChangeBusinessName.bind(this);
      this.onChangeGstNumber = this.onChangeGstNumber.bind(this);
      this.onSubmit = this.onSubmit.bind(this);

      this.state = {
          person_name: '',
          business_name: '',
          business_gst_number:''
      }
  }
  onChangePersonName(e) {
    this.setState({
      person_name: e.target.value
    });
  }
  onChangeBusinessName(e) {
    this.setState({
      business_name: e.target.value
    })  
  }
  onChangeGstNumber(e) {
    this.setState({
      business_gst_number: e.target.value
    })
  }

  onSubmit(e) {
    e.preventDefault();
    console.log(`The values are ${this.state.person_name}, ${this.state.business_name}, and ${this.state.business_gst_number}`)
    this.setState({
      person_name: '',
      business_name: '',
      business_gst_number: ''
    })
  }
 
  render() {
      return (
          <div style={{ marginTop: 10 }}>
              <h3>Add New Business</h3>
              <form onSubmit={this.onSubmit}>
                  <div className="form-group">
                      <label>Person Name:  </label>
                      <input 
                        type="text" 
                        className="form-control" 
                        value={this.state.person_name}
                        onChange={this.onChangePersonName}
                        />
                  </div>
                  <div className="form-group">
                      <label>Business Name: </label>
                      <input type="text" 
                        className="form-control"
                        value={this.state.business_name}
                        onChange={this.onChangeBusinessName}
                        />
                  </div>
                  <div className="form-group">
                      <label>GST Number: </label>
                      <input type="text" 
                        className="form-control"
                        value={this.state.business_gst_number}
                        onChange={this.onChangeGstNumber}
                        />
                  </div>
                  <div className="form-group">
                      <input type="submit" value="Register Business" className="btn btn-primary"/>
                  </div>
              </form>
          </div>
      )
  }
}

#5: Create a backend on Node.js

Inside our reactcrud project root, create one folder called api and go inside that folder and initialize the package.json file.

npm init -y

Now, install the following node.js dependencies.

yarn add express body-parser cors mongoose

# or

npm install express body-parser cors mongoose --save

Also, install the nodemon as a development dependency. So that we do not need to restart every time, we change our server code.

npm install nodemon --save-dev

Now, inside the api folder, create one file called the server.js and add the following code inside it.

// server.js

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.listen(PORT, function(){
  console.log('Server is running on Port:',PORT);
});

Save the file and open a new tab terminal inside the api folder and hit the following command to spin up the node.js server.

nodemon server

You can see inside the terminal that, our node.js server is running.

React CRUD Example | MERN Stack Tutorial

 

#6: Setup a MongoDB database

If you are a beginner in MongoDB database, then please check out by below tutorial.

Related Post: NoSQL MongoDB Tutorial

I have already installed the MongoDB on Mac. So I am starting the MongoDB server by the following command.

mongod

Inside the api folder, create one file called the DB.js and add the following line of code.

// DB.js

module.exports = {
    DB: 'mongodb://localhost:27017/reactcrud'
}

In my local MongoDB database, the username and password are empty, but in the production, you need to create one admin user and assign the database to that user.

Now, import this DB.js file into the server.js file.

// server.js

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');
const mongoose = require('mongoose');
const config = require('./DB.js');

mongoose.Promise = global.Promise;
mongoose.connect(config.DB, { useNewUrlParser: true }).then(
  () => {console.log('Database is connected') },
  err => { console.log('Can not connect to the database'+ err)}
);

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.listen(PORT, function(){
  console.log('Server is running on Port:',PORT);
});

Save the file, and you can see inside the terminal that our node.js application is connected to a mongodb database.

#7: Create a Mongoose Schema

Next step is that we need to create a schema for the mongodb database. For that, create a file inside the api project root called business.model.js and add the following code.

// business.model.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// Define collection and schema for Business
let Business = new Schema({
  person_name: {
    type: String
  },
  business_name: {
    type: String
  },
  business_gst_number: {
    type: Number
  }
},{
    collection: 'business'
});

module.exports = mongoose.model('Business', Business);

We have taken three fields called person_name, business_name, and business_gst_number with its datatypes.

#8: Define the route for Node.js Express application

Write the CRUD code inside the business.route.js file.

// business.route.js

const express = require('express');
const businessRoutes = express.Router();

// Require Business model in our routes module
let Business = require('./business.model');

// Defined store route
businessRoutes.route('/add').post(function (req, res) {
  let business = new Business(req.body);
  business.save()
    .then(business => {
      res.status(200).json({'business': 'business in added successfully'});
    })
    .catch(err => {
    res.status(400).send("unable to save to database");
    });
});

// Defined get data(index or listing) route
businessRoutes.route('/').get(function (req, res) {
    Business.find(function(err, businesses){
    if(err){
      console.log(err);
    }
    else {
      res.json(businesses);
    }
  });
});

// Defined edit route
businessRoutes.route('/edit/:id').get(function (req, res) {
  let id = req.params.id;
  Business.findById(id, function (err, business){
      res.json(business);
  });
});

//  Defined update route
businessRoutes.route('/update/:id').post(function (req, res) {
    Business.findById(req.params.id, function(err, business) {
    if (!business)
      res.status(404).send("data is not found");
    else {
        business.person_name = req.body.person_name;
        business.business_name = req.body.business_name;
        business.business_gst_number = req.body.business_gst_number;

        business.save().then(business => {
          res.json('Update complete');
      })
      .catch(err => {
            res.status(400).send("unable to update the database");
      });
    }
  });
});

// Defined delete | remove | destroy route
businessRoutes.route('/delete/:id').get(function (req, res) {
    Business.findByIdAndRemove({_id: req.params.id}, function(err, business){
        if(err) res.json(err);
        else res.json('Successfully removed');
    });
});

module.exports = businessRoutes;

Here, we have defined the CRUD operations for MongoDB. So when the request hits the server, it maps the URI and according to URI, the above function will be executed, and database operation will be performed and send the response to the client.

Here, we have used a Mongoose ORM to save, update, delete the data from the database. Mongoose is an ORM used in MongoDB database. Now, we have all the CRUD operations set up on the route file; we need to import inside the server.js file.

So, our final server.js file looks like this.

// server.js

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');
const mongoose = require('mongoose');
const config = require('./DB.js');
const businessRoute = require('./business.route');

mongoose.Promise = global.Promise;
mongoose.connect(config.DB, { useNewUrlParser: true }).then(
  () => {console.log('Database is connected') },
  err => { console.log('Can not connect to the database'+ err)}
);

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.use('/business', businessRoute);

app.listen(PORT, function(){
  console.log('Server is running on Port:',PORT);
});

Save the file and see the terminal and check if we got any errors.

#9: Install Axios library and send a POST request.

Install the Axios library and send the POST request. If you want to learn about the Axios library, then check out my Getting Started With Axios Promise Based HTTP Client Tutorial Example article.

yarn add axios

# or

npm install axios --save

Now, send the HTTP POST request along with the form data to the node js server. We will send the data as an object because we have used the body-parser at the backend to pluck the data from the request and save it in the database.

Write the following code inside the create.component.js file.

// create.component.js

import React, { Component } from 'react';
import axios from 'axios';

export default class Create extends Component {
  constructor(props) {
    super(props);
    this.onChangePersonName = this.onChangePersonName.bind(this);
    this.onChangeBusinessName = this.onChangeBusinessName.bind(this);
    this.onChangeGstNumber = this.onChangeGstNumber.bind(this);
    this.onSubmit = this.onSubmit.bind(this);

    this.state = {
      person_name: '',
      business_name: '',
      business_gst_number:''
    }
  }
  onChangePersonName(e) {
    this.setState({
      person_name: e.target.value
    });
  }
  onChangeBusinessName(e) {
    this.setState({
      business_name: e.target.value
    })  
  }
  onChangeGstNumber(e) {
    this.setState({
      business_gst_number: e.target.value
    })
  }

  onSubmit(e) {
    e.preventDefault();
    const obj = {
      person_name: this.state.person_name,
      business_name: this.state.business_name,
      business_gst_number: this.state.business_gst_number
    };
    axios.post('http://localhost:4000/business/add', obj)
        .then(res => console.log(res.data));
    
    this.setState({
      person_name: '',
      business_name: '',
      business_gst_number: ''
    })
  }
 
  render() {
    return (
        <div style={{ marginTop: 10 }}>
            <h3>Add New Business</h3>
            <form onSubmit={this.onSubmit}>
                <div className="form-group">
                    <label>Person Name:  </label>
                    <input 
                      type="text" 
                      className="form-control" 
                      value={this.state.person_name}
                      onChange={this.onChangePersonName}
                      />
                </div>
                <div className="form-group">
                    <label>Business Name: </label>
                    <input type="text" 
                      className="form-control"
                      value={this.state.business_name}
                      onChange={this.onChangeBusinessName}
                      />
                </div>
                <div className="form-group">
                    <label>GST Number: </label>
                    <input type="text" 
                      className="form-control"
                      value={this.state.business_gst_number}
                      onChange={this.onChangeGstNumber}
                      />
                </div>
                <div className="form-group">
                    <input type="submit" value="Register Business" className="btn btn-primary"/>
                </div>
            </form>
        </div>
    )
  }
}

Now, submit the form with proper values and open your browser console panel and see the response.

 

React CRUD Project

Also, now check inside the mongodb database and see the values.

To see the values inside the database, we can start a mongoshell and look at the values in the database.

 

Mongo CRUD

So, we can see that our data is added successfully.

#10: Display the backend data

Write the following code inside the index.component.js file.

// index.component.js

import React, { Component } from 'react';
import axios from 'axios';
import TableRow from './TableRow';

export default class Index extends Component {

  constructor(props) {
      super(props);
      this.state = {business: []};
    }
    componentDidMount(){
      axios.get('http://localhost:4000/business')
        .then(response => {
          this.setState({ business: response.data });
        })
        .catch(function (error) {
          console.log(error);
        })
    }
    tabRow(){
      return this.state.business.map(function(object, i){
          return <TableRow obj={object} key={i} />;
      });
    }

    render() {
      return (
        <div>
          <h3 align="center">Business List</h3>
          <table className="table table-striped" style={{ marginTop: 20 }}>
            <thead>
              <tr>
                <th>Person</th>
                <th>Business</th>
                <th>GST Number</th>
                <th colSpan="2">Action</th>
              </tr>
            </thead>
            <tbody>
              { this.tabRow() }
            </tbody>
          </table>
        </div>
      );
    }
  }

So, here, we have sent the GET request to the node.js server and fetch that data from an API.

We have imported the TableRow.js component. So let us create that component. Inside the components folder, create one more component called TableRow.js and add the following code inside it.

// TableRow.js

import React, { Component } from 'react';

class TableRow extends Component {
  render() {
    return (
        <tr>
          <td>
            {this.props.obj.person_name}
          </td>
          <td>
            {this.props.obj.business_name}
          </td>
          <td>
            {this.props.obj.business_gst_number}
          </td>
          <td>
            <button className="btn btn-primary">Edit</button>
          </td>
          <td>
            <button className="btn btn-danger">Delete</button>
          </td>
        </tr>
    );
  }
}

export default TableRow;

This component is responsible for display the row data fetched from the backend.

Save the file and go to the browser and see this URL: http://localhost:3000/index.

 

React Node Example

#11: Edit and Update Functionality

First, add the Link to the TableRow.js file.

// TableRow.js

import { Link } from 'react-router-dom';

<Link to={"/edit/"+this.props.obj._id} className="btn btn-primary">Edit</Link>

Add the following code to the edit.component.js file.

// edit.component.js

import React, { Component } from 'react';
import axios from 'axios';

export default class Edit extends Component {
  constructor(props) {
    super(props);
    this.onChangePersonName = this.onChangePersonName.bind(this);
    this.onChangeBusinessName = this.onChangeBusinessName.bind(this);
    this.onChangeGstNumber = this.onChangeGstNumber.bind(this);
    this.onSubmit = this.onSubmit.bind(this);

    this.state = {
      person_name: '',
      business_name: '',
      business_gst_number:''
    }
  }

  componentDidMount() {
      axios.get('http://localhost:4000/business/edit/'+this.props.match.params.id)
          .then(response => {
              this.setState({ 
                person_name: response.data.person_name, 
                business_name: response.data.business_name,
                business_gst_number: response.data.business_gst_number });
          })
          .catch(function (error) {
              console.log(error);
          })
    }

  onChangePersonName(e) {
    this.setState({
      person_name: e.target.value
    });
  }
  onChangeBusinessName(e) {
    this.setState({
      business_name: e.target.value
    })  
  }
  onChangeGstNumber(e) {
    this.setState({
      business_gst_number: e.target.value
    })
  }

  onSubmit(e) {
    e.preventDefault();
    const obj = {
      person_name: this.state.person_name,
      business_name: this.state.business_name,
      business_gst_number: this.state.business_gst_number
    };
    axios.post('http://localhost:4000/business/update/'+this.props.match.params.id, obj)
        .then(res => console.log(res.data));
    
    this.props.history.push('/index');
  }
 
  render() {
    return (
        <div style={{ marginTop: 10 }}>
            <h3 align="center">Update Business</h3>
            <form onSubmit={this.onSubmit}>
                <div className="form-group">
                    <label>Person Name:  </label>
                    <input 
                      type="text" 
                      className="form-control" 
                      value={this.state.person_name}
                      onChange={this.onChangePersonName}
                      />
                </div>
                <div className="form-group">
                    <label>Business Name: </label>
                    <input type="text" 
                      className="form-control"
                      value={this.state.business_name}
                      onChange={this.onChangeBusinessName}
                      />
                </div>
                <div className="form-group">
                    <label>GST Number: </label>
                    <input type="text" 
                      className="form-control"
                      value={this.state.business_gst_number}
                      onChange={this.onChangeGstNumber}
                      />
                </div>
                <div className="form-group">
                    <input type="submit" 
                      value="Update Business" 
                      className="btn btn-primary"/>
                </div>
            </form>
        </div>
    )
  }
}

So, what we have done is, we have used the component lifecycle method to fetch the data from the API.

That data needs to be displayed inside the textbox because this is edit form. Next, it is the same thing as we have written the code in the create.component.js file.

Save the file and go to the edit page from the index or listing page. If the data is not displayed then please first check that you have the running node.js server on the backend.

 

React MongoDB Example

We have also written the code that will update the data because we have written the function that will send the request to the node.js server and update the data based on the ID.

#12: Delete the data

Now, the only thing remaining is to delete the data. So define the delete function inside TableRow.js file.

// TableRow.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';

class TableRow extends Component {

  constructor(props) {
        super(props);
        this.delete = this.delete.bind(this);
    }
    delete() {
        axios.get('http://localhost:4000/business/delete/'+this.props.obj._id)
            .then(console.log('Deleted'))
            .catch(err => console.log(err))
    }
  render() {
    return (
        <tr>
          <td>
            {this.props.obj.person_name}
          </td>
          <td>
            {this.props.obj.business_name}
          </td>
          <td>
            {this.props.obj.business_gst_number}
          </td>
          <td>
            <Link to={"/edit/"+this.props.obj._id} className="btn btn-primary">Edit</Link>
          </td>
          <td>
            <button onClick={this.delete} className="btn btn-danger">Delete</button>
          </td>
        </tr>
    );
  }
}

export default TableRow;

Now, we have completed React CRUD Example or MERN Stack Tutorial From Scratch.

I have put this code on Github. So you can check that code as well.

Finally, React CRUD Example Tutorial is over. Thanks for taking.

Github Code

The post React CRUD Example | MERN Stack Tutorial appeared first on AppDividend.

]]>
https://appdividend.com/2018/11/11/react-crud-example-mern-stack-tutorial/feed/ 38
React Context API Tutorial With Example https://appdividend.com/2018/11/03/react-context-api-tutorial-with-example/ https://appdividend.com/2018/11/03/react-context-api-tutorial-with-example/#respond Sat, 03 Nov 2018 21:22:50 +0000 http://localhost/wordpress/?p=2067 React Context API Example Tutorial

React Context API Tutorial With Example is today’s leading topic.  Context provides the way to pass data through the component tree without having to pass the props down manually at every level. In the typical React application, data is passed top-down (parent to child) via props, but this can be the cumbersome and not good idea for certain […]

The post React Context API Tutorial With Example appeared first on AppDividend.

]]>
React Context API Example Tutorial

React Context API Tutorial With Example is today’s leading topic.  Context provides the way to pass data through the component tree without having to pass the props down manually at every level. In the typical React application, data is passed top-down (parent to child) via props, but this can be the cumbersome and not good idea for certain types of props (e.g., locale preference, theme) that are required by many components within the application. The React team suggests sticking to props if you have just a few levels of children to pass because it’s still a much less complicated API than the Context API.

If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.

React Context API Tutorial With Example

Create a new React app using the following command.

npx create-react-app contextapi
cd contextapi
npm start

 

React Context API Tutorial With Example

When you start the react development server and find any error regarding webpack-dev-server then you will find a solution in the terminal, if it works for you then best otherwise you can go for the below solution.

Create one .env file in root and add the following code inside it.

SKIP_PREFLIGHT_CHECK=true

Install the bootstrap 4 css framework also by the following command.

yarn add bootstrap

# or

npm install bootstrap

You create the context using React.createContext() , which returns the Context object.

const {Provider, Consumer} = React.createContext()

Then you create the wrapper component that returns the Provider component, and you add as children all the elements from which you want to access the context. Let us take an example.

Write the following code inside src >> App.js file.

// App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';

const BtnColorContext = React.createContext('btn btn-dark');

class App extends Component {
  render() {
    return (
      <BtnColorContext.Provider value="btn btn-info">
        <Button />
      </BtnColorContext.Provider>
    );
  }
}

function Button(props) {
  return (
  <div className="container">
    <ThemedButton />    
  </div>
  );
}

class ThemedButton extends Component {
  
  static contextType = BtnColorContext;
  render() {
    return <button className={this.context} >
      hello
    </button>;
  }
}

export default App;

You can see in the webpage output that the color of the button is changed according to btn btn-info.

Explanation of React Context API

Context is designed to share the data that can be considered as a “global” for the tree of React components, such as a current authenticated user, theme, or preferred language settings. We have done the following things in the above example. Let us see one by one.

First, we create a button class context and assign the btn btn-dark. 

Then inside the App class, we have changed the value of the context to the btn btn-info.

Now, the inside the App component, the nested component is Button. It is a stateless component, means just a functional component, which receives the props as an argument.

Now, inside that component, we have one more nested component called ThemedButton. But we have not passed any property from Button component to ThemedButton.

So, now if we want to access the value of the button class, which we have defined in the React context, then we need to write the following code inside ThemedButton class.

class ThemedButton extends Component {
  
  static contextType = BtnColorContext;
  render() {
    return <button className={this.context} >
      hello
    </button>;
  }
}

So, we have defined the static contextType and use the current context value by this.context, and now we can see the latest context value, which is described in this code.

<BtnColorContext.Provider value="btn btn-info">
   <Button />
</BtnColorContext.Provider>

Now, if we write the above code like this then see the output on the result.

<div>
  <Button />
</div>

Save the file and see the button color. It will change to dark according to defined the react context. That means, if we modify the context in between parent to children flow then it will take the latest value otherwise it will take the first defined value.

React Context API

1. React.createContext

You can create the context using the following syntax.

const MyContext = React.createContext(defaultValue);

Creates a Context object. When React renders the component that subscribes to this Context object, it will read the current context value from a closest matching Provider above it in the tree. We have used this in our example to change the button class from dark to info.

The defaultValue argument is only used when the component does not have the matching Provider above it in the tree. It is very helpful for testing components in the isolation without wrapping them. Please Note here that passing undefined as a Provider value does not cause consuming components to use defaultValue.

2. Context.Provider

The syntax is following.

<MyContext.Provider value={/* some value */}>

Every Context object comes with the Provider React component that allows consuming components to subscribe to the context changes. Accepts the value prop to be passed to the consuming components that are the descendants of this Provider. One Provider can be connected to the many consumers. Providers can be nested to override the values deeper within a tree. As we have overridden the default value of the className and we get the latest value of the className in the component tree.

3. Context.Consumer

The syntax is following.

<MyContext.Consumer>
  {value => /* render something based on the context value */}
</MyContext.Consumer>

It is the React component that subscribes to the context changes. It lets us subscribe to the context within the function component. Requires the function as a child

The function receives a current context value and returns the React node. The value argument passed to a function will be equal to a value prop of the closest Provider for this context above in the tree. If there are no Providers for the context above, the value argument will be equal to the defaultValue that was passed to createContext().

Finally, React Context API Tutorial With Example is over.

The post React Context API Tutorial With Example appeared first on AppDividend.

]]>
https://appdividend.com/2018/11/03/react-context-api-tutorial-with-example/feed/ 0
React Dropdown Select Example Tutorial https://appdividend.com/2018/10/19/react-dropdown-select-example-tutorial/ https://appdividend.com/2018/10/19/react-dropdown-select-example-tutorial/#respond Fri, 19 Oct 2018 10:29:18 +0000 http://localhost/wordpress/?p=1948 React Multiple Dropdown Example

React Dropdown Select Example Tutorial is the today’s leading topic. We use the library called React-select that features dynamic search/filter, async option loading, accessibility, and fast render times. It has a flexible and beautiful Select Input control for ReactJS with multi-select, autocomplete and ajax support. It has the following features. Flexible approach to data, with customizable functions. Extensible styling […]

The post React Dropdown Select Example Tutorial appeared first on AppDividend.

]]>
React Multiple Dropdown Example

React Dropdown Select Example Tutorial is the today’s leading topic. We use the library called React-select that features dynamic search/filter, async option loading, accessibility, and fast render times. It has a flexible and beautiful Select Input control for ReactJS with multi-select, autocomplete and ajax support.

It has the following features.

  • Flexible approach to data, with customizable functions.
  • Extensible styling API with emotion.
  • Component Injection API for complete control over the UI behavior.
  • Controllable state props and modular architecture.
  • Long-requested features like option groups, portal support, animation, and more.
If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.

React Dropdown Select Example Tutorial

First, we install the React.js and then install the react-select library.

#1: Install React and other libraries

Type the following command.

npx create-react-app reaselect

 

React Dropdown Select Example Tutorial

Now, go inside the project folder.

Earn a Tech Degree and get the skills like Frontend Development or Javascript Development that can help you to launch a career. Start your free trial
cd reaselect

To install React-Select v2, add the react-select package using the following command.

yarn add react-select

# or

npm install react-select --save

Also, we can install the Bootstrap 4 using the following command.

yarn add bootstrap

# or

npm install bootstrap --save

#2: Import the react-select module.

Inside the src >> App.js file, add the following code.

// App.js

import React from 'react';
import Select from 'react-select';
import 'bootstrap/dist/css/bootstrap.min.css';

const techCompanies = [
  { label: "Apple", value: 1 },
  { label: "Facebook", value: 2 },
  { label: "Netflix", value: 3 },
  { label: "Tesla", value: 4 },
  { label: "Amazon", value: 5 },
  { label: "Alphabet", value: 6 },
];

const App = () => (
  <div className="container">
    <div className="row">
      <div className="col-md-4"></div>
      <div className="col-md-4">
        <Select options={ techCompanies } />
      </div>
      <div className="col-md-4"></div>
    </div>
  </div>
);

export default App

 

React Select Dropdown example

Here, we have imported the bootstrap 4 and react-select library.

Then, we have created an Array that contains the data that needs to be displayed on the drop down.

After that, we have used the Select element and pass the options object. There are many other properties available which are the following.

  • autofocus – focus the control when it mounts.
  • className – apply a className to the control.
  • classNamePrefix – apply classNames to inner elements with the given prefix.
  • isDisabled – disable the control.
  • isMulti – allow the user to select multiple values.
  • isSearchable – allow the user to search for matching options.
  • name – generate an HTML input with this name, containing the current value.
  • onChange – subscribe to change events.
  • options – specify the options the user can select from.
  • placeholder – change the text displayed when no option is selected.
  • value – control the current value.

You must import the Select component from react-select.

Each object in the options array techCompanies must have at least two values: label, a string, and value, which may be any type.

The only required prop is the options array.

#Other Features

We can use the multiple select using the following property. We need to add that property.

<Select options={ techCompanies } 
          isMulti />

 

React Multi Select Example

Controllable Props

You can control the following props by providing values for them. If you don’t, react-select will manage them for you.

  • value / onChange – specify the current value of the control.
  • menuIsOpen / onMenuOpen / onMenuClose – control whether the menu is open.
  • inputValue / onInputChange – control the value of the search input (changing this will update the available options).

If you don’t provide these props, you can set the initial value of the state they control:

  • defaultValue – set the initial value of the control.
  • defaultMenuIsOpen – set the initial open value of the menu.
  • defaultInputValue – set the initial value of the search input.

Methods

React-select exposes two public methods:

  • focus() – focus the control programmatically.
  • blur() – blur the control programmatically.

Finally, React Dropdown Select Example Tutorial is over.

The post React Dropdown Select Example Tutorial appeared first on AppDividend.

]]>
https://appdividend.com/2018/10/19/react-dropdown-select-example-tutorial/feed/ 0
Redux Thunk Tutorial With Example From Scratch https://appdividend.com/2018/10/03/redux-thunk-tutorial-example/ https://appdividend.com/2018/10/03/redux-thunk-tutorial-example/#comments Wed, 03 Oct 2018 20:04:29 +0000 http://localhost/wordpress/?p=1826 Getting Started With redux-thunk

In this example, we will see Redux Thunk Tutorial With Example From Scratch. Redux is a predictable container state management system. It’s a lightweight implementation of Flux, which is another library for managing the state. Redux allows us to put a middleware that sits between an action being dispatched and the action that reaching to the reducers. Two very […]

The post Redux Thunk Tutorial With Example From Scratch appeared first on AppDividend.

]]>
Getting Started With redux-thunk

In this example, we will see Redux Thunk Tutorial With Example From Scratch. Redux is a predictable container state management system. It’s a lightweight implementation of Flux, which is another library for managing the state. Redux allows us to put a middleware that sits between an action being dispatched and the action that reaching to the reducers. Two very popular middleware libraries that will allow for side effects and asynchronous activities are Redux Thunk and Redux Saga. Redux Thunk is the middleware that lets you call the action creators that return a function instead of the action object. That function then receives the store’s dispatch method, which is then used to dispatch the regular synchronous actions inside a body of the function once the asynchronous operations have completed.  The thunk is a concept in programming where a function is used to delay the evaluation/calculation of an operation.

If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.
Earn a Tech Degree and get the skills like Frontend Development or Javascript Development that can help you to launch a career. Join the program

Redux Thunk Tutorial With Example From Scratch

Let us install React.js using the following command.

#1: Install React.js

npx create-react-app reactreduxthunk

 

Redux Thunk Tutorial With Example From Scratch

#2: Install Redux, react-redux, and redux-thunk.

Go inside the folder and type the following command to install the axiosreact-redux, redux, and redux-thunk library.

npm install axios redux react-redux redux-thunk --save

# or

yarn add axios redux react-redux redux-thunk

#3: Create the action.

Now, we will fetch the data from Github API, and for that, we need to use Axios: promise based library to send the network request to a Github API server and fetch the data.

Now, the network request is the best example of an Asynchronous call. The redux-thunk middleware is useful to fetch the data from an API.

Inside the src folder, create three more folders, and their names are following.

  1. actions
  2. reducers
  3. containers

Now, first inside the actions folder, create one file called types.js and write the following code inside it.

// types.js

export const FETCH_GITHUB_DATA = 'FETCH_GITHUB_DATA';

When the page loads, we initiate the FETCH_GITHUB_DATA action and fetch all the data from the server and save it inside the Redux store. 

Now, that action returns the object that contains two properties.

  1. Action type
  2. Payload

As we know for our demo, we have two actions, so create one file inside src >> actions folder called index.js.

Add the following code inside the index.js.

// index.js

import { FETCH_GITHUB_DATA } from './types';
import axios from 'axios';

const apiUrl = 'https://api.github.com/users/KrunalLathiya';

export const fetchData = (data) => {
  return {
    type: FETCH_GITHUB_DATA,
    data
  }
};

export const fetchGithubData = () => {
  return (dispatch) => {
    return axios.get(apiUrl)
      .then(response => {
        dispatch(fetchData(response.data))
      })
      .catch(error => {
        throw(error);
      });
  };
};

So, here we have defined an action that calls the Github API and gets a response from the server. Remember, the reducer is a pure function, and we do not want any asynchronous call inside reducer, all the asynchronous actions are called here inside actions.

#4: Create the rootReducer and postReducer.

Now, inside the reducers folder, create one file called githubReducer.js.

Write the following code inside the githubReducer.js.

// githubReducer.js

import { FETCH_GITHUB_DATA } from '../actions/types';

export default function githubReducer(state = [], action) {
  switch (action.type) {
      case FETCH_GITHUB_DATA:
      return action.data;
    default:
      return state;
  }
}

This githubReducer.js file contains pure functions and does not relate to any backend service. Reducers must be pure functions.

So, if the action type is matched with the fired action, then it will modify the store and change the current state and give that mutated state.

Now, create an index.js file inside reducers folderWrite the following code inside it.

// index.js

import { combineReducers } from 'redux';
import data from './githubReducer';

export default combineReducers({
    data: data
});

#5: Configure the redux Store

Import the src >> reducers >> index.js reducer file inside src >> index.js file, which is already there. So, our final src >> index.js file looks like below.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';

import App from './App';
import rootReducer from './reducers';
import { fetchGithubData } from './actions/index';

const store = createStore(rootReducer, applyMiddleware(thunk));

store.dispatch(fetchGithubData());

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, document.getElementById('root'));

Here, we have created the redux store. Also, imported the createStore, applyMiddleware, thunk.

Since we are dealing with Asynchronous data, we have to use the thunk to save the data inside the redux store, and then the redux store will update the state and update the React.js User Interface.

First, we have created the redux store and then apply redux-thunk middleware to the store. This middleware helps us to help with Async action inside the store.

After creating the store, we have dispatched the action that fetches all the data from the GitHub server and put it inside the Redux store. So, when our react app loads for the first time, we get the data.

#6: Display the data.

Now, inside the containers folder, create one container component called GithubData.jsf and write the following code.

// GithubData.js

import React from 'react';
import { connect } from 'react-redux';

function GithubData({ data }) {
  if(!data) {
    return (
      <div>
        No Data
      </div>
    )
  }
  return (
    <div>
      <div>
        Name: { data.name }
      </div>
      <br />
      <div>
        Blog: { data.blog }
      </div>
      <br />
      <div>
        Github Followers: { data.followers }
      </div>
    </div>
  );
}

const mapStateToProps = state => {
  return {
    data: state.data
  };
};

export default connect(
  mapStateToProps,
  null
)(GithubData);

So, here we have mapped the state data to properties of this component.

Save this file and go to the terminal and start the react dev server.

npm start

 

Redux thunk example

Head over to the browser and see the following output.

thunk example in redux

 

Finally, Redux Thunk Tutorial With Example From Scratch is over.

The post Redux Thunk Tutorial With Example From Scratch appeared first on AppDividend.

]]>
https://appdividend.com/2018/10/03/redux-thunk-tutorial-example/feed/ 1
How To Save Multiple Checkboxes Values in React js https://appdividend.com/2018/09/25/how-to-save-multiple-checkboxes-values-in-react-js/ https://appdividend.com/2018/09/25/how-to-save-multiple-checkboxes-values-in-react-js/#respond Tue, 25 Sep 2018 21:20:04 +0000 http://localhost/wordpress/?p=1781 React js multiple checkbox example

In this tutorial, we will see How To Save Multiple Checkboxes Values in React js. If you are building a web application, then there are lots of form controls we need to create an interactive user form. The checkbox is one of the most used form control in a web application. We will take three checkboxes and […]

The post How To Save Multiple Checkboxes Values in React js appeared first on AppDividend.

]]>
React js multiple checkbox example

In this tutorial, we will see How To Save Multiple Checkboxes Values in React js. If you are building a web application, then there are lots of form controls we need to create an interactive user form. The checkbox is one of the most used form control in a web application. We will take three checkboxes and user can check multiple boxes and save its values inside MongoDB database. As we know, form control values are always controlled by React.js state. So when the user submits the form, we need only to send the values of checkboxes whose values are valid or whose checkbox values are checked. We save the values as a String in a MongoDB database. We use Node.js as a platform. There are many ways you can save multiple checkbox values in React js inside the MongoDB database.

If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.
Earn a Tech Degree and get the skills like Frontend Development or Javascript Development that can help you to launch a career. Join the program

How To Save Multiple Checkboxes Values in React

First of all, let us install React.js using the following command.

#1: Install React.js

npx create-react-app checkbox

Now, go inside the folder, and we need to install the bootstrap and axios libraries.

yarn add bootstrap axios

# or

npm install bootstrap axios --save

Next step is to import the bootstrap css file inside src >> App.js file.

// App.js

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

#2: Create Form inside an App.js.

For this example, I am merely taking the checkboxes and not other input types. So I am making three textboxes. So, first, we need to define the three initial state values.

// App.js

import React, { Component } from 'react';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

class App extends Component {

  state = {
    isMJ: false,
    isJB: false,
    isDrake: false
  };

  toggleChangeMJ = () => {
    this.setState(prevState => ({
      isMJ: !prevState.isMJ,
    }));
  }

  toggleChangeJB = () => {
    this.setState(prevState => ({
      isJB: !prevState.isJB,
    }));
  }

  toggleChangeDrake = () => {
    this.setState(prevState => ({
      isDrake: !prevState.isDrake,
    }));
  }

  onSubmit = (e) => {
    e.preventDefault();
    console.log(this.state);
  }

  render() {
    return (
      <div className="container">
        <h2>Save the multiple checkbox values in React js</h2>
        <hr />
        <form onSubmit = {this.onSubmit}>
          <div className="form-check">
            <label className="form-check-label">
              <input type="checkbox"
                checked={this.state.isMJ}
                onChange={this.toggleChangeMJ}
                className="form-check-input"
              />
              MJ
            </label>
          </div>
          <div className="form-check">
            <label className="form-check-label">
              <input type="checkbox"
                checked={this.state.isJB}
                onChange={this.toggleChangeJB}
                className="form-check-input"
              />
              JB
            </label>
          </div>
          <div className="form-check">
            <label className="form-check-label">
              <input type="checkbox"
                checked={this.state.isDrake}
                onChange={this.toggleChangeDrake}
                className="form-check-input"
              />
              Drake
            </label>
          </div>
          <div className="form-group">
            <button className="btn btn-primary">
              Submit
            </button>
          </div>
        </form>
      </div>
    );
  }
}

export default App;

We have defined the three initial states. Each state is for one checkbox. 

We also need to handle the change event. So when the user either check the checkbox or uncheck the checkbox, the state will be changed. So when the user submits the form, we get all the three state, and if any of the checkboxes are checked, then we send it to the server and save the data in the MongoDB database.

#3: Convert checked values into String.

We will save the string into the database. The String is comma separated values. So, we filter the state, and if any of the checkbox value is right or true, we add into an array and then finally change that array into the string and send that data to the Node.js server.

So, write the following code inside onSubmit() function.

// App.js

onSubmit = (e) => {
    e.preventDefault();
    let arr = [];
    for (var key in this.state) {
      if(this.state[key] === true) {
        arr.push(key);
      }
    }
    let data = {
      check: arr.toString() 
    };
}

So, here as I have explained, the first loop through the states and if the value is true, we push into the new array and finally cast that array into the String.

#4: Use Axios to send a POST request.

Import the axios module and send the POST request to the node server. So our final App.js file looks like below.

// App.js

import React, { Component } from 'react';
import axios from 'axios';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

class App extends Component {

  state = {
    isMJ: false,
    isJB: false,
    isDrake: false
  };

  toggleChangeMJ = () => {
    this.setState(prevState => ({
      isMJ: !prevState.isMJ,
    }));
  }

  toggleChangeJB = () => {
    this.setState(prevState => ({
      isJB: !prevState.isJB,
    }));
  }

  toggleChangeDrake = () => {
    this.setState(prevState => ({
      isDrake: !prevState.isDrake,
    }));
  }

  onSubmit = (e) => {
    e.preventDefault();
    let arr = [];
    for (var key in this.state) {
      if(this.state[key] === true) {
        arr.push(key);
      }
    }
    let data = {
      check: arr.toString() 
    };
    axios.post('http://localhost:4000/checks/add', data)
          .then(res => console.log(res.data));
  }

  render() {
    return (
      <div className="container">
        <h2>Save the multiple checkbox values in React js</h2>
        <hr />
        <form onSubmit = {this.onSubmit}>
          <div className="form-check">
            <label className="form-check-label">
              <input type="checkbox"
                checked={this.state.isMJ}
                onChange={this.toggleChangeMJ}
                className="form-check-input"
              />
              MJ
            </label>
          </div>
          <div className="form-check">
            <label className="form-check-label">
              <input type="checkbox"
                checked={this.state.isJB}
                onChange={this.toggleChangeJB}
                className="form-check-input"
              />
              JB
            </label>
          </div>
          <div className="form-check">
            <label className="form-check-label">
              <input type="checkbox"
                checked={this.state.isDrake}
                onChange={this.toggleChangeDrake}
                className="form-check-input"
              />
              Drake
            </label>
          </div>
          <div className="form-group">
            <button className="btn btn-primary">
              Submit
            </button>
          </div>
        </form>
      </div>
    );
  }
}

export default App;

#5: Create a Node.js backend.

First, start the mongodb server using the following command.

mongodb

Now, create one folder inside the root of the checkbox – our react project folder called backend and go inside that folder and initialize the package.json file.

npm init -y

Now, install the following dependencies for node project.

yarn add express body-parser mongoose cors

# or

npm install express body-parser mongoose cors --save

Now, create a database connection using the following command.

// DB.js

module.exports = {
  DB: 'mongodb://localhost:27017/checks'
};

Now, create the routes and models folders inside the backend folder.

Inside the models folder, create one file CheckModel.js add the following code.

// CheckModel.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

let CheckModel = new Schema({
  check: {
    type: String
  },
},{
    collection: 'checks'
});

module.exports = mongoose.model('CheckModel', CheckModel);

Also, you need to create the check.route.js file. Add the following code inside that file.

// CheckRoute.js

const checkRoute = require('express').Router(),
  CheckModel = require('../models/CheckModel');

  checkRoute.route('/add').post(function (req, res) {
    let checkmodel = new CheckModel(req.body);
    checkmodel.save()
      .then(Checkvalue => {
        res.status(200).json({'Checkvalue': 'Checkbox values have added successfully'});
      })
      .catch(err => {
        res.status(400).send("unable to save to database");
      });
  });

module.exports = checkRoute;

Finally, our server.js file looks like this.

// server.js

const app = require('express')(),
  bodyParser = require('body-parser'),
  cors = require('cors'),
  mongoose = require('mongoose')
  config = require('./DB'),
  checkRoute = require('./routes/check.route');

  mongoose.Promise = global.Promise;
  mongoose.connect(config.DB, { useNewUrlParser: true }).then(
    () => {console.log('Database is connected') },
    err => { console.log('Can not connect to the database'+ err)}
  );

  const PORT = process.env.PORT || 4000;

  app.use(bodyParser.json());
  app.use(cors());

  app.use('/checks', checkRoute);

  app.listen(PORT, () => {
    console.log('Listening on port ' + PORT);
  });

Open the terminal inside the backend folder and hit the following command.

node server

So, now you have three servers are running.

  1. React Development Server
  2. Node server
  3. MongoDB server

Go to the browser and navigate to this URL: http://localhost:3000/

You can see this page.

How To Save Multiple Checkboxes Values in React js

 

Now, check the multiple boxes and submit the form. If everything goes correct, then you can see the response on your console.

Save multiple checkbox values in React

 

I have inserted multiple documents and you can see that inside the following image in the MongoDB database.

 

Multiple checkbox in React

Finally, our How To Save Multiple Checkboxes Values in React js Tutorial Example is over. Thanks for taking.

The post How To Save Multiple Checkboxes Values in React js appeared first on AppDividend.

]]>
https://appdividend.com/2018/09/25/how-to-save-multiple-checkboxes-values-in-react-js/feed/ 0
React Datepicker Tutorial Example From Scratch https://appdividend.com/2018/09/24/react-datepicker-tutorial-example-from-scratch/ https://appdividend.com/2018/09/24/react-datepicker-tutorial-example-from-scratch/#comments Mon, 24 Sep 2018 09:33:51 +0000 http://localhost/wordpress/?p=1750 React Datepicker Demo Tutorial

React Datepicker Tutorial Example From Scratch is today’s leading topic.  We use the package called react-datepicker for this demo. React Date Picker is a  simple and reusable Datepicker component. There are many other packages available, but for this demo, we are using React Date Picker package for this example. If you want to learn more about React and Redux then check […]

The post React Datepicker Tutorial Example From Scratch appeared first on AppDividend.

]]>
React Datepicker Demo Tutorial

React Datepicker Tutorial Example From Scratch is today’s leading topic.  We use the package called react-datepicker for this demo. React Date Picker is a  simple and reusable Datepicker component. There are many other packages available, but for this demo, we are using React Date Picker package for this example.

If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.
Earn a Tech Degree and get the skills like Frontend Development or Javascript Development that can help you to launch a career. Join the program

React Datepicker Tutorial Example

Install React.js using the following command.

#1: Install React.js

Type the following command.

npx create-react-app reactdates
cd reactdates
npm start

 

React Datepicker Tutorial Example

#2: Install React Date Picker

Install react-datepicker using the following command.

npm install react-datepicker --save

# or

yarn add react-datepicker

We also need to install Moment.js separately since the dependency isn’t included in the package. Below is a simple example of how to use the Datepicker in a React view. You will also need to require the CSS file from this package.

npm install moment --save

# or

yarn add moment

Also, install the bootstrap using the following command.

npm install bootstrap --save

# or

yarn add bootstrap

Okay, now we have installed all the frontend libraries. Next step is to set up the frontend.

#3: Add Datepicker to the form

Inside src >> App.js file, replace the following code inside the App.js file.

// App.js

import React, { Component } from 'react';
import DatePicker from 'react-datepicker';
import moment from 'moment';
 
import 'react-datepicker/dist/react-datepicker.css';
import 'bootstrap/dist/css/bootstrap.min.css';

class App extends Component {

  constructor (props) {
    super(props)
    this.state = {
      startDate: moment()
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(date) {
    this.setState({
      startDate: date
    })
  }

  handleSubmit(e) {
    e.preventDefault();
    let main = this.state.startDate
    console.log(main.format('L'));
  }

  render() {
    return (
      <div className = "container">
        <h3>React Datepicker Example</h3>
        <form onSubmit={ this.handleSubmit }>
          <div className="form-group">
            <label>Select Date: </label>
            <DatePicker
              selected={ this.state.startDate }
              onChange={ this.handleChange }
              name="startDate"
              dateFormat="MM/DD/YYYY"
            />
          </div>
          <div className="form-group">
            <button className="btn btn-success">Add Date</button>
          </div>
        </form>
      </div>
    );
  }
}

export default App;

#Explanation

Here, we have imported datpicker, moment, bootstrap libraries.

We have set the initial date to today’s date.

When the user changes the date, it will set the new state with its new values. 

When the user submits the date, we get the value of the textbox, which is the object of Moment so that we can call the moment function like formate on the value of the textbox. We can format the date in whatever way we want.

Now, <Datepicker /> component has many options that we can configure it.

The most basic use of the DatePicker can be described with:

<DatePicker selected={this.state.date} onChange={this.handleChange} />

You can use onSelect event handler which fires each time some calendar date has been selected.

<DatePicker selected={this.state.date}
  onSelect={this.handleSelect} //when day is clicked
  onChange={this.handleChange} //only when value has changed
/>

onClickOutside Handler may be useful to close datepicker in inline mode.

#Time picker

You can also include a time picker by adding the showTimeSelect prop.

<DatePicker
  selected={this.state.date}
  onChange={this.handleChange}
  showTimeSelect
  dateFormat="LLL" />

#4: Create the Node.js backend

Inside the root folder of reactdates, create one more folder called backend.

Go inside the folder and open the terminal and initialize the package.json file using the following command.

npm init -y

Now, install the following dependencies.

yarn add express body-parser mongoose cors

# or

npm install express body-parser mongoose --save

Also, install the nodemon as a development dependency.

npm install nodemon --save-dev

Now, create one file called the server.js and add the following code.

// server.js

const app = require('express')(),
  bodyParser = require('body-parser'),
  cors = require('cors'),
  mongoose = require('mongoose');

  const PORT = process.env.PORT || 4000;

  app.listen(PORT, () => {
    console.log('Listening on port ' + PORT);
  });

The next thing is to connect MongoDB database with our node.js application.

If you have not installed the MongoDB database then install it and then start the mongodb server.

Type the following command to start the MongoDB server.

mongod

React date example tutorial

So, Now, we need to connect our node.js application to the mongodb database.

Create one file called DB.js inside backend folder.

// DB.js

module.exports = {
  DB: 'mongodb://localhost:27017/reactdates'
};

Import this DB.js file inside our server.js file and use mongoose library to set up the database connection with MongoDB. We can also use Mongoose to save the data in the database using Mongoose ORM.

Write the following code inside the server.js file to connect our MongoDB application to the Node.js server.

// server.js

const app = require('express')(),
  bodyParser = require('body-parser'),
  cors = require('cors'),
  mongoose = require('mongoose')
  config = require('./DB');

  mongoose.Promise = global.Promise;
  mongoose.connect(config.DB, { useNewUrlParser: true }).then(
    () => {console.log('Database is connected') },
    err => { console.log('Can not connect to the database'+ err)}
  );

  const PORT = process.env.PORT || 4000;

  app.use(bodyParser.json());
  app.use(cors());

  app.listen(PORT, () => {
    console.log('Listening on port ' + PORT);
  });

Save a file and go to a terminal and start the node.js server using the following command. Make sure you are inside backend folder root and not in reactdates folder root.

nodemon server

 

MongoDB Date Tutorial

Now, We have the total of three servers are running.

  1. React Development Server.
  2. Node.js Server.
  3. Mongodb Server.

#5: Create a model and Express routes.

Now, we need to create two folders inside the backend folder called routes and models.

In the models’ folder, create one model called DateModel.js.

// DateModel.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

let DateModel = new Schema({
  sDate: {
    type: Date
  },
},{
    collection: 'dates'
});

module.exports = mongoose.model('DateModel', DateModel);

Here, we will store only one field called sDate, and its datatype is Date.

In the routes folder, create one file called date.route.js. Add the following code inside the date.route.js file.

// date.route.js

const dateRoute = require('express').Router(),
      DateModel = require('../models/DateModel');

dateRoute.route('/add').post(function (req, res) {
  let datemodel = new DateModel(req.body);
  datemodel.save()
    .then(dateSaved => {
    res.status(200).json({'dateSaved': 'Date in added successfully'});
    })
    .catch(err => {
    res.status(400).send("unable to save to database");
    });
});

module.exports = dateRoute;

Now, our backend work is done. When the POST request hits the route: /dates/add, it will save the values inside the mongodb database.

Our final server.js file looks like this.

// server.js
const app = require('express')(),
  bodyParser = require('body-parser'),
  cors = require('cors'),
  mongoose = require('mongoose')
  config = require('./DB'),
  dateRoute = require('./routes/date.route');

  mongoose.Promise = global.Promise;
  mongoose.connect(config.DB, { useNewUrlParser: true }).then(
    () => {console.log('Database is connected') },
    err => { console.log('Can not connect to the database'+ err)}
  );

  const PORT = process.env.PORT || 4000;

  app.use(bodyParser.json());
  app.use(cors());

  app.use('/dates', dateRoute);

  app.listen(PORT, () => {
    console.log('Listening on port ' + PORT);
  });

#6: Install Axios and send POST request.

Type the following command to install Axios library using the following command, and We need to install it on the frontend, so please open the terminal inside reactdates project root.

yarn add axios

# or

npm install axios --save

Okay, now import the axios inside App.js file and send the data to the Node.js server. Write the final code inside the App.js file.

// server.js

import React, { Component } from 'react';
import DatePicker from 'react-datepicker';
import moment from 'moment';
import axios from 'axios';
 
import 'react-datepicker/dist/react-datepicker.css';
import 'bootstrap/dist/css/bootstrap.min.css';

class App extends Component {

  constructor (props) {
    super(props)
    this.state = {
      startDate: moment()
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(date) {
    this.setState({
      startDate: date
    })
  }

  handleSubmit(e) {
    e.preventDefault();
    let mainDate = this.state.startDate;
    const dateObj = {
      sDate: mainDate.format('L')
    }
    axios.post('http://localhost:4000/dates/add', dateObj)
        .then(res => console.log(res.data));
  }

  render() {
    return (
      <div className = "container">
        <h3>React Datepicker Example</h3>
        <form onSubmit={ this.handleSubmit }>
          <div className="form-group">
            <label>Select Date: </label>
            <DatePicker
              selected={ this.state.startDate }
              onChange={ this.handleChange }
              name="startDate"
              dateFormat="MM/DD/YYYY"
            />
          </div>
          <div className="form-group">
            <button className="btn btn-success">Add Date</button>
          </div>
        </form>
      </div>
    );
  }
}

export default App;

Save the file and go to the browser, select the data and submit the form and you can see in the console that, our date is successfully saved inside MongoDB database.

 

React Datepicker Tutorial

I have submitted four dates. So in the MongoDB database, there are four entries.

 

Mongoose Date Example Tutorial

Finally, React Datepicker Tutorial Example From Scratch is over. I have put the code on Github. Please check it out as well.

Github Code

The post React Datepicker Tutorial Example From Scratch appeared first on AppDividend.

]]>
https://appdividend.com/2018/09/24/react-datepicker-tutorial-example-from-scratch/feed/ 1
How To Create Sidebar Component In React https://appdividend.com/2018/08/29/how-to-create-sidebar-component-in-react/ https://appdividend.com/2018/08/29/how-to-create-sidebar-component-in-react/#comments Wed, 29 Aug 2018 12:28:06 +0000 http://localhost/wordpress/?p=1577 Create Sidebar Component In React

In this example, we will see How To Create Sidebar Component In React. We use the library called react-burger-menu. This library will help us to build a sidebar menu component in React.js. We are not using Redux so we will build with plain React.js. If you want to learn more about React and Redux then check out this React […]

The post How To Create Sidebar Component In React appeared first on AppDividend.

]]>
Create Sidebar Component In React

In this example, we will see How To Create Sidebar Component In React. We use the library called react-burger-menuThis library will help us to build a sidebar menu component in React.js. We are not using Redux so we will build with plain React.js.

If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.

# Create Sidebar Component In React

First, we install the React.js and then install the third-party GitHub library called react-burger-menu.

#1: Install React.js

Type the following command to install React.js.

npx create-react-app sidebar

Go inside the folder and open it in VSCode editor.

cd sidebar
code .

Now, install the react-burger-menu library using the following command.

npm install react-burger-menu --save

# or

yarn add react-burger-menu

#2: Create a Sidebar Menu

Inside the src folder, create one file called sidebar.js. In this sidebar component, we can add the list item that can display inside that sidebar. Here, we will make use of react-burger-menu as well.

So, write the following code inside the sidebar.js file.

// sidebar.js

import React from 'react';
import { slide as Menu } from 'react-burger-menu';

export default props => {
  return (
    <Menu>
      <a className="menu-item" href="/">
        Home
      </a>

      <a className="menu-item" href="/laravel">
        Laravel
      </a>

      <a className="menu-item" href="/angular">
        Angular
      </a>

      <a className="menu-item" href="/react">
        React
      </a>

      <a className="menu-item" href="/vue">
        Vue
      </a>

      <a className="menu-item" href="/node">
        Node
      </a>
    </Menu>
  );
};

So, here we have imported the slide component from the react-burger-menu. 

#3: Import the sidebar.js file inside an App.js file.

Write the following code inside an App.js file.

// App.js

import React from 'react';
import SideBar from './sidebar';

import './App.css';

export default function App() {
  return (
    <div id="App">
      <SideBar />
      <div id="page-wrap">
        <h1>AppDividend</h1>
        <h2>Check out our tutorials the side menubar</h2>
      </div>
    </div>
  );
}

Now, finally add the css code inside App.css file.

html,
body {
  margin: 0;
}

#App {
  font-family: sans-serif;
  height: 100vh;
}

#page-wrap {
  text-align: center;
  overflow: auto;
}

.bm-item {
  display: inline-block;
  text-decoration: none;
  margin-bottom: 10px;
  color: #d1d1d1;
  transition: color 0.2s;
}

.bm-item:hover {
  color: white;
}

.bm-burger-button {
  position: fixed;
  width: 36px;
  height: 30px;
  left: 36px;
  top: 36px;
}

.bm-burger-bars {
  background: #373a47;
}

.bm-cross-button {
  height: 24px;
  width: 24px;
}

.bm-cross {
  background: #bdc3c7;
}

.bm-menu {
  background: #373a47;
  padding: 2.5em 1.5em 0;
  font-size: 1.15em;
}

.bm-morph-shape {
  fill: #373a47;
}

.bm-item-list {
  color: #b8b7ad;
}

.bm-overlay {
  background: rgba(0, 0, 0, 0.3);
}

After saving the file, go to the terminal and start the React development server.

npm start

 

How To Create Sidebar Component In React

So at this URL: http://localhost:3000/. You can see that our React.js project is up and running.

To try out our different animations, merely change the imported slide at the top of our sidebar.js file to any of the other animation, such as bubble. To use a different animation you can substitute slide with any of the following.

1. slide
2. stack
3. elastic
4. bubble
5. push
6. pushRotate
7. scaleDown
8. scaleRotate
9. fallDown
10. reveal

Properties

Some animations require certain other elements to be on your page.

Page Wrapper

An element wrapping the rest of the content on your page.

<Menu pageWrapId={ "page-wrap" } />
<main id="page-wrap">
  .
  .
  .
</main>

Outer container

An element containing everything, including the menu component.

<div id="outer-container">
  <Menu pageWrapId={ "page-wrap" } outerContainerId={ "outer-container" } />
  <main id="page-wrap">
    .
    .
    .
  </main>
</div>

Finally, How To Create Sidebar Component In React Tutorial Example is over. Thanks for taking.

The post How To Create Sidebar Component In React appeared first on AppDividend.

]]>
https://appdividend.com/2018/08/29/how-to-create-sidebar-component-in-react/feed/ 2
React Autocomplete Example Tutorial https://appdividend.com/2018/08/23/react-autocomplete-example-tutorial/ https://appdividend.com/2018/08/23/react-autocomplete-example-tutorial/#comments Thu, 23 Aug 2018 13:04:15 +0000 http://localhost/wordpress/?p=1536 How to create Autocomplete Component in React

React Autocomplete Example Tutorial is today’s main topic.  In the modern web development, improving the user experience, and with React is easy. The concept of autocomplete is straightforward. It is a list of suggestions based on a user’s input. A user can then hit enter to complete the word of phrase. It saves the user’s time, and that […]

The post React Autocomplete Example Tutorial appeared first on AppDividend.

]]>
How to create Autocomplete Component in React

React Autocomplete Example Tutorial is today’s main topic.  In the modern web development, improving the user experience, and with React is easy. The concept of autocomplete is straightforward. It is a list of suggestions based on a user’s input. A user can then hit enter to complete the word of phrase. It saves the user’s time, and that tends to make users very happy. Autocomplete can be implemented in any number of ways regarding how the suggestions are filtered and presented to the user, and in this article, we are going to use a fixed list of recommendations passed to our component. As the user types, we will filter the results and only show the suggestions that contain the user’s input anywhere in the suggestion.

If you want to learn more about React.js then checkout this  React 16 – The Complete Guide (incl. React Router 4 & Redux) Guide. It has a very brief intro about React and Redux.
React 16 – The Complete Guide (incl. React Router 4 & Redux)

React Autocomplete Example Tutorial

We use the library for this tutorial called react-autocompleteBut first, let us install the React.js using the following command.

#1: Install React.js.

Type the following command.

npx create-react-app my-app
cd my-app
npm start

 

React Autocomplete Example Tutorial

Now, install the react-autocomplete library using the following command.

npm install --save react-autocomplete

#2: Create the static data.

Inside the src folder, create one file called data.js and add the following function that returns the static data.

// data.js

export function getStocks() {
  return [
    { abbr: 'ADANIPORTS', name: 'Adani Ports & Special Economic Zone Ltd.' },
    { abbr: 'ASIANPAINT', name: 'Asian Paints Ltd.' },
    { abbr: 'AXISBANK', name: 'Axis Bank Ltd.' },
    { abbr: 'BAJAJ-AUTO', name: 'Bajaj Auto Ltd.' },
    { abbr: 'BAJFINANCE', name: 'Bajaj Finance' },
    { abbr: 'BAJAJFINSV', name: 'Bajaj Finserv Ltd.' },
    { abbr: 'BPCL', name: 'Bharat Petroleum Corporation Ltd.' },
    { abbr: 'BHARTIARTL', name: 'Bharti Airtel Ltd.' },
    { abbr: 'INFRATEL', name: 'Bharti Infratel' },
    { abbr: 'CIPLA', name: 'Cipla Ltd.' },
    { abbr: 'COALINDIA', name: 'Coal India Ltd' },
    { abbr: 'DRREDDY', name: 'Dr. Reddys Laboratories Ltd.' },
    { abbr: 'EICHERMOT', name: 'Eicher Motors Ltd.' },
    { abbr: 'GAIL', name: 'GAIL (India) Ltd.' },
    { abbr: 'GRASIM', name: 'Grasim Industries Ltd.' },
    { abbr: 'HCLTECH', name: 'HCL Technologies Ltd.' },
    { abbr: 'HDFCBANK', name: 'HDFC Bank Ltd.' },
    { abbr: 'HEROMOTOCO', name: 'Hero MotoCorp Ltd.' },
    { abbr: 'HINDALCO', name: 'Hindalco Industries Ltd.' },
    { abbr: 'HINDPETRO', name: 'Hindustan Petroleum Corporation Ltd.' },
    { abbr: 'HINDUNILVR', name: 'Hindustan Unilever Ltd.' },
    { abbr: 'HDFC', name: 'Housing Development Finance Corporation Ltd.' },
    { abbr: 'ITC', name: 'I T C Ltd.' },
    { abbr: 'ICICIBANK', name: 'ICICI Bank Ltd.' },
    { abbr: 'IBULHSGFIN', name: 'Indiabulls Housing Finance' },
    { abbr: 'IOC', name: 'Indian Oil Corporation Ltd.' },
    { abbr: 'INDUSINDBK', name: 'IndusInd Bank Ltd.' },
    { abbr: 'INFY	', name: 'Infosys Ltd.' },
    { abbr: 'KOTAKBANK', name: 'Kotak Mahindra Bank Ltd.' },
    { abbr: 'LT', name: 'Larsen & Toubro Ltd.' },
    { abbr: 'LUPIN', name: 'Lupin Ltd.' },
    { abbr: 'M&M', name: 'Mahindra & Mahindra Ltd.' },
    { abbr: 'MARUTI', name: 'Maruti Suzuki India Ltd.' },
    { abbr: 'NTPC', name: 'NTPC Ltd.' },
    { abbr: 'ONGC', name: 'Oil & Natural Gas Corporation Ltd.' },
    { abbr: 'POWERGRID', name: 'Power Grid Corporation of India Ltd.' },
    { abbr: 'RELIANCE', name: 'Reliance Industries Ltd.' },
    { abbr: 'SBIN', name: 'State Bank of India' },
    { abbr: 'SUNPHARMA', name: 'Sun Pharmaceutical Industries Ltd.' },
    { abbr: 'TCS', name: 'Tata Consultancy Services Ltd.' },
    { abbr: 'TATAMOTORS', name: 'Tata Motors Ltd.' },
    { abbr: 'TATASTEEL', name: 'Tata Steel Ltd.' },
    { abbr: 'TECHM', name: 'Tech Mahindra Ltd.' },
    { abbr: 'TITAN', name: 'Titan Company Ltd.' },
    { abbr: 'ULTRACEMCO', name: 'UltraTech Cement Ltd.' },
    { abbr: 'UPL', name: 'UPL Ltd.' },
    { abbr: 'VEDL', name: 'Vedanta Ltd' },
    { abbr: 'WIPRO', name: 'Wipro Ltd.' },
    { abbr: 'YESBANK', name: 'Yes Bank Ltd.' },
    { abbr: 'ZEEL', name: 'Zee Entertainment Enterprises Ltd.' }
  ];
}
Earn a Tech Degree and get the skills like Frontend Development or Javascript Development that can help you to launch a career. Join the program

This function will return the top 50 stocks name and its abbreviation of Indian Share Market.

Also, we need to create one more function here, and that is matchStocks.

This function allows us to filter out the stocks that are typing by the user in the input area. So when the user starts typing in the text box, it will compare to the array of stocks and if find the match then return and display to the user.

So write the second function and export it from the data.js file.

// data.js

export function matchStocks(state, value) {
  return (
    state.name.toLowerCase().indexOf(value.toLowerCase()) !== -1 ||
    state.abbr.toLowerCase().indexOf(value.toLowerCase()) !== -1
  );
}

So, now basically, we import these functions inside App.js file and pass it to the Autocomplete component.

#3: Autocomplete API

It has the following properties.

value: It is the default value of the textbox, in our case, it will be empty or ”.

inputProps: It is an object. Props passed to props.renderInput.; By default, these props will be applied to the <input /> element rendered by Autocomplete unless you have specified a custom value for props.renderInput
wrapperStyle: It is an object, and it has the default value of the following.
{
display: 'inline-block'
}
items: It is an array of data, which is defined in the data.js file. In our case, it is a stock market data.
getItemValue: Used to read the display value from each entry in items.
shouldItemRender: It is a function. Invoked for each entry in items and its return value is used to determine whether or not it should be displayed in the drop-down menu. By de,fault all items are always rendered.
onChange: It is a function and invoked every time the user changes the input’s value.
onSelect: This function invokes when the user selects an item from the drop-down menu.
renderMenu: It is the function and invoked to generate the render tree for the drop-down menu. Ensure the returned tree includes every entry in items or else the highlighted order and keyboard navigation logic will break. The styles will contain { top, left, minWidth } which are the coordinates of the top-left corner and the width of the drop-down menu.
renderItem: It is the function and invoked for each entry in the items that also passes shouldItemRender to generate the render tree for each item in the drop-down menu. The styles is an optional set of styles that can be applied to improve the look/feel of the items in the drop-down menu.

#4: Add Autocomplete component into App.js file.

So our final App.js file looks like this.

import React, { Component } from 'react';
import Autocomplete from  'react-autocomplete';
import { getStocks, matchStocks } from './data';
import './App.css';

class App extends Component {

  state = { value: '' };

  render() {
    return (
      <div style = {{ marginTop: 40, marginLeft: 50 }}>
        <Autocomplete
          value={ this.state.value }
          inputProps={{ id: 'states-autocomplete' }}
          wrapperStyle={{ position: 'relative', display: 'inline-block' }}
          items={ getStocks() }
          getItemValue={ item => item.name }
          shouldItemRender={ matchStocks }
          onChange={(event, value) => this.setState({ value }) }
          onSelect={ value => this.setState({ value }) }
          renderMenu={ children => (
            <div className = "menu">
              { children }
            </div>
          )}
          renderItem={ (item, isHighlighted) => (
            <div
              className={`item ${isHighlighted ? 'item-highlighted' : ''}`}
              key={ item.abbr } >
              { item.name }
            </div>
          )}
        />
      </div>
      );
    }
  }

export default App;

Here, we have used all the properties that we have discussed earlier. Some of them are still not there, but you can check it out on the Github.

And our data.js file looks like this.

// data.js

export function getStocks() {
  return [
    { abbr: 'ADANIPORTS', name: 'Adani Ports & Special Economic Zone Ltd.' },
    { abbr: 'ASIANPAINT', name: 'Asian Paints Ltd.' },
    { abbr: 'AXISBANK', name: 'Axis Bank Ltd.' },
    { abbr: 'BAJAJ-AUTO', name: 'Bajaj Auto Ltd.' },
    { abbr: 'BAJFINANCE', name: 'Bajaj Finance' },
    { abbr: 'BAJAJFINSV', name: 'Bajaj Finserv Ltd.' },
    { abbr: 'BPCL', name: 'Bharat Petroleum Corporation Ltd.' },
    { abbr: 'BHARTIARTL', name: 'Bharti Airtel Ltd.' },
    { abbr: 'INFRATEL', name: 'Bharti Infratel' },
    { abbr: 'CIPLA', name: 'Cipla Ltd.' },
    { abbr: 'COALINDIA', name: 'Coal India Ltd' },
    { abbr: 'DRREDDY', name: 'Dr. Reddys Laboratories Ltd.' },
    { abbr: 'EICHERMOT', name: 'Eicher Motors Ltd.' },
    { abbr: 'GAIL	', name: 'GAIL (India) Ltd.' },
    { abbr: 'GRASIM', name: 'Grasim Industries Ltd.' },
    { abbr: 'HCLTECH', name: 'HCL Technologies Ltd.' },
    { abbr: 'HDFCBANK', name: 'HDFC Bank Ltd.' },
    { abbr: 'HEROMOTOCO', name: 'Hero MotoCorp Ltd.' },
    { abbr: 'HINDALCO', name: 'Hindalco Industries Ltd.' },
    { abbr: 'HINDPETRO', name: 'Hindustan Petroleum Corporation Ltd.' },
    { abbr: 'HINDUNILVR', name: 'Hindustan Unilever Ltd.' },
    { abbr: 'HDFC', name: 'Housing Development Finance Corporation Ltd.' },
    { abbr: 'ITC', name: 'I T C Ltd.' },
    { abbr: 'ICICIBANK', name: 'ICICI Bank Ltd.' },
    { abbr: 'IBULHSGFIN', name: 'Indiabulls Housing Finance' },
    { abbr: 'IOC', name: 'Indian Oil Corporation Ltd.' },
    { abbr: 'INDUSINDBK', name: 'IndusInd Bank Ltd.' },
    { abbr: 'INFY	', name: 'Infosys Ltd.' },
    { abbr: 'KOTAKBANK', name: 'Kotak Mahindra Bank Ltd.' },
    { abbr: 'LT', name: 'Larsen & Toubro Ltd.' },
    { abbr: 'LUPIN', name: 'Lupin Ltd.' },
    { abbr: 'M&M', name: 'Mahindra & Mahindra Ltd.' },
    { abbr: 'MARUTI', name: 'Maruti Suzuki India Ltd.' },
    { abbr: 'NTPC', name: 'NTPC Ltd.' },
    { abbr: 'ONGC', name: 'Oil & Natural Gas Corporation Ltd.' },
    { abbr: 'POWERGRID', name: 'Power Grid Corporation of India Ltd.' },
    { abbr: 'RELIANCE', name: 'Reliance Industries Ltd.' },
    { abbr: 'SBIN', name: 'State Bank of India' },
    { abbr: 'SUNPHARMA', name: 'Sun Pharmaceutical Industries Ltd.' },
    { abbr: 'TCS', name: 'Tata Consultancy Services Ltd.' },
    { abbr: 'TATAMOTORS', name: 'Tata Motors Ltd.' },
    { abbr: 'TATASTEEL', name: 'Tata Steel Ltd.' },
    { abbr: 'TECHM', name: 'Tech Mahindra Ltd.' },
    { abbr: 'TITAN', name: 'Titan Company Ltd.' },
    { abbr: 'ULTRACEMCO', name: 'UltraTech Cement Ltd.' },
    { abbr: 'UPL', name: 'UPL Ltd.' },
    { abbr: 'VEDL', name: 'Vedanta Ltd' },
    { abbr: 'WIPRO', name: 'Wipro Ltd.' },
    { abbr: 'YESBANK', name: 'Yes Bank Ltd.' },
    { abbr: 'ZEEL', name: 'Zee Entertainment Enterprises Ltd.' }
  ];
}

export function matchStocks(state, value) {
  return (
    state.name.toLowerCase().indexOf(value.toLowerCase()) !== -1 ||
    state.abbr.toLowerCase().indexOf(value.toLowerCase()) !== -1
  );
}

Finally, App.css file looks like this.

body {
  color: #333;
  font-family: "Helvetica Neue", Arial, sans-serif;
  font-weight: 200;
}

.example {
  padding: 0 25px;
}

label {
  display: block;
  margin: 5px 0;
}

code {
  padding: .2em .5em;
  font-size: 85%;
  background-color: rgba(0,0,0,0.04);
  border-radius: 3px;
}

.menu {
  position: absolute;
  box-sizing: border-box;
  width: 100%;
  border: 1px solid #cccccc;
}

.item {
  padding: 2px 6px;
  cursor: default;
}

.item-highlighted {
  color: white;
  background-color: #4095bf;
}

.item-header {
  background-color: #eeeeee;
  color: #454545;
  font-weight: bold;
}

Save all the files and go to the http://localhost:3000/

Type the stocks from the array of data, and you will get the suggestions.

 

React Autocomplete Tutorial

So, finally, we have completed the React Autocomplete Example Tutorial. Thanks for taking.

The post React Autocomplete Example Tutorial appeared first on AppDividend.

]]>
https://appdividend.com/2018/08/23/react-autocomplete-example-tutorial/feed/ 1
React Redux Node MongoDB JWT Authentication Example https://appdividend.com/2018/07/18/react-redux-node-mongodb-jwt-authentication/ https://appdividend.com/2018/07/18/react-redux-node-mongodb-jwt-authentication/#comments Wed, 18 Jul 2018 11:42:45 +0000 http://localhost/wordpress/?p=1327 Redux JWT Authentication Example Tutorial

React Redux Node MongoDB JWT Authentication Example is the today’s leading topic. We use React and Redux for the frontend, Node.js as a platform, express as a web framework and MongoDB as a NoSQL database. We use JWT authentication where, if the user is logged in then it returns a token and the client saves that […]

The post React Redux Node MongoDB JWT Authentication Example appeared first on AppDividend.

]]>
Redux JWT Authentication Example Tutorial

React Redux Node MongoDB JWT Authentication Example is the today’s leading topic. We use React and Redux for the frontend, Node.js as a platform, express as a web framework and MongoDB as a NoSQL database. We use JWT authentication where, if the user is logged in then it returns a token and the client saves that token. The client uses that token each time when he tries to access the protected route. So the concept is obvious. Now let us start this small project. This article is not about the beginner’s course. So if you are not familiar with Redux with React then check out this post React Redux Axios Tutorial Example From Scratch.

If you want to learn more about React.js then check out this  React 16 – The Complete Guide (incl. React Router 4 & Redux) Guide. It has a very brief intro about React and Redux.
React 16 – The Complete Guide (incl. React Router 4 & Redux)

React Redux Node MongoDB JWT Authentication

Now for this project, we need to separate projects.

  1. React Frontend
  2. Node Backend

For React Frontend, we can use the create-react-app boilerplate to kick off the frontend project, but for the backend, we need to create the project from scratch.

#1: Create a backend on Node.js.

Now, first, we need to create the main project. So type the following command to create a project.

mkdir jwtauth

Now, go inside that folder.

cd jwtauth

In this folder, we have two more folders. One for backend and one for the frontend.

Create a backend folder.

mkdir backend

Now, go into the folder.

cd backend

Type the following command to initialize the package.json file.

npm init -y

Okay, now we need to install the dependencies. I have installed all the dependencies that will need in this backend project. We will use a passport, passport-jwt, jsonwebtoken for authentication. Mongoose for ORM for MongoDB, the validator for validating the input types, body-parser for parsing the data that comes from request, gravatar for getting avatar image associated with an email address.

yarn add bcryptjs body-parser express gravatar jsonwebtoken mongoose passport passport-jwt validator

# or

npm install --save bcryptjs body-parser express gravatar jsonwebtoken mongoose passport passport-jwt validator

Also, we need to install nodemon for development dependency.

npm install -D nodemon

We need this dependency because when we save our file, we need to restart the node.js server and nodemon does this precisely without stop or restart the server manually.

Okay, now start the mongodb server by the following command.

mongod

If you have not installed then install MongoDB server first and then if possible install the database client like studio3t or use MongoLab to create a database. It has the free version.

#2: Create an app.js file to create the node server.

Inside the backend folder, create one file called app.js and add the following code.

// app.js

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');

const app = express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.get('/', function(req, res) {
    res.send('hello');
});

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
    console.log(`Server is running on PORT ${PORT}`);
});

Go to the root of the backend project and open the terminal and type the following command to start the node.js server by using the following command.

nodemon app

It will start the server at port: 5000.

React Redux Node MongoDB JWT Authentication Example

 

#3: Create a database file called db.js.

Write the following code inside the db.js file.

// db.js

module.exports = {
    DB: 'mongodb://localhost:27017/auth'
}

Include the db.js file inside an app.js file.

// app.js

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');
const config = require('./db');

mongoose.connect(config.DB, { useNewUrlParser: true }).then(
    () => {console.log('Database is connected') },
    err => { console.log('Can not connect to the database'+ err)}
);

const app = express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.get('/', function(req, res) {
    res.send('hello');
});

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
    console.log(`Server is running on PORT ${PORT}`);
});

Save the file and make sure that your mongodb server is running. So in the console, you can see that Database is connected!!

#4: Create a User model.

Inside the backend folder, create one folder called models and inside that folder, create one file called User.js. Write the following schema inside User.js file.

// User.js

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const UserSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true
    },
    password: {
        type: String,
        required: true
    },
    avatar: {
        type: String
    },
    date: {
        type: Date,
        default: Date.now
    }
});

const User = mongoose.model('users', UserSchema);

module.exports = User;

The name, email, and password come from the React.js form. We fetch the avatar from gravatar based on email address.

#5: Create a validation for input values.

Inside the backend folder, create a folder called validation and inside that, create one file called register.js. But before that, we also need to create one more validation file called is-empty.js inside same validation directory.

// is-empty.js

const isEmpty = (value) => {
    return (
        value === undefined ||
        value === null ||
        (typeof value === 'object' && Object.keys(value).length === 0) ||
        (typeof value === 'string' && value.trim().length === 0)
    );
}
module.exports = isEmpty;

This function will check if the passed value is undefined or null or object or string‘s length is 0.

Write the following code inside the register.js file. For validation, we have used the validator library.

// register.js

const Validator = require('validator');
const isEmpty = require('./is-empty');

module.exports = function validateRegisterInput(data) {
    let errors = {};
    data.name = !isEmpty(data.name) ? data.name : '';
    data.email = !isEmpty(data.email) ? data.email : '';
    data.password = !isEmpty(data.password) ? data.password : '';
    data.password_confirm = !isEmpty(data.password_confirm) ? data.password_confirm : '';

    if(!Validator.isLength(data.name, { min: 2, max: 30 })) {
        errors.name = 'Name must be between 2 to 30 chars';
    }
    
    if(Validator.isEmpty(data.name)) {
        errors.name = 'Name field is required';
    }

    if(!Validator.isEmail(data.email)) {
        errors.email = 'Email is invalid';
    }

    if(Validator.isEmpty(data.email)) {
        errors.email = 'Email is required';
    }

    if(!Validator.isLength(data.password, {min: 6, max: 30})) {
        errors.password = 'Password must have 6 chars';
    }

    if(Validator.isEmpty(data.password)) {
        errors.password = 'Password is required';
    }

    if(!Validator.isLength(data.password_confirm, {min: 6, max: 30})) {
        errors.password_confirm = 'Password must have 6 chars';
    }

    if(!Validator.equals(data.password, data.password_confirm)) {
        errors.password_confirm = 'Password and Confirm Password must match';
    }

    if(Validator.isEmpty(data.password_confirm)) {
        errors.password_confirm = 'Password is required';
    }

    return {
        errors,
        isValid: isEmpty(errors)
    }
}

Here, I have used validator function to check the input values and based on the values, if the values are empty or not formatted correctly, or length is not defined in the rules then, it fills an error object and sends back to the client.

Here all the input values are checked to see the validation and if it fails then error object will be sent back to the user and display that errors in proper format.

Also same for login form validation. So inside validation folder, create one file called login.js and add the following code.

// login.js

const Validator = require('validator');
const isEmpty = require('./is-empty');

module.exports = function validateLoginInput(data) {
    let errors = {};
    data.email = !isEmpty(data.email) ? data.email : '';
    data.password = !isEmpty(data.password) ? data.password : '';

    if(!Validator.isEmail(data.email)) {
        errors.email = 'Email is invalid';
    }

    if(Validator.isEmpty(data.email)) {
        errors.email = 'Email is required';
    }

    if(!Validator.isLength(data.password, {min: 6, max: 30})) {
        errors.password = 'Password must have 6 chars';
    }

    if(Validator.isEmpty(data.password)) {
        errors.password = 'Password is required';
    }

    return {
        errors,
        isValid: isEmpty(errors)
    }
}

#6: Create routes for register and login.

We are using jwt-authentication, so we need to create a passport’s jwt strategy. So inside the backend folder, we need to create one file called passport.js. Write the following code inside passport.js.

// passport.js

const JWTStrategy = require('passport-jwt').Strategy;
const ExtractJWT = require('passport-jwt').ExtractJwt;
const mongoose = require('mongoose');
const User = mongoose.model('users');
const opts = {};

opts.jwtFromRequest = ExtractJWT.fromAuthHeaderAsBearerToken();
opts.secretOrKey = 'secret';

module.exports = passport => {
    passport.use(new JWTStrategy(opts, (jwt_payload, done) => {
        User.findById(jwt_payload.id)
            .then(user => {
                if(user) {
                    return done(null, user);
                }
                return done(null, false);
            })
            .catch(err => console.error(err));
    }));
}

Inside the backend folder, create one folder called routes and inside that folder, create one file called user.js and add the following code inside it.

// user.js

const express = require('express');
const router = express.Router();
const gravatar = require('gravatar');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const passport = require('passport');
const validateRegisterInput = require('../validation/register');
const validateLoginInput = require('../validation/login');

const User = require('../models/User');

router.post('/register', function(req, res) {

    const { errors, isValid } = validateRegisterInput(req.body);

    if(!isValid) {
        return res.status(400).json(errors);
    }
    User.findOne({
        email: req.body.email
    }).then(user => {
        if(user) {
            return res.status(400).json({
                email: 'Email already exists'
            });
        }
        else {
            const avatar = gravatar.url(req.body.email, {
                s: '200',
                r: 'pg',
                d: 'mm'
            });
            const newUser = new User({
                name: req.body.name,
                email: req.body.email,
                password: req.body.password,
                avatar
            });
            
            bcrypt.genSalt(10, (err, salt) => {
                if(err) console.error('There was an error', err);
                else {
                    bcrypt.hash(newUser.password, salt, (err, hash) => {
                        if(err) console.error('There was an error', err);
                        else {
                            newUser.password = hash;
                            newUser
                                .save()
                                .then(user => {
                                    res.json(user)
                                }); 
                        }
                    });
                }
            });
        }
    });
});

router.post('/login', (req, res) => {

    const { errors, isValid } = validateLoginInput(req.body);

    if(!isValid) {
        return res.status(400).json(errors);
    }

    const email = req.body.email;
    const password = req.body.password;

    User.findOne({email})
        .then(user => {
            if(!user) {
                errors.email = 'User not found'
                return res.status(404).json(errors);
            }
            bcrypt.compare(password, user.password)
                    .then(isMatch => {
                        if(isMatch) {
                            const payload = {
                                id: user.id,
                                name: user.name,
                                avatar: user.avatar
                            }
                            jwt.sign(payload, 'secret', {
                                expiresIn: 3600
                            }, (err, token) => {
                                if(err) console.error('There is some error in token', err);
                                else {
                                    res.json({
                                        success: true,
                                        token: `Bearer ${token}`
                                    });
                                }
                            });
                        }
                        else {
                            errors.password = 'Incorrect Password';
                            return res.status(400).json(errors);
                        }
                    });
        });
});

router.get('/me', passport.authenticate('jwt', { session: false }), (req, res) => {
    return res.json({
        id: req.user.id,
        name: req.user.name,
        email: req.user.email
    });
});

module.exports = router;

So, here, I have defined the two post routes.

  1. Register.
  2. Login.

Inside the post route of the register, we first check the validation for all of our inputs. If the errors exist, then there is no need for the further process. So sent back the error response to the client.

After that, we check, if the email already exists, if so we need to send an error response to the client.

Otherwise, we fetch the avatar based on email address, if an avatar is not there then by default will be sent back as a response.

Then we create a hash value of the password and save the user in the database successfully and send back that user to the client.

Now, for login the user, first, we check the validation same as a register.

Then go for checking the email, and if the email is not found, then we send back the error to the client saying that user is not found.

If email is proper, then we check password with bcrypt’s compare method. If the match is found, then we need to generate the jwt token.

We use the user object as a payload and give a secret key to generate JWT token and send back that token to the user and logged in the user.

Also, I have used get route, and that is /me.

If the user is logged in and it has the jwt token then and then it can access this route otherwise he will redirect back to log in because this route is protected.

Finally, import passport.js file and routes >> user.js file inside backend >> app.js file.

So, our final app.js file looks like below.

// app.js

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');
const config = require('./db');

const users = require('./routes/user'); 

mongoose.connect(config.DB, { useNewUrlParser: true }).then(
    () => {console.log('Database is connected') },
    err => { console.log('Can not connect to the database'+ err)}
);

const app = express();
app.use(passport.initialize());
require('./passport')(passport);

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use('/api/users', users);

app.get('/', function(req, res) {
    res.send('hello');
});

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
    console.log(`Server is running on PORT ${PORT}`);
});

So, we have completed our backend for this React Redux Node MongoDB JWT Authentication Tutorial. Now, we need to build a frontend using React.js and Redux.

#7: Create React.js project using create-react-app.

For generating the react.js project. We need to go to the root of the jwtauth folder and type the following command.

create-react-app frontend

 

React Redux Authentication

Now, go to the frontend folder.

cd frontend

Install the dependencies using the following command.

yarn add axios bootstrap classnames jwt-decode react-redux react-router-dom redux redux-thunk

# or

npm install --save axios bootstrap classnames jwt-decode react-redux react-router-dom redux redux-thunk

Now, inside package.json file of the frontend project, we need to add a proxy, so that we can avoid the CORS problem because of its a cross-origin request from frontend to backend. The react.js project will be running on PORT: 3000 and Node.js project will be on the PORT: 5000. So CORS problem will arise. To avoid that, we need to add a proxy. It simulates as one server in which react.js is running, but both are different.

So our final package.json file looks like below.

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "axios": "^0.18.0",
    "bootstrap": "^4.1.2",
    "classnames": "^2.2.6",
    "jwt-decode": "^2.2.0",
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.3.1",
    "react-scripts": "1.1.4",
    "redux": "^4.0.0",
    "redux-thunk": "^2.3.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": "http://localhost:5000"
}

Here, we have added proxy server to node.js server. So that our api request will look like this.

http://localhost:3000/api/users/register

Although, our primary node server will be running on port:5000. If you try the API in postman, then you have to send a POST request to the following URL.

http://localhost:5000/api/users/register

But, we have added a proxy, so now we can send a post request from the 3000 port and also receive to the 3000 port. Thus, both domains are the same, and we do not face the CORS error.

Import the bootstrap inside src >> App.js file.

// App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';

class App extends Component {
  render() {
    return (
      <div>
        React Redux Auth App
      </div>
    );
  }
}

export default App;

Save the file and start the React development server using the following command.

npm start

#8: Create a Navbar.

Inside src folder, create one folder called components and inside that folder, create one file called Navbar.js and add the following code.

// Navbar.js

import React, { Component } from 'react';

class Navbar extends Component {
    render() {
        return(
            <nav class="navbar navbar-expand-lg navbar-light bg-light">
                <a class="navbar-brand" href="#">Redux Auth</a>
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav ml-auto">
                        <li class="nav-item">
                            <a class="nav-link" href="#">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">Register</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">Login</a>
                        </li>
                    </ul>
                </div>
            </nav>
        )
    }
}
export default Navbar;

Import this Navbar.js file inside the App.js file.

// App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Navbar from './components/Navbar';

class App extends Component {
  render() {
    return (
      <div>
        <Navbar />
      </div>
    );
  }
}

export default App;

#9: Create a Register component.

Inside src >> components folder, create one component called Register.js and add the following code.

// Register.js

import React, { Component } from 'react';

class Register extends Component {

    constructor() {
        super();
        this.state = {
            name: '',
            email: '',
            password: '',
            password_confirm: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleInputChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            name: this.state.name,
            email: this.state.email,
            password: this.state.password,
            password_confirm: this.state.password_confirm
        }
        console.log(user);
    }

    render() {
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Registration</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="text"
                    placeholder="Name"
                    className="form-control"
                    name="name"
                    onChange={ this.handleInputChange }
                    value={ this.state.name }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className="form-control"
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className="form-control"
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Confirm Password"
                    className="form-control"
                    name="password_confirm"
                    onChange={ this.handleInputChange }
                    value={ this.state.password_confirm }
                    />
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Register User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

export default Register;

Okay, so when now fill all the textbox values and hit the Register button, you can see that, we got all the values inside out console of the browser.

Same we can create a Login component inside components folder. Add the following code inside Login.js file.

// Login.js

import React, { Component } from 'react';

class Login extends Component {

    constructor() {
        super();
        this.state = {
            email: '',
            password: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleInputChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            email: this.state.email,
            password: this.state.password,
        }
        console.log(user);
    }

    render() {
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Login</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className="form-control"
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className="form-control"
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Login User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

export default Login;

#10: Setup the React Router.

We forget to create one component called Home. So let us create inside the components folder.

// Home.js

import React, { Component } from 'react';

export default class Home extends Component {
    render() {
        return (
            <div>
                Home Component
            </div>
        );
    }
}

Inside the src >> App.js file add the following code.

// App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';

import Navbar from './components/Navbar';
import Register from './components/Register';
import Login from './components/Login';
import Home from './components/Home';

import 'bootstrap/dist/css/bootstrap.min.css';

class App extends Component {
  render() {
    return (
      <Router>
          <div>
            <Navbar />
              <Route exact path="/" component={ Home } />
              <div className="container">
                <Route exact path="/register" component={ Register } />
                <Route exact path="/login" component={ Login } />
              </div>
          </div>
        </Router>
    );
  }
}

export default App;

Also, we need to add the Link to the components >> Navbar.js file.

// Navbar.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';

class Navbar extends Component {
    render() {
        return(
            <nav className="navbar navbar-expand-lg navbar-light bg-light">
                <Link className="navbar-brand" to="/">Redux Node Auth</Link>
                <div className="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul className="navbar-nav ml-auto">
                        <li className="nav-item">
                            <Link className="nav-link" to="/register">Sign Up</Link>
                        </li>
                        <li className="nav-item">
                            <Link className="nav-link" to="/login">Sign Up</Link>
                        </li>
                        <li className="nav-item">
                            <Link className="nav-link" to="/">Home</Link>
                        </li>
                    </ul>
                </div>
            </nav>
        )
    }
}
export default Navbar;

Now, we can navigate through different links using React Router.

#11: Setup a Redux Store.

Inside the src folder, create two folders.

  1. actions
  2. reducers

Inside reducers folder, create one file called index.js and add the following code in it.

// index.js

import { combineReducers } from 'redux';

export default combineReducers({
   
});

Right now, we do not have any reducers. But we will have reducer files in the future.

Inside the src folder, create one file called store.js and add the following code in it.

// store.js

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const inititalState = {};

const store = createStore(
        rootReducer, 
        inititalState, 
        compose(applyMiddleware(thunk), 
                window.__REDUX_DEVTOOLS_EXTENSION__&& window.__REDUX_DEVTOOLS_EXTENSION__()));

export default store;

Here, we have used redux-thunk middleware to deal with AJAX or network request through redux.

Also, I have used the compose function. We have used a chrome extension to display our store data in that extension. So we have connected our Redux application to that extension.

Now we need to pass this store into our React application. So modify the src >> App.js file with the following code.

// App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './store';

import Navbar from './components/Navbar';
import Register from './components/Register';
import Login from './components/Login';
import Home from './components/Home';

import 'bootstrap/dist/css/bootstrap.min.css';

class App extends Component {
  render() {
    return (
      <Provider store = { store }>
        <Router>
            <div>
              <Navbar />
                <Route exact path="/" component={ Home } />
                <div className="container">
                  <Route exact path="/register" component={ Register } />
                  <Route exact path="/login" component={ Login } />
                </div>
            </div>
          </Router>
        </Provider>
    );
  }
}

export default App;

#12: Create actions.

We create two actions throughout our project.

  1. GET_ERRORS
  2. SET_CURRENT_USER

So inside actions folder, create one file called types.js and add the following code in it.

// types.js

export const GET_ERRORS = 'GET_ERRORS';
export const SET_CURRENT_USER = 'SET_CURRENT_USER';

Also, inside actions folder, create one file called authentication.js and add the following code.

Write the following code inside an authentication.js file.

// authentication.js

import axios from 'axios';
import { GET_ERRORS } from './types';

export const registerUser = (user, history) => dispatch => {
    axios.post('/api/users/register', user)
            .then(res => history.push('/login'))
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

export const loginUser = (user) => dispatch => {
    axios.post('/api/users/login', user)
            .then(res => {
                console.log(res.data);
            })
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

So, from this file, we will send an AJAX request to the node.js server. We can not write this code inside Reducer because otherwise, it is a violation of pure function. So we need to write any database operations from actions.

If we get any errors, then we dispatch the actions and reducer will handle that for us.

#13: Create reducers.

Inside reducers folder, create one file called errorReducer.js and add the following code.

// errorReducer.js

import { GET_ERRORS } from '../actions/types';

const initialState = {};

export default function(state = initialState, action ) {
    switch(action.type) {
        case GET_ERRORS:
            return action.payload;
        default: 
            return state;
    }
}

If any errors occur then this reducer fill the state with errors and we can display that errors from the frontend. Now, import this errorReducer.js file inside reducers >> index.js file.

// index.js

import { combineReducers } from 'redux';
import errorReducer from './errorReducer';

export default combineReducers({
    errors: errorReducer
});

#14: Create a validation.

Inside src folder, create one file called is-empty.js and add the following code in it.

// is-empty.js

const isEmpty = (value) => {
    return (
        value === undefined ||
        value === null ||
        (typeof value === 'object' && Object.keys(value).length === 0) ||
        (typeof value === 'string' && value.trim().length === 0)
    );
}
export default isEmpty;

We need this file when we check whether the user is authenticated or not.

#15: Connect Register component to Redux store.

Okay, so now it’s time to connect our Register.js file to the Redux store. For that, we use the connect method provided by react-redux.

// Register.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { registerUser } from '../actions/authentication';

class Register extends Component {

    constructor() {
        super();
        this.state = {
            name: '',
            email: '',
            password: '',
            password_confirm: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleInputChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            name: this.state.name,
            email: this.state.email,
            password: this.state.password,
            password_confirm: this.state.password_confirm
        }
        this.props.registerUser(user, this.props.history);
    }

    componentWillReceiveProps(nextProps) {
        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    render() {
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Registration</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="text"
                    placeholder="Name"
                    className="form-control"
                    name="name"
                    onChange={ this.handleInputChange }
                    value={ this.state.name }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className="form-control"
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className="form-control"
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Confirm Password"
                    className="form-control"
                    name="password_confirm"
                    onChange={ this.handleInputChange }
                    value={ this.state.password_confirm }
                    />
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Register User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Register.propTypes = {
    registerUser: PropTypes.func.isRequired,
};

const mapStateToProps = state => ({
    errors: state.errors
});

export default connect(mapStateToProps,{ registerUser })(withRouter(Register))

Now, register the user with the empty value and analyze the console. You can see that its 400 Bad Request because we are getting errors. We need to figure it somehow out how we can display the errors.

#16: Display the Validation errors.

We have already installed the module called classnames. We just need to render conditional errors. So we can write the Register.js file like below.

// Register.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { registerUser } from '../actions/authentication';
import classnames from 'classnames';

class Register extends Component {

    constructor() {
        super();
        this.state = {
            name: '',
            email: '',
            password: '',
            password_confirm: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleInputChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            name: this.state.name,
            email: this.state.email,
            password: this.state.password,
            password_confirm: this.state.password_confirm
        }
        this.props.registerUser(user, this.props.history);
    }

    componentWillReceiveProps(nextProps) {
        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    render() {
        const { errors } = this.state;
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Registration</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="text"
                    placeholder="Name"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.name
                    })}
                    name="name"
                    onChange={ this.handleInputChange }
                    value={ this.state.name }
                    />
                    {errors.name && (<div className="invalid-feedback">{errors.name}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.email
                    })}
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                    {errors.email && (<div className="invalid-feedback">{errors.email}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password
                    })}
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                    {errors.password && (<div className="invalid-feedback">{errors.password}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Confirm Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password_confirm
                    })}
                    name="password_confirm"
                    onChange={ this.handleInputChange }
                    value={ this.state.password_confirm }
                    />
                    {errors.password_confirm && (<div className="invalid-feedback">{errors.password_confirm}</div>)}
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Register User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Register.propTypes = {
    registerUser: PropTypes.func.isRequired,
};

const mapStateToProps = state => ({
    errors: state.errors
});

export default connect(mapStateToProps,{ registerUser })(withRouter(Register))

We can see the errors like below image.

 

Redux Node Mongodb Authentication

If all of the values of the input box is right and valid then we can be able to sign up and redirect to login page.

#17: Connect Login component to Redux Store.

Edit the Login.js file with the following code.

// Login.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { loginUser } from '../actions/authentication';

class Login extends Component {

    constructor() {
        super();
        this.state = {
            email: '',
            password: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleInputChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            email: this.state.email,
            password: this.state.password,
        }
        this.props.loginUser(user);
    }

    componentWillReceiveProps(nextProps) {

        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    render() {
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Login</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className="form-control"
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className="form-control"
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Login User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Login.propTypes = {
    errors: PropTypes.object.isRequired
}

const mapStateToProps = (state) => ({
    errors: state.errors
})

export  default connect(mapStateToProps, { loginUser })(Login)

Now, try to login the user with the empty values and analyze the console. You can see that its 400 Bad Request because we are getting errors. We use same classnames module to display the errors.

So edit the Login.js component with the following code.

// Login.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { loginUser } from '../actions/authentication';
import classnames from 'classnames';

class Login extends Component {

    constructor() {
        super();
        this.state = {
            email: '',
            password: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleInputChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            email: this.state.email,
            password: this.state.password,
        }
        this.props.loginUser(user);
    }

    componentWillReceiveProps(nextProps) {

        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    render() {
        const {errors} = this.state;
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Login</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.email
                    })}
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                    {errors.email && (<div className="invalid-feedback">{errors.email}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password
                    })} 
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                    {errors.password && (<div className="invalid-feedback">{errors.password}</div>)}
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Login User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Login.propTypes = {
    errors: PropTypes.object.isRequired
}

const mapStateToProps = (state) => ({
    errors: state.errors
})

export  default connect(mapStateToProps, { loginUser })(Login)

Now, we can see the validation errors.

 

Redux JWT Authentication

Now, if all of your credentials are right then we will get a token in response and we can see that token inside our console right now.

After getting a token, we need to store that token inside localStorage and set the header to add that token in the future request. So when we try to access any protected route then due to jwt token, we can access that route very easily.

#18: Set the Auth token.

Inside src folder, create one file called setAuthToken.js and add the following code.

// setAuthToken.js

import axios from 'axios';

const setAuthToken = token => {
    if(token) {
        axios.defaults.headers.common['Authorization'] = token;
    }
    else {
        delete axios.defaults.headers.common['Authorization'];
    }
}

export default setAuthToken;

Okay, now we have set the headers and add the Authorization to a token. Now, we need to save this token and set the current user as a logged in user.

Write the following code inside actions >> authentication.js file.

// authentication.js

import axios from 'axios';
import { GET_ERRORS, SET_CURRENT_USER } from './types';
import setAuthToken from '../setAuthToken';
import jwt_decode from 'jwt-decode';

export const registerUser = (user, history) => dispatch => {
    axios.post('/api/users/register', user)
            .then(res => history.push('/login'))
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

export const loginUser = (user) => dispatch => {
    axios.post('/api/users/login', user)
            .then(res => {
                const { token } = res.data;
                localStorage.setItem('jwtToken', token);
                setAuthToken(token);
                const decoded = jwt_decode(token);
                dispatch(setCurrentUser(decoded));
            })
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

export const setCurrentUser = decoded => {
    return {
        type: SET_CURRENT_USER,
        payload: decoded
    }
}

Also, we need to create one more reducer called authReducer.js and add the following code inside it.

// authReducer.js

import { SET_CURRENT_USER } from '../actions/types';
import isEmpty from '../validation/is-empty';

const initialState = {
    isAuthenticated: false,
    user: {}
}

export default function(state = initialState, action ) {
    switch(action.type) {
        case SET_CURRENT_USER:
            return {
                ...state,
                isAuthenticated: !isEmpty(action.payload),
                user: action.payload
            }
        default: 
            return state;
    }
}

Import this reducer inside reducers >> index.js file.

// index.js

import { combineReducers } from 'redux';
import errorReducer from './errorReducer';
import authReducer from './authReducer';

export default combineReducers({
    errors: errorReducer,
    auth: authReducer
});

#19: Create a Logout.

Now, we need to connect the redux store to the component >> Navbar.js file and also we need to change the Navbar based on the User is logged in or not.

So write the following code inside Navbar.js file.

// Navbar.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { logoutUser } from '../actions/authentication';
import { withRouter } from 'react-router-dom';

class Navbar extends Component {

    onLogout(e) {
        e.preventDefault();
        this.props.logoutUser(this.props.history);
    }

    render() {
        const {isAuthenticated, user} = this.props.auth;
        const authLinks = (
            <ul className="navbar-nav ml-auto">
                <a href="#" className="nav-link" onClick={this.onLogout.bind(this)}>
                    <img src={user.avatar} alt={user.name} title={user.name}
                        className="rounded-circle"
                        style={{ width: '25px', marginRight: '5px'}} />
                            Logout
                </a>
            </ul>
        )
      const guestLinks = (
        <ul className="navbar-nav ml-auto">
            <li className="nav-item">
                <Link className="nav-link" to="/register">Sign Up</Link>
            </li>
            <li className="nav-item">
                <Link className="nav-link" to="/login">Sign In</Link>
            </li>
        </ul>
      )
        return(
            <nav className="navbar navbar-expand-lg navbar-light bg-light">
                <Link className="navbar-brand" to="/">Redux Node Auth</Link>
                <div className="collapse navbar-collapse" id="navbarSupportedContent">
                    {isAuthenticated ? authLinks : guestLinks}
                </div>
            </nav>
        )
    }
}
Navbar.propTypes = {
    logoutUser: PropTypes.func.isRequired,
    auth: PropTypes.object.isRequired
}

const mapStateToProps = (state) => ({
    auth: state.auth
})

export default connect(mapStateToProps, { logoutUser })(withRouter(Navbar));

Now, we need to create a logoutUser action inside actions >> authentication.js file.

// authentication.js

import axios from 'axios';
import { GET_ERRORS, SET_CURRENT_USER } from './types';
import setAuthToken from '../setAuthToken';
import jwt_decode from 'jwt-decode';

export const registerUser = (user, history) => dispatch => {
    axios.post('/api/users/register', user)
            .then(res => history.push('/login'))
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

export const loginUser = (user) => dispatch => {
    axios.post('/api/users/login', user)
            .then(res => {
                const { token } = res.data;
                localStorage.setItem('jwtToken', token);
                setAuthToken(token);
                const decoded = jwt_decode(token);
                dispatch(setCurrentUser(decoded));
            })
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

export const setCurrentUser = decoded => {
    return {
        type: SET_CURRENT_USER,
        payload: decoded
    }
}

export const logoutUser = (history) => dispatch => {
    localStorage.removeItem('jwtToken');
    setAuthToken(false);
    dispatch(setCurrentUser({}));
    history.push('/login');
}

Now, we can be able to log out the user successfully and we can also see that Navbar items are changing according to the user is logged in or not.

#20: Check the logged in user status.

If any point in time, the user is logged in then he can not able to see the login or register route. For that, we need to add some code inside Register.js and Login.js file.

Our final Register.js file looks like below. We have added a componentDidMount method. If the current user is logged in user and trying to register the new user, then it prevents it and redirects to a home route.

// Register.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { registerUser } from '../actions/authentication';
import classnames from 'classnames';

class Register extends Component {

    constructor() {
        super();
        this.state = {
            name: '',
            email: '',
            password: '',
            password_confirm: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleInputChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            name: this.state.name,
            email: this.state.email,
            password: this.state.password,
            password_confirm: this.state.password_confirm
        }
        this.props.registerUser(user, this.props.history);
    }

    componentWillReceiveProps(nextProps) {
        if(nextProps.auth.isAuthenticated) {
            this.props.history.push('/')
        }
        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    componentDidMount() {
        if(this.props.auth.isAuthenticated) {
            this.props.history.push('/');
        }
    }

    render() {
        const { errors } = this.state;
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Registration</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="text"
                    placeholder="Name"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.name
                    })}
                    name="name"
                    onChange={ this.handleInputChange }
                    value={ this.state.name }
                    />
                    {errors.name && (<div className="invalid-feedback">{errors.name}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.email
                    })}
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                    {errors.email && (<div className="invalid-feedback">{errors.email}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password
                    })}
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                    {errors.password && (<div className="invalid-feedback">{errors.password}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Confirm Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password_confirm
                    })}
                    name="password_confirm"
                    onChange={ this.handleInputChange }
                    value={ this.state.password_confirm }
                    />
                    {errors.password_confirm && (<div className="invalid-feedback">{errors.password_confirm}</div>)}
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Register User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Register.propTypes = {
    registerUser: PropTypes.func.isRequired,
    auth: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
    auth: state.auth,
    errors: state.errors
});

export default connect(mapStateToProps,{ registerUser })(withRouter(Register))

Also, we need to add some code inside src >> App.js file. The final App.js file looks like below.

// App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './store';
import jwt_decode from 'jwt-decode';
import setAuthToken from './setAuthToken';
import { setCurrentUser, logoutUser } from './actions/authentication';

import Navbar from './components/Navbar';
import Register from './components/Register';
import Login from './components/Login';
import Home from './components/Home';

import 'bootstrap/dist/css/bootstrap.min.css';

if(localStorage.jwtToken) {
  setAuthToken(localStorage.jwtToken);
  const decoded = jwt_decode(localStorage.jwtToken);
  store.dispatch(setCurrentUser(decoded));

  const currentTime = Date.now() / 1000;
  if(decoded.exp < currentTime) {
    store.dispatch(logoutUser());
    window.location.href = '/login'
  }
}

class App extends Component {
  render() {
    return (
      <Provider store = { store }>
        <Router>
            <div>
              <Navbar />
                <Route exact path="/" component={ Home } />
                <div className="container">
                  <Route exact path="/register" component={ Register } />
                  <Route exact path="/login" component={ Login } />
                </div>
            </div>
          </Router>
        </Provider>
    );
  }
}

export default App;

And also we need to add componentDidMount inside Login.js file.

// Login.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { loginUser } from '../actions/authentication';
import classnames from 'classnames';

class Login extends Component {

    constructor() {
        super();
        this.state = {
            email: '',
            password: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleInputChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            email: this.state.email,
            password: this.state.password,
        }
        this.props.loginUser(user);
    }

    componentDidMount() {
        if(this.props.auth.isAuthenticated) {
            this.props.history.push('/');
        }
    }

    componentWillReceiveProps(nextProps) {
        if(nextProps.auth.isAuthenticated) {
            this.props.history.push('/')
        }
        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    render() {
        const {errors} = this.state;
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Login</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.email
                    })}
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                    {errors.email && (<div className="invalid-feedback">{errors.email}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password
                    })} 
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                    {errors.password && (<div className="invalid-feedback">{errors.password}</div>)}
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Login User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Login.propTypes = {
    loginUser: PropTypes.func.isRequired,
    auth: PropTypes.object.isRequired,
    errors: PropTypes.object.isRequired
}

const mapStateToProps = (state) => ({
    auth: state.auth,
    errors: state.errors
})

export  default connect(mapStateToProps, { loginUser })(Login)

So, finally our React Redux Node MongoDB JWT Authentication Example Tutorial is over.

Register with a new User and it will redirect to a login page.

Login with your credentials and you can see the avatar is appearing inside the navbar and links are also changed.

Now, try to access the login or register route and you will be redirected to the root or home route.

Next, try to log out and you will be on the login page.

I have put the whole code on Github.

You can find more on Redux here.

Github Code

The post React Redux Node MongoDB JWT Authentication Example appeared first on AppDividend.

]]>
https://appdividend.com/2018/07/18/react-redux-node-mongodb-jwt-authentication/feed/ 24