Thursday, January 2, 2020

Using Google Place Autocomplete API in React

I want to have an auto completing location search bar in my react component
Reference Google Maps API JS library via /public/index.html file:
Get google API Key from here -> https://developers.google.com/places/web-service/get-api-key
https://cloud.google.com/console/google/maps-apis/overview
You need to enable Maps JavaScript API & Places Api from below links ->
https://console.developers.google.com/google/maps-apis/apis/maps-backend.googleapis.com

https://console.developers.google.com/google/maps-apis/apis/places-backend.googleapis.com

import React from "react";

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.autocompleteInput = React.createRef();
    this.autocomplete = null;
    this.handlePlaceChanged = this.handlePlaceChanged.bind(this);
  }

  componentDidMount() {
    this.autocomplete = new google.maps.places.Autocomplete(
        this.autocompleteInput.current, {"types": ["geocode"]}
    );

    this.autocomplete.addListener('place_changed', this.handlePlaceChanged);
  }

  handlePlaceChanged(){
    const place = this.autocomplete.getPlace();
    this.props.onPlaceLoaded(place);
  }



  render() {
    return (
        <input ref={this.autocompleteInput}  id="autocomplete" 
         placeholder="Enter your address"
         type="text"></input>
    );
  }
}

export default MyComponent

Wednesday, January 1, 2020

bootstrap-datepicker with React: onChange doesn't fire while onClick does

bootstrap-datepicker with React: onChange doesn't fire while onClick does
import React, { Component } from 'react'
import {Redirect} from "react-router-dom";

class MyComponent extends Component {
    constructor () {
        super();
        this.state = {
     back: false,
            dateOfBirth: "",
            dateOfBirthInput: ""
        };
        this.handleUserInput = this.handleUserInput.bind(this);
    }

    componentDidMount () {
        super.componentDidMount();

        $(this.state.dateOfBirthInput).datepicker({
     format: "mm/dd/yyyy"
 });

        $(this.state.dateOfBirthInput).on('changeDate', function(e) {
            console.log(e);
            console.log(e.target.value);
     this.handleUserInput(e);
        })
    }

    handleUserInput (e) {
        let name = e.target.name;
        let value = e.target.value;

        console.log(`Name=${name}, value=${value}`);

        this.setState({[name]: value});
    }

    render () {
        if (this.state.back) {
            return <Redirect to={'/dashboard/user-profile'} push={true}/>
        }
        return (
            <div>
                <div className="form-group row">
                    <label className={'col-12 col-sm-12 col-md-4 col-lg-3 col-xl-2 col-form-label'}>Date of birth</label>
                    <div className="col-12 col-sm-12 col-md-8 col-lg-9 col-xl-10">
                        <div className='input-group date'>
                            <input name={'dateOfBirth'} value={this.state.dateOfBirth}
                                   onChange={(e) => this.handleUserInput(e)}
                                   ref={(n) => this.state.dateOfBirthInput = n}
                                   type='text' className="form-control"/>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

export default MyComponent

Saturday, December 28, 2019

Implementing Programically Redirect With React Router | React redirect to component | Redirect with React Router

A lot of these short blog posts are just for me to find later when I forget how to do something.
So, there is an span where there is a click event named goToAnotherPage, when clicked I just set state the edit variable true, and it redirect to another page using react component named Redirect as described in function goToAnotherPage.
import React, { Component } from 'react'
import {Redirect} from 'react-router-dom'

class SomePage extends Component {
    constructor () {
        super();
        this.state = {
            edit: false
        };
        this.goToAnotherPage = this.goToAnotherPage.bind(this);
    }

    componentDidMount () {
        super.componentDidMount();
    }

    goToAnotherPage(e) {
        this.setState({'edit': true});
    }

    render () {
        if (this.state.edit) {
            return <Redirect to={'/go-to-another-page'} push={true}/>
        }
        return (
            <span onClick={(e) => this.goToAnotherPage(e)}>Go to another page</span>
        )
    }
}

export default SomePage

Friday, December 27, 2019

Htaccess | what does $1 in .htaccess file mean | Check if file exists in subdirectory

$1 is the first captured group from your regular expression; that is, the contents between ( and ). If you had a second set of parentheses in your regex, $2 would contain the contents of those parens and so on. Here is an example:
RewriteRule (js|css|img)/(.*?).(js|css|jpg|jpeg|png|ttf)$ public/$1/$2.$3 [NC,L,QSA]
Will served files as below:

js/app.js will be served from public/js/app.js

css/main.css will be served from public/css/main.css

Laravel 5 | Start Session Manually | Dynamically Set Session Id on Creating Session | Extending the StartSession Middleware | Session Handler Extending

Its really easy using the middleware in Laravel 5, I needed any request with an API key not to have a session and I simply did :
For this case you can create a StartSession middleware for your application that extends the Illuminate and need to override few methods to manage as you want.

<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Session\Middleware\StartSession as BaseStartSession;

class StartSession extends BaseStartSession
{

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return parent::handle($request, $next);
    }

    /**
     * Get the session implementation from the manager.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Contracts\Session\Session
     */
    public function getSession(Request $request)
    {
        return tap($this->manager->driver(), function (\Illuminate\Contracts\Session\Session $session) use ($request) {
            // getting session id from request
            // then using the same id for session
            $token = request()->header("token", null);
            if (is_null($token)) {
                $token = "custom" . \Str::random(34);
            }

            $session->setId($token);
        });
    }

    /**
     * Start the session for the given request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Contracts\Session\Session
     */
    protected function startSession(Request $request)
    {
        return tap($this->getSession($request), function (\Illuminate\Contracts\Session\Session $session) use ($request) {
            $session->setRequestOnHandler($request);

            $session->start();
        });
    }
}
Now need to replace session middleware in kernel file: app\Http\Kernel.php as below:

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\TrustProxies::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \App\Http\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            \App\Http\Middleware\StartSession::class,
            'throttle:60,1',
            'bindings',
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];

    /**
     * The priority-sorted list of middleware.
     *
     * This forces non-global middleware to always be in the given order.
     *
     * @var array
     */
    protected $middlewarePriority = [
        \App\Http\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\Authenticate::class,
        \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \Illuminate\Auth\Middleware\Authorize::class,
    ];
}

Thursday, December 19, 2019

ReactJS - Multiple Layout In React Using React Router | Using multiple layouts for react-router components

React Router is a standard routing library for React.
In the first step, we will create two different layout files (named CommonLayout and DashboardLayout) and their respective routes to implement multiple layouts in React.

CommonLayout


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

class CommonLayoutComponent extends React.Component{
    constructor(props){
        super(props);
        this.createRef = this.createRef.bind(this);
    }

    createRef(element) {
        console.log(element);
    }

    render() {
        return (
            <div key="dashboard">
                <div className="Content" ref={this.createRef}>
                    {this.props.children}
                </div>
            </div>
        );
    }
}

const CommonLayoutRoute = ({component: Component, ...rest}) => {
    return (
        <Route {...rest} render={matchProps => (
            <CommonLayoutComponent {...matchProps}>
                <Component {...matchProps} />
            </CommonLayoutComponent>
        )} />
    )
};

export default CommonLayoutRoute;

DashboardLayout


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

const DashboardLayoutRoute = ({component: Component, ...rest}) => {
    return (
        <Route {...rest} render={matchProps => (
            <div>
                <h3>Dashboard Layout</h3>
                <Component {...matchProps} />
            </div>
        )} />
    )
};

export default DashboardLayoutRoute;
Now, update your App.js file to use both - the layout and the component - as below.
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom';

/** Layouts **/
import CommonLayoutRoute from "./CommonLayoutRoute";
import DashboardLayoutRoute from "./DashboardLayout";

/** Components **/
import LayoutPage1 from './LayoutPage1';
import LayoutPage2 from './LayoutPage2'

/*
   App
 */
class App extends Component {
    render() {
        return (
            <Router>
                <Switch>
                    <Route exact path="/">
                        <Redirect to="/layout1" />
                    </Route>
                    <CommonLayoutRoute path="/layout1" component={LayoutPage1} />
                    <DashboardRoute path="/layout2" component={LayoutPage2} />
                </Switch>
            </Router>
        );
    }
}

export default App;
Here, we have updated the App.js file as defined in the route. When we route to /layout1, then CommonLayoutRoute (our first layout) will be used as the master page for the component LayoutPage1. On the other hand, when we route to /layout2, then our second layout, i.e., DashbaordLayoutRoute will be used as the master page for the component LayoutPage2.

Wednesday, December 18, 2019

ReactJS - Preventing Form Submission

I've been experimenting with React. In my experiement, I'm using the React framework. When I click a button, I've noticed that the HTML form submits. Is there a way to prevent form submission when a button is clicked? Just need to add the following attribute to the form.

<form onSubmit={(e) => e.preventDefault()}>


</form>