Thursday, June 9, 2022

Difference between state and props in React




State is the local state of the component which cannot be accessed and modified outside of the component. It's equivalent to local variables in a function.

Plain JS Function

const DummyFunction = () => {
  let name = 'Manoj';
  console.log(`Hey ${name}`)
}

React Component

class DummyComponent extends React.Component {
  state = {
    name: 'Manoj'
  }
  render() {
    return <div>Hello {this.state.name}</div>;
  }

Props, on the other hand, make components reusable by giving components the ability to receive data from their parent component in the form of props. They are equivalent to function parameters.

Plain JS Function

const DummyFunction = (name) => {
  console.log(`Hey ${name}`)
}

// when using the function
DummyFunction('Manoj');
DummyFunction('Ajay');

React Component

class DummyComponent extends React.Component {
  render() {
    return <div>Hello {this.props.name}</div>;
  }

}

// when using the component
<DummyComponent name="Manoj" />
<DummyComponent name="Ajay" />

 

Tuesday, March 1, 2022

Redux


Reference:

https://redux.js.org/tutorials/essentials/part-1-overview-concepts

Redux is a pattern and library for managing and updating application state, using events called "actions". It serves as a centralized store for state that needs to be used across your entire application, with rules ensuring that the state can only be updated in a predictable fashion.

Redux is more useful when:

  • You have large amounts of application state that are needed in many places in the app
  • The app state is updated frequently over time
  • The logic to update that state may be complex
  • The app has a medium or large-sized codebase, and might be worked on by many people

Not all apps need Redux.

type and payload in Redux:

Payload is what is keyed ( the key value pairs ) in your actions and passed around between reducers in your redux application. For example -

const someAction = {
  type: "Test",
  payload: {user: "Test User", age: 25},
}

This is a generally accepted convention to have a type and a payload for an action. The payload can be any valid JS type ( array , object, etc ).

Reference:

https://stackoverflow.com/questions/51357412/what-is-a-payload-in-redux-context

 

 

 

super(props) in React



super(props) is a reference to the parents constructor() function, that's all it is. We have to add super(props) every single time we define a constructor() function inside a class-based component.

In JavaScript, super refers to the parent class constructor. (In our example, it points to the React.Component implementation.)

Importantly, you can’t use this in a constructor until after you’ve called the parent constructor. JavaScript won’t let you:

class Checkbox extends React.Component {
  constructor(props) {
    // 🔴 Can’t use `this` yet
    super(props);
    // ✅ Now it’s okay though
    this.state = { isOn: true };
  }
  // ...
}

 

React: connect(mapStateToProps, mapDispatchToProps)



For parent-child communication, simply pass props.

Use state to store the data your current page needs in your controller-view. 

Example

class DummyComponent extends React.Component {
  state = {
    name: 'Manoj'
  }
  render() {
    return <div>Hello {this.state.name}</div>;
  }

Use props to pass data & event handlers down to your child components. 

Example:

class DummyComponent extends React.Component {
  render() {
    return <div>Hello {this.props.name}</div>;
  }

}

// when using the component
<DummyComponent name="Manoj" />
<DummyComponent name="Ajay" />

 mapStateToProps is used for selecting the part of the data from the store that the connected component needs. The mapStateToProps function should always be written with at least state passed in.

Example:

function mapStateToProps(state) {
return {
a: 42,
todos: state.todos,
filter: state.visibilityFilter,
}
}

// component will receive: props.a, props.todos, and props.filter

 import { connect, Provider } from 'react-redux';
import store from '../../systems/redux/store';

  • By default, a connected component receives props.dispatch and can dispatch actions itself.
  • connect can accept an argument called mapDispatchToProps, which lets you create functions that dispatch when called, and pass those functions as props to your component.
render() {
return <button onClick={() => this.props.toggleTodo(this.props.todoId)} />
}

const mapDispatchToProps = dispatch => {
return {
toggleTodo: todoId => dispatch(toggleTodo(todoId))
}
}

 

react-redux is the library that is passing these methods to your component as props.

dispatch() is the method used to dispatch actions and trigger state changes to the store. react-redux is simply trying to give you convenient access to it.

React Redux includes a <Provider /> component, which makes the Redux store available to the rest of your app:

import React from 'react'
import ReactDOM from 'react-dom'

import { Provider } from 'react-redux'
import store from './store'

import App from './App'

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

 

useSelector reads a value from the store state and subscribes to updates, while useDispatch returns the store's dispatch method to let you dispatch actions.

import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import {
decrement,
increment,
incrementByAmount,
incrementAsync,
selectCount,
} from './counterSlice'
import styles from './Counter.module.css'

export function Counter() {
const count = useSelector(selectCount)
const dispatch = useDispatch()

return (
<div>
<div className={styles.row}>
<button
className={styles.button}
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
+
</button>
<span className={styles.value}>{count}</span>
<button
className={styles.button}
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
-
</button>
</div>
{/* omit additional rendering output here */}
</div>
)
}

render in React

We have

<body>
  <div id="root"></div>
</body>

In React
import React from 'react';

import { render } from 'react-dom';

class Welcome extends React.Component {
  constructor(props) {
super(props);
}
 
render() { return <h1>Hello, {this.props.name}</h1>; } }
if (document.getElementById('root')) { 
 ReactDOM.render(
   <Welcome name="John" />,
   document.getElementById('root')
 );

}

Wednesday, February 23, 2022

React



// This is a Class component
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
// This is a functional component
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
 
reference:
https://reactjs.org/docs/react-component.html 
https://medium.com/swlh/react-basics-components-and-the-importance-of-state-dd26250e88ce 
https://medium.com/weekly-webtips/react-basics-whats-the-difference-between-javascript-and-jsx-604dd224b1cf 

Friday, February 18, 2022

FormData() to create a new FormData object.



Reference:

https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData

 

Syntax:

new FormData(form) 
 
Example 1:
var formData = new FormData(); // Currently empty 
formData.append('username', 'Chris');  
 
Example 2:
 <form id="myForm" name="myForm">
  <div>
    <label for="username">Enter name:</label>
    <input type="text" id="username" name="username">
  </div>
  <div>
    <label for="useracc">Enter account number:</label>
    <input type="text" id="useracc" name="useracc">
  </div>
  <div>
    <label for="userfile">Upload file:</label>
    <input type="file" id="userfile" name="userfile">
  </div>
  <input type="submit" value="Submit!">
</form>
 let myForm = document.getElementById('myForm');
let formData = new FormData(myForm);

Wednesday, February 16, 2022

JS : insert an array into another using spread operator



The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected.

Example:

a2 = [21,22];
a1 = [1,2,...a2,3,4,5];//...a2 is use of spread operator
console.log(a1);

 Spread syntax (...)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

React, input validation




https://www.codegrepper.com/code-examples/javascript/input+field+validation+in+react+js

JavaScript Arrays and Associate Arrays



JavaScript Arrays:

Reference:

W3 School JS

https://www.w3schools.com/js/js_arrays.asp

W3 School React JS

https://www.w3schools.com/react/default.asp

Example 1:

const cars = [
  "Saab",
  "Volvo",
  "BMW"
];  

Example 2:

const cars = [];
cars[0]= "Saab";
cars[1]= "Volvo";
cars[2]= "BMW";
 

or 

let  cars = []; //variables defined with let/const cannot be Redeclared.

//Variables defined with let/const have Block Scope.

for example 


{
  let x = 2;
}
// x can NOT be used outside the scope

or

var  cars = [];

JavaScript  Associate Arrays/object

Reference:

https://flexiple.com/associative-array-javascript/ 

Example 1:

var arr = {key1:'value1', key2:'value2'};
access object properties:
arr.key1 or arr['key1'] 
Example 2:
var arr = {
    "Company Name": 'Flexiple',
    "ID": 123
};
for (var key in arr) {
    var value = arr[key];
    document.write(key + " = " + value + '
'); } //Output: Company Name = Flexiple ID = 123
 
 

 

Tuesday, February 15, 2022

ag-grid onCellClicked单击单元格事件



Reference:

https://www.itxst.com/ag-grid/ueui3ury.html

Example: in AG Grid:

             columnDefs: [
                { field: 'application_id', headerName: 'ID', editable: false, cellStyle: nonEditable, pinned: 'left', hide: true },
                { field: 'type', headerName: 'Fund Type', editable: false, cellStyle: nonEditable, },
        ],
 onCellClicked(params) {
 let action = params.event.target.dataset.action;

                    if (action === "delete") {
                        // params.api.applyTransaction({
                        //   remove: [params.node.data]
                        // });
                        params.context.componentParent.handleDel(params.data.application_id)
                    }

JS, fadeTo function



in React Function(id, msg)

    showFadingMsg = (id, msg) => {
        let fadingTime = 1500;
        if (id == 'fadingFail') {
            fadingTime = 2500;
        }
        this.setState({ [id]: msg })
        $('#' + id).show().fadeTo(500, 1);
        // Now set a timeout to hide it
        window.setTimeout(function () {
            $("#" + id).fadeTo(500, 0).slideUp(500, function () {
                $(this).hide();
            });
        }, fadingTime);
    }

 Here fadingTime = 5000 is in millisecond.
fadeTo(500, 1): here 1 is opacity, 500
is in millisecond: ie, time to show from opacity from 0 to 1.

Call this function in React

 this.showFadingMsg('fadingFail', 'Application update failed.')
 

Reference:

https://api.jquery.com/fadeto/


Thursday, February 10, 2022

AG Grid Cell Rendering




https://ag-grid.com/angular-data-grid/cell-rendering/ 

 http://54.222.217.254/javascript-grid-components/

You can also refer to the component classes directly using the framework variant of the property. For example instead of using cellRenderer you use cellRendererFramework

 

Wednesday, February 9, 2022

jQuery filter/search function in table




https://www.w3schools.com/bootstrap/bootstrap_filters.asp# 

<script>
$(document).ready(function(){
  $("#myInput").on("keyup", function() {
    var value = $(this).val().toLowerCase();
    $("#myTable tr").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
    });
  });
});
</script>

 

Sticky header using Bootstrap Affix



https://www.w3schools.com/bootstrap/bootstrap_affix.asp

<nav class="navbar navbar-inverse" data-spy="affix" data-offset-top="197">
  <ul class="nav navbar-nav">
    <li class="active"><a href="#">Basic Topnav</a></li>
    <li><a href="#">Page 1</a></li>
    <li><a href="#">Page 2</a></li>
    <li><a href="#">Page 3</a></li>
  </ul>
</nav>

Add data-spy="affix" to the element you want affixed.

Optionally, add the data-offset-top|bottom attribute to calculate the position of the scroll.

 

Tuesday, February 8, 2022

React/Laravel: design header

We can use views to store header and footer (used in current coding)

resources/views/templates/

In resources/views/templates/view_layout.blade.php

        @include('templates.header_primary_menu')
        @include('templates.header_sub_menu')
we have header_primary_menu.blade.php and  header_sub_menu.blade.php under

/views/templates/

Bootstrap dropdown menu:

https://getbootstrap.com/docs/4.0/components/dropdowns/ 

<div class="dropdown show">
  <a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Dropdown link
  </a>

  <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
    <a class="dropdown-item" href="#">Action</a>
    <a class="dropdown-item" href="#">Another action</a>
    <a class="dropdown-item" href="#">Something else here</a>
  </div>
</div>

 data-toggle="collapse" to show/hide text

https://getbootstrap.com/docs/4.0/components/collapse/ 

<p>
  <a class="btn btn-primary" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
    Link with href
  </a>
  <button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
    Button with data-target
  </button>
</p>
<div class="collapse" id="collapseExample">
  <div class="card card-body">
    Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
  </div>
</div>

 

data-toggle dropdown

https://www.w3schools.com/bootstrap/bootstrap_dropdowns.asp

<div class="dropdown">
  <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
  <span class="caret"></span></button>
  <ul class="dropdown-menu">
    <li><a href="#">HTML</a></li>
    <li><a href="#">CSS</a></li>
    <li><a href="#">JavaScript</a></li>
  </ul>
</div>

 

The .dropdown class indicates a dropdown menu.

To open the dropdown menu, use a button or a link with a class of .dropdown-toggle and the data-toggle="dropdown" attribute.

The .caret class creates a caret arrow icon (), which indicates that the button is a dropdown.

Add the .dropdown-menu class to a <ul> element to actually build the dropdown menu.

or we can use React

resources/js/components/Header.js

import React, {useRef} from 'react';
import { BrowserRouter as Router, Link, Route } from 'react-router-dom';
import { makeStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import IconButton from '@material-ui/core/IconButton';
import Button from '@material-ui/core/Button';
import Badge from '@material-ui/core/Badge';
import MenuItem from '@material-ui/core/MenuItem';
import Menu from '@material-ui/core/Menu';
import AccountCircle from '@material-ui/icons/AccountCircle';
import ContactSupportIcon from '@material-ui/icons/ContactSupport';
import NotificationsIcon from '@material-ui/icons/Notifications';
import MoreIcon from '@material-ui/icons/MoreVert';
import { connect } from 'react-redux';


import UserGuide from '../systems/UserGuide';


Laravel: get enum values of a column in MySQL table



    public function get_enum_values($table, $field){
        $enum = [];
        $test=DB::select(DB::raw("show columns from {$table} where field = '{$field}'"));
        if(!empty($test)){
            preg_match('/^enum\((.*)\)$/', $test[0]->Type, $matches);
            foreach( explode(',', $matches[1]) as $value )
            {
                $enum[] = trim( $value, "'" );
            }
        }
        return $enum;
    }

Laravel: Send Email



            $data = array(
                'userName' => $userName,
                'from' => $from,
                'to' => $to,
                'cc' => $cc,
                'bcc' => $bcc,
                'subject' => $subject,
                'content' => nl2br($content)
            );
            array_unique($bcc);
            Mail::send([], $data, function($message) use($data) {
                $message->to($data['to'])->subject($data['subject']);
                if($data['cc'] && is_array($data['cc']) && count($data['cc'])>0){
                    foreach($data['cc'] as $b){
                        $message->cc($b);
                    }
                }
                if($data['bcc'] && is_array($data['bcc']) && count($data['bcc'])>0){
                    foreach($data['bcc'] as $b){
                        $message->bcc($b);
                    }
                }
                $message->from($data['from'], $data['userName']);
                $message->setBody($data['content'],'text/html');
            });

Thursday, February 3, 2022

Update PHP 7.4 to PHP 8.1 in CENTOS Server



1) php -v
PHP 7.4.27 (cli) (built: Dec 14 2021 17:17:06) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies

2) sudo sed -i -e '/\[remi-php81\]/,/^\[/s/enabled=0/enabled=1/' /etc/yum.repos.d/remi-php81.repo

3) sudo yum -y --enablerepo=remi-php81 install php php-common php-gd php-mbstring php-xml php-mysqlnd php-pdo php-devel php-pear php-soap php-pecl-zip php-pecl-mcrypt

4)php -v
PHP Warning:  PHP Startup: ibm_db2: Unable to initialize module
Module compiled with module API=20190902
PHP    compiled with module API=20210902
These options need to match
 in Unknown on line 0
PHP 8.1.1 (cli) (built: Dec 15 2021 02:00:45) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.1.1, Copyright (c) Zend Technologies

5) As I used  PHP ibm_db2 module, I need to compile it again

wget https://pecl.php.net/get/ibm_db2-2.1.5.tgz
tar -xzvf ibm_db2-2.1.5.tgz
cd ibm_db2-2.1.5
phpize --clean
phpize
sudo ./configure --with-IBM_DB2=/opt/ibm/db2/V10.5
sudo make
sudo make install

6) $ php -v
PHP 8.1.1 (cli) (built: Dec 15 2021 02:00:45) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.1.1, Copyright (c) Zend Technologies
    with Xdebug v3.1.2, Copyright (c) 2002-2021, by Derick Rethans

Code update from PHP 7.4 to PHP 8.1 - Session_database_driver.php in CodeIgniter 3



system/libraries/Session/drivers/Session_database_driver.php 

Reference

https://github.com/bcit-ci/CodeIgniter/pull/6078/files

Severity: 8192

Message: Return type of CI_Session_database_driver::open($save_path, $name) should either be compatible with SessionHandlerInterface::open(string $path, string $name): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice

Filename: drivers/Session_database_driver.php

Line Number: 129

line 129 change

      public function open($save_path, $name)

to
        public function open(string $save_path, string $name): bool

line 282 change

      public function close()

to
      public function close(): bool

line 154 change

        public function read($session_id)

to

// the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice

     #[\ReturnTypeWillChange]
        public function read(string $session_id)

line 214

change

       public function write($session_id, $session_data)

to
        public function write(string $session_id, string $session_data): bool

line 307 change

      public function destroy($session_id)

to
        public function destroy(string $session_id): bool

line 347 change


         public function gc($maxlifetime)

to
        #[\ReturnTypeWillChange]
        public function gc(int $maxlifetime)

 

npm install jquery-ui-dist



 sudo npm install jquery-ui-dist

will install latest jquery-ui-dist and update package.json.

We can also update 

   "jquery": "^3.6.0",
in package.json and run

sudo npm run update

Example of package.json:

 {
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mode=development",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod_build": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --config=node_modules/laravel-mix/setup/webpack.config.js --env.mode=production"
    },
    "devDependencies": {
        "@babel/preset-react": "^7.12.10",
        "@material-ui/core": "^4.11.3",
        "@material-ui/icons": "^4.11.2",
        "axios": "^0.21.1",
        "bootstrap": "^4.6.0",
        "cross-env": "^7.0.3",
        "focus-trap-react": "^8.4.2",
        "jquery": "^3.6.0",
        "laravel-mix": "^5.0.9",
        "lodash": "^4.17.21",
        "mui-datatables": "^3.7.6",
        "popper.js": "^1.16.1",
        "react": "^17.0.1",
        "react-bootstrap": "^1.5.0",
        "react-dom": "^17.0.1",
        "react-table": "^7.6.3",
        "resolve-url-loader": "^3.1.2",
        "sass": "^1.30.0",
        "sass-loader": "^10.1.0",
        "vue-template-compiler": "^2.6.12"
    },
   "dependencies": {
        "@babel/plugin-proposal-class-properties": "^7.12.1",
        "@codewell/super-search": "^1.0.0",
        "@date-io/date-fns": "^1.3.13",
        "@material-ui/lab": "^4.0.0-alpha.58",
        "@material-ui/pickers": "^3.2.10",
        "@popperjs/core": "^2.6.0",
        "@react-pdf/renderer": "^2.0.19",
        "@react-pdf/stylesheet": "^2.0.11",
        "ag-grid-community": "^25.3.0",
        "ag-grid-enterprise": "^25.3.0",
        "ag-grid-react": "^25.3.0",
        "autoprefixer": "^9.8.6",
        "date-fns": "^2.16.1",
        "jquery-ui": "^1.12.1",
        "jquery-ui-dist": "^1.13.0",
        "jspdf": "^2.3.1",
        "jspdf-autotable": "^3.5.14",
        "material-design-iconic-font": "^2.2.0",
        "minimist": "^1.2.5",
        "moment": "^2.29.1",
        "npm": "^6.14.10",
        "pdfmake": "^0.2.0",
        "postcss": "^7.0.35",
        "react-autocomplete": "^1.8.1",
        "react-bootstrap-typeahead": "^5.1.4",
        "react-csv": "^2.0.3",
        "react-fast-compare": "^3.2.0",
        "react-hook-form": "^7.12.2",

        "react-hook-form-input": "^1.1.10",
        "react-html-parser": "^2.0.2",
        "react-loader-advanced": "^1.7.1",
        "react-multiselect-checkboxes": "^0.1.1",
        "react-pdf": "^5.3.2",
        "react-pdf-scroll": "^1.0.0",
        "react-redux": "^7.2.2",
        "react-router-dom": "^5.2.0",
        "react-select": "^3.1.1",
        "react-waypoint": "^10.1.0",
        "reactstrap": "^8.9.0",
        "redux": "^4.0.5",
        "redux-thunk": "^2.3.0",
        "sweetalert2": "^10.12.6",
        "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.3",
        "validator": "^13.5.2"
    }
}