create-reactjs-application-with-laravel-api

create reactjs application with laravel api

Hello World, Today i am going to create reactjs application with laravel api from scratch. In this application, we will fetch data from database with laravel resource api and show in reactjs application. In this tutorial, I have created two different application one is in laravel and other is in reactjs and then we have connected these both with api.

Laravel

  • Install Laravel
  • Create product model and migration
  • Generate dummy data
  • Create Product resource
  • Route for api request
  • Test our application


Install Laravel

Please follow the tutorial to install and create your first laravel application.


Create product model and migration

In this step, we will create product model and migration. Please enter the following command to create model and migration.

php artisan make:model Product -m

-m flag will create product migration.

  • Open this newly created /database/migrations/…product.php/ file and add following code in up method.
Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->mediumText('summery');
            $table->string('image');
            $table->tinyInteger('price');
            $table->timestamps();
        });
  • Enter the following command to migrate the table.
php artisan migrate

Generate dummy data

In this step, we will generate dummy data for products table. Open the following file.

  • /database/factories/UserFactory.php
  • Add the following code at the end.
  • // Generate Products
    $factory->define(App\Product::class, function (Faker $faker) {
        return [
            'title' => $faker->name,
            'summery' => $faker->text(50),
            'image' => $faker->image('public/imgs',300,300,'technics',false),
            'price' => $faker->randomDigit(),
        ];
    });
  • Open the command line and add the following commands to generate dummy content.
  • php artisan tinker
    factory(App\Product::class,10)->create();

Create Product resource

In this step,we will create our product model resource. This resource is middle layer between model and route.

  • Open the command line and enter the following command to create resource.
php artisan make:resource Product
  • Resource has been created in /app/Http/Resource/Product.php

Route for api request

We will define all our resource routes in  routes/api.php. The main difference between web.php and api.php route is that api.php routes are stateless.

  • Open this file and add the following code.
Route::get('/products','ProductController@all_products');
Route::get('/product-detail/{id}','ProductController@single_product');
Route::get('/search-products/{string}','ProductController@search_product');

Test our api

Open the api url in browser. In my case i will open http://localhost/laravel-apps/public/api/products.

If all things will right then you can see the data in json format. following screenshot is the example.

json-api-screenshot


Install reactJs

Please follow the tutorial to install and create your first reactjs application.


Project Configuration

Open /index.js file and include ProductList (Later we will create this component) component.


Url Routing

For routing we have used “react-router-dom” package. This package make our application to single page application.


Create Components

  • ProductList.js

This component will wrap up our application. In this component we have added our header and main component.

import React from 'react';
import {BrowserRouter} from 'react-router-dom';
import Header from './Header.js';
import Main from './Main.js';
class ProductList extends React.Component{
  render(){
    return(
      <BrowserRouter>
      <>
        <Header />
        <Main />
      </>
      </BrowserRouter>
    )
  }
}
export default ProductList;
  • Header.js
import React from 'react';
import {Link} from 'react-router-dom';
function Header(){
    return (
        <nav className="navbar navbar-expand-lg navbar-dark bg-dark">
            <div className="container">
                <Link to="/">Home</Link>
                <Link to="/categories">Categories</Link>
            </div>
        </nav>
    );
}
export default Header;
  • Main.js
import React from 'react';
import {Switch,Route} from 'react-router-dom';
// Import Other Components
import Home from './Home.js';
import SingleProduct from './SingleProduct.js';
function Main(){
    return (
        <>
            <main>
                <Switch>
                    <Route path="/" exact component={Home} />
                    <Route path="/product-detail/:id" component={SingleProduct} />
                </Switch>
            </main>
        </>
    );
}
export default SingleProduct;
  • Home.js
import React from 'react';
import {Link} from 'react-router-dom';
class Home extends React.Component{
    constructor(){
        super();
        this.state={
            products:[],
            loading:true,
            limit:12,
            currentPage:0
        }
        this.handleKeyUp = this.handleKeyUp.bind(this);
    }

    handleKeyUp(e){
        if(e.target.value!=''){
            fetch('http://localhost/laravel-apps/laravelArticles/public/api/search-products/'+e.target.value)
            .then(response=>response.json())
            .then(json=>
                this.setState({
                    products:json.data,
                    loading:false
                })
            );
        }else{
            fetch('http://localhost/laravel-apps/laravelArticles/public/api/products')
            .then(response=>response.json())
            .then(json=>
                this.setState({
                    products:json.data,
                    loading:false
                })
            );
        }
    }

    componentDidMount(){
        fetch('http://localhost/laravel-apps/laravelArticles/public/api/products')
        .then(response=>response.json())
        .then(json=>
            this.setState({
                products:json.data,
                loading:false
            })
        );
    }

    render(){
        let data;
        if(this.state.loading){
            data=<div className="container mt-4"><p>Loading...</p></div>
        }else{
            data=<div className="container">
                    <input type="text" className="form-control mt-4" onKeyUp={this.handleKeyUp} placeholder="Type Product Name" />
                    <div className="row mt-4">
                        {this.state.products.map((product,index)=>(
                        <div className="col-4 mb-3" key={product.id}>
                            <div className="card">
                                
                                <div className="card-body">
                                    <h5 className="card-title">{product.title}</h5>
                                    <p className="card-text">{product.summery}</p>
                                    <Link to={`product-detail/${post.id}`} className="btn btn-primary">Read More</Link>
                                </div>
                            </div>
                        </div>
                        ))}
                    </div>
                </div>
        }
        return(
            <>
                {data}
            </>
        );
    }
}
export default Home;
  • SingleProduct.js
import React, { Component } from 'react';
class SingleProduct extends Component {
    constructor(){
        super();
        this.state={
            singleProduct:'',
            loading:true
        }
    }

    componentDidMount(){
        fetch('http://localhost/laravel-apps/laravelArticles/public/api/product-detail/'+this.props.match.params.id)
        .then(response => response.json())
        .then(json => 
            this.setState({
                singleProduct:json.data,
                loading:false
            })    
        );
    }

    render() {
        let data;
        if(this.state.loading){
            data=<div className="container mt-4"><p>Loading...</p></div>
        }else{
            data=<div className="container">
                    <div className="row mt-4">
                        <div className="col-4 mb-3">
                            <div className="card">
                                <img src={`http://localhost/laravel-apps/laravelArticles/public/imgs/${this.state.singlePost.image}`} className="card-img-top" />
                                <div className="card-body">
                                    <h5 className="card-title">{this.state.singlePost.title}</h5>
                                    <p className="card-text">{this.state.singlePost.summery}</p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
        }
        return(
            <>
                {data}
            </>
        );
    }
}
export default SingleProduct;

Fetch product data with api request

In “Home” component, you can see that we are fetching data from url in “componentDidMount” function. This is reactjs application life cycle method.There are various method in lifecycle for different purpose. ComponentDidMount function will react only when all data has been loaded. Here we are using “fetch” api. There are other things that we are doing here, We are showing loader when data is in loading process then hide that loading in componentDidMount. “setState” object is very important here, this contains all of your data. This is normal object same like as other object in javascript but the only difference is it will load its data automatically when it change.


Run project

For running reactjs application, Go to application folder and run the following command.

npm start

It will run the project in http://localhost:3000 url.

Leave a Reply