ReactJS App With Laravel RESTful API Endpoint Part 2

ReactJS App With Laravel RESTful API Endpoint Part 2  #redux

  • /reducers”;const logger = createLogger();export default createStore(reducer, composeWithDevTools( applyMiddleware(thunk, promise, logger),));This file is the store that holds the application state and provides a few helper methods to access the state, dispatch actions and register listeners.
  • /UsersReducer”export default combineReducers({ users})UsersReducer.jsexport default function reducer(state={ users: [], user: null, fetched: false, error: null}, action){switch (action.type){case “FETCH_USERS_REJECTED”: { return { …state, fetched: false, error: action.payload } }case “FETCH_USERS_FULFILLED”: { return { …state, fetched: true, users: action.payload.data.users, } }case “FETCH_USER_REJECTED”: { return { …state, fetched: false, error: action.payload } }case “FETCH_USER_FULFILLED”: { return { …state, fetched: true, user: action.payload } }}return state;}Next we update the app.js file in the public/js/ folderapp.js import React from “react”;import ReactDOM from “react-dom”;import { Router, Route, IndexRoute, hashHistory } from “react-router”;import { Provider } from “react-redux”;import Layout from “.
  • /store”;const app = Provider store={store} Router history = { hashHistory } Route path = “/” component = { Layout } IndexRoute component = { Home }/IndexRoute Route path = “users” component = { Users }/Route Route path = “users/new” component = { NewUser }/Route Route path = “users/:id/edit” component = { EditUser }/Route Route path = “articles” component = { Articles }/Route /Route /Router /Provider, app);Wrapping the router with a react-redux Provider component which would allow our React components to automatically share data and efficiently update whenever some action is triggered.Step 1Update the Users.js inside the public/js/components folderUsers.jsimport React from ‘react’;import { connect } from “react-redux”;import { Link } from “react-router”import { fetchUsers, deleteUser } from Users extends React.Component{constructor(){ super(); this.handleBtnDelete = event){ event.preventDefault();var r = confirm(“Are you sure you want to delete this document!”)
  • ; if (r == true) { const url = var formElement = var formData = new FormData(formElement); } }render(){return( div h1 className=”pull-left”Users/h1 div className=”col-lg-12″Link to=”users/new” className=”btn btn-primary btn-sm pull-left”Create New nbsp; i className=”glyphicon glyphicon-plus”/i/Linktable className=”table table-responsive”thead tr thName/th thEmail/th thPhone Number/th thContact Address/th th/th /tr /thead tbody { this.props.users.map((user, index) = { return ( tr key={index+1} td{user.fullname}/td td{user.email}/td td{user.phone_number}/td td{user.contact_address}/td tdLink className=”btn btn-success btn-xs pull-left”i className=”glyphicon glyphicon-pencil”/i/Linkform id={“form_”+user.user_id} className=”pull-left” method=”post” input type=”hidden” name=”user_id” value={user.user_id} / a className=”btn btn-danger btn-xs” onClick={(event) = event)} href=”#” id={user.user_id}i className=”glyphicon glyphicon-trash”/i/a /form /td /tr ) }) } /tbody/table/div /div ); } }function mapStateToProps(state) { return { users: state.users.users, } } export default the code above, the Users component is connected to the redux store which has access to dispatch two actions which are fetchUsers, deleteUser in the userActions.js file.
  • This is the component for creating a new user.NewUser.jsimport React from ‘react’;import { push } from “react-router”;import axios from “axios”;import { NotificationManager } from ‘react-notifications’;class NewUser extends React.Component{static contextTypes = { router: };constructor(){ super();this.state = { errors: ” }; this.handleSubmit = this.handleSubmit.bind(this); }handleSubmit(event) { event.preventDefault();var formElement = var formData = new FormData(formElement); formData) .

This article is the concluding part of the series on React App With Laravel RESTful API Endpoint. Sorry for the delay of this much awaited post. In the previous article, I set up the react app with…

@ReactGuru: ReactJS App With Laravel RESTful API Endpoint Part 2 #redux

ReactJS App With Laravel RESTful API Endpoint Part 2

This article is the concluding part of the series on React App With Laravel RESTful API Endpoint. Sorry for the delay of this much awaited post.

In the previous article, I set up the react app with the Home Users and Articles pages. For this part, i would just be working on the CRUD operations on the users part of the system. This can be applied to the articles section for those who want to try it out. Before we start I want to explain a key technology i would be using in this project which is Redux.

Redux inspired by Facebook’s flux was created as an application’s state management tool. This maintains the state of an entire application in a single immutable state tree, which can’t be changed directly. You can visit http://redux.js.org/ to learn about Redux. So lets dive in

Step 1

Update the package.json file

package.json

“name”: “my-blog-reactapp”,

“version”: “0.0.0”,

“description”: “”,

“main”: “webpack.config.js”,

“dependencies”: {

“axios”: “^0.15.2”,

“babel-core”: “^6.17.0”,

“babel-loader”: “^6.2.0”,

“babel-plugin-add-module-exports”: “^0.1.2”,

“babel-plugin-react-html-attrs”: “^2.0.0”,

“babel-plugin-transform-class-properties”: “^6.3.13”,

“babel-plugin-transform-decorators-legacy”: “^1.3.4”,

“babel-preset-es2015”: “^6.3.13”,

“babel-preset-react”: “^6.3.13”,

“babel-preset-stage-0”: “^6.3.13”,

“flux”: “^3.1.0”,

“history”: “^4.4.0”,

“react”: “^15.0.2”,

“react-addons-css-transition-group”: “^15.4.2”,

“react-dom”: “^15.3.2”,

“react-notifications”: “^1.3.0”,

“react-redux”: “^5.0.3”,

“react-router”: “^3.0.0”,

“redux”: “^3.6.0”,

“redux-devtools”: “^3.3.2”,

“redux-devtools-extension”: “^2.13.0”,

“redux-logger”: “^2.8.2”,

“redux-promise”: “^0.5.3”,

“redux-thunk”: “^2.1.0”,

“webpack”: “^1.12.9”,

“webpack-dev-server”: “^1.16.2”

“devDependencies”: {

“font-awesome”: “^4.7.0”

“scripts”: {

“dev”: “webpack-dev-server”,

“test”: “echo \”Error: no test specified\” && exit 1″

“author”: “Adelekan David”,

“license”: “ISC”

Then from the terminal run

$ npm install

to update the dependencies needed for the project into a folder called node_modules.

Also inside the public/js/ folder, create a file called store.js,

store.js

import { createStore, applyMiddleware } from ‘redux’;

import { composeWithDevTools } from ‘redux-devtools-extension’;

import thunk from “redux-thunk”;

import promise from “redux-promise”;

import createLogger from ‘redux-logger’;

import reducer from “./reducers”;

const logger = createLogger();

export default createStore(reducer, composeWithDevTools(

applyMiddleware(thunk, promise, logger),

This file is the store that holds the application state and provides a few helper methods to access the state, dispatch actions and register listeners. The entire state is represented by a single store. Any action returns a new state via reducers. That makes Redux very simple and predictable. If redux chrome developers tools is installed on your browser, you can view the store and manage states in it.

Next we create the following files in the public/js/reducers folder

index.js

import { combineReducers } from “redux”

import users from “./UsersReducer”

export default combineReducers({

users

UsersReducer.js

export default function reducer(state={

users: [],

user: null,

fetched: false,

error: null

}, action){

switch (action.type){

case “FETCH_USERS_REJECTED”: {

return {

…state,

fetched: false,

error: action.payload

case “FETCH_USERS_FULFILLED”: {

return {

…state,

fetched: true,

users: action.payload.data.users,

case “FETCH_USER_REJECTED”: {

return {

…state,

fetched: false,

error: action.payload

case “FETCH_USER_FULFILLED”: {

return {

…state,

fetched: true,

user: action.payload

return state;

Next we update the app.js file in the public/js/ folder

app.js

import React from “react”;

import ReactDOM from “react-dom”;

import { Router, Route, IndexRoute, hashHistory } from “react-router”;

import { Provider } from “react-redux”;

import Layout from “./components/Layout”;

import Home from “./components/Home”;

import Users from “./components/Users”;

import NewUser from “./components/NewUser”;

import EditUser from “./components/EditUser”;

import Articles from “./components/Articles”;

import store from “./store”;

const app = document.getElementById(‘app’);

ReactDOM.render(

,

app);

Wrapping the router with a react-redux Provider component which would allow our React components to automatically share data and efficiently update whenever some action is triggered.

Step 1

Update the Users.js inside the public/js/components folder

Users.js

import React from ‘react’;

import { connect } from “react-redux”;

import { Link } from “react-router”

import { fetchUsers, deleteUser } from “./../actions/userActions”;

class Users extends React.Component{

constructor(){

super();

this.handleBtnDelete = this.handleBtnDelete.bind(this);

componentWillMount(){

this.props.dispatch(fetchUsers());

handleBtnDelete(id, event){

event.preventDefault();

var r = confirm(“Are you sure you want to delete this document!”);

if (r == true) {

const url = baseUrl+”/api/v1/users/delete”;

var formElement = document.getElementById(“form_”+id);

var formData = new FormData(formElement);

this.props.dispatch(deleteUser(formData));

render(){

return(

Users

Create New  

{ this.props.users.map((user, index) => {

return (

Name Email Phone Number Contact Address
{user.fullname} {user.email} {user.phone_number} {user.contact_address}

this.handleBtnDelete(user.user_id, event)} href=”#” id={user.user_id}>

function mapStateToProps(state) {

return {

users: state.users.users,

export default connect(mapStateToProps)(Users)

From the code above, the Users component is connected to the redux store which has access to dispatch two actions which are fetchUsers, deleteUser in the userActions.js file. Upon connecting the component to redux store, the state is then mapped to the props of the component, which enables us to access it. Next we create the userActions.js inside the public/js/actions folder

userActions.js

import axios from “axios”;

import { NotificationManager } from ‘react-notifications’;

export function fetchUsers(){

return function (dispatch) {

axios.get(baseUrl+”api/v1/users”)

.then((response) => {

dispatch({type: “FETCH_USERS_FULFILLED”, payload: response.data});

.catch((error) => {

dispatch({type: “FETCH_USERS_REJECTED”, payload: error});

export function fetchUser(id){

return function (dispatch) {

axios.get(baseUrl+”api/v1/users/”+id)

.then((response) => {

dispatch({type: “FETCH_USER_FULFILLED”, payload: response.data.user});

.catch((error) => {

dispatch({type: “FETCH_USER_REJECTED”, payload: error});

export function deleteUser(formData){

return function (dispatch) {

axios.post(baseUrl+”api/v1/users/delete”, formData)

.then((response) => {

NotificationManager.success(response.data.message, ‘Success’, 5000);

dispatch(fetchUsers());

.catch((error) => {

NotificationManager.error(“An error occured in the operation”, ‘Error’, 5000);

We are using a third party http library called Axios which is a promise-based HTTP client that works both in the browser and in a node.js environment. It basically provides a single API for dealing with XMLHttpRequests and node’s http interface. Besides that, it wraps the requests using a polyfill for ES6 new’s promise syntax. In this post we’ll see how to perform HTTP requests using axios.

Step 3

Create a file called NewUser.js inside the public/js/components folder. This is the component for creating a new user.

NewUser.js

import React from ‘react’;

import { push } from “react-router”;

import axios from “axios”;

import { NotificationManager } from ‘react-notifications’;

class NewUser extends React.Component{

static contextTypes = {

router: React.PropTypes.object.isRequired

constructor(){

super();

this.state = {

errors: ”

this.handleSubmit = this.handleSubmit.bind(this);

handleSubmit(event) {

event.preventDefault();

var formElement = document.querySelector(“form”);

var formData = new FormData(formElement);

axios.post(baseUrl+”api/v1/users/create”, formData)

.then((response) => {

this.context.router.push(‘/users’);

NotificationManager.success(‘User has been created!’, ‘Success’, 5000);

.catch((error) => {

var errors = error.response.data.data;

this.setState({

errors: errors

NotificationManager.error(‘Error occured during operation!’, ‘Error’, 5000);

createMarkup() {

return {__html: this.state.errors};

render(){

var errors = ”;

if(this.state.errors != ”){

errors =

ReactJS App With Laravel RESTful API Endpoint Part 2