In order to execute a function from a layout / component, you will need to pass component / layout reference to other side. React supports a special attribute that you can attach to any component, pass reference to other side, and you can access the functions of the component in the layout accessing |
Sample App.js |
import React, { Suspense, lazy } from "react"; import { BrowserRouter, Switch } from "react-router-dom"; import DashboardLayoutRoute from "./DashboardLayout"; import Home from "./Home"; const Connections = lazy(() => import("./Connections")); class App extends React.Component { constructor() { super(); console.log("App Initialized"); } render() { return ( <BrowserRouter basename={this.APP_PATH}> <Switch> <DashboardLayoutRoute exact path="/" component={Home} /> </Switch> <Suspense fallback={<div>Loading...</div>}> <Switch> <DashboardLayoutRoute path="/connections" component={Connections} /> </Switch> </Suspense> </BrowserRouter> ); } } export default App; |
Sample Layout |
import React from "react"; import { Route } from "react-router-dom"; class DashboardLayoutComponent extends React.Component { constructor(props) { super(props); this.callBackToComponent = this.callBackToComponent.bind(this); } componentDidMount() { console.log("Layout Component Did Mount"); let _this = this; if (this.props.children.type._result instanceof Promise) { this.props.children.type._result.then(function(data) { _this.callBackToComponent(); }); } else { this.callBackToComponent(); } } componentDidUpdate() { console.log("Layout Component Did Update"); let _this = this; if (this.props.children.type._result instanceof Promise) { this.props.children.type._result.then(function(data) { _this.callBackToComponent(); }); } else { this.callBackToComponent(); } } callBackToComponent() { let t = this.props.children.type; if (t.prototype !== undefined) { t.prototype.callBackToParentComponent(this); } else { // If you use your Route in Suspense t._result.prototype.callBackToParentComponent(this); } } callbackParent() { console.log("Layout function called from some component"); } render() { return ( <div className={"dashboard-main-container"}> <div className="container"> <div className="row"> <div className="col-sm-10 right-body-container"> {this.props.children} </div> </div> </div> </div> ); } } const DashboardLayoutRoute = ({ component: Component, ...rest }) => { return ( <Route {...rest} render={matchProps => ( <DashboardLayoutComponent {...matchProps}> <Component key={matchProps.match.params.id} {...matchProps} /> </DashboardLayoutComponent> )} /> ); }; export default DashboardLayoutRoute; |
Sample Component |
import React from "react"; import { Link } from "react-router-dom"; class Connections extends React.Component { constructor() { super(); console.log("Connections"); } // this function will be called from layout function with self reference // so calling [layout.callbackParent()] will call a function inside layout component itself callBackToParentComponent(layout) { console.log("callBackToParentComponent for Connections"); layout.callbackParent(); } render() { return ( <div> <h1>Connections</h1> <Link to={"/"}>Home</Link> </div> ); } } export default Connections; |
Sample console.log |
App Initialized App Initialized Layout Component Did Mount callBackToParentComponent for Connections Layout function called from some component Connections Connections Home Home Layout Component Did Mount callBackToParentComponent for Home Layout function called from some component Connections Connections Layout Component Did Mount callBackToParentComponent for Connections Layout function called from some component |
Sample Output: |
Live Example At codesandbox.io: https://codesandbox.io/s/reactjs-call-methods-functions-between-component-and-layout-fydou |
Thursday, February 20, 2020
ReactJS Call Methods / Functions Between Component And Layout
Sunday, February 16, 2020
PHP - Encryption and Decryption of Large Files with OpenSSL
PHP lacks a build-in function to encrypt and decrypt large files. openssl_encrypt can be used to encrypt strings, but loading a huge file into memory is a bad idea.
This example uses the symmetric AES-256-CBC algorithm to encrypt smaller chunks of a large file and writes them into another file. |
<?php define('FILE_ENCRYPTION_BLOCKS', 10000); /** * Encrypt the passed file and saves the result in a new file with ".enc" as suffix. * * @param string $source Path to file that should be encrypted * @param string $key The key used for the encryption * @param string $dest File name where the encryped file should be written to. * @return string|false Returns the file name that has been created or FALSE if an error occured */ function encryptFile($source, $key, $dest) { $key = substr(sha1($key, true), 0, 16); $iv = openssl_random_pseudo_bytes(16); $error = false; if ($fpOut = fopen($dest, 'w')) { // Put the initialzation vector to the beginning of the file fwrite($fpOut, $iv); if ($fpIn = fopen($source, 'rb')) { while (!feof($fpIn)) { $plaintext = fread($fpIn, 16 * FILE_ENCRYPTION_BLOCKS); $ciphertext = openssl_encrypt($plaintext, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv); // Use the first 16 bytes of the ciphertext as the next initialization vector $iv = substr($ciphertext, 0, 16); fwrite($fpOut, $ciphertext); } fclose($fpIn); } else { $error = true; } fclose($fpOut); } else { $error = true; } return $error ? null : $dest; } /** * Dencrypt the passed file and saves the result in a new file, removing the * last 4 characters from file name. * * @param string $source Path to file that should be decrypted * @param string $key The key used for the decryption (must be the same as for encryption) * @param string $dest File name where the decryped file should be written to. * @return string|false Returns the file name that has been created or FALSE if an error occured */ function decryptFile($source, $key, $dest) { $key = substr(sha1($key, true), 0, 16); $error = false; if ($fpOut = fopen($dest, 'w')) { if ($fpIn = fopen($source, 'rb')) { // Get the initialzation vector from the beginning of the file $iv = fread($fpIn, 16); while (!feof($fpIn)) { $ciphertext = fread($fpIn, 16 * (FILE_ENCRYPTION_BLOCKS + 1)); // we have to read one block more for decrypting than for encrypting $plaintext = openssl_decrypt($ciphertext, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv); // Use the first 16 bytes of the ciphertext as the next initialization vector $iv = substr($ciphertext, 0, 16); fwrite($fpOut, $plaintext); } fclose($fpIn); } else { $error = true; } fclose($fpOut); } else { $error = true; } return $error ? null : $dest; } $key = 'my secret key'; $fileName = __DIR__ . '/testfile.txt'; file_put_contents($fileName, 'File would be encrypted...'); $result = encryptFile($fileName, $key, $fileName . '.enc'); if ($result) { echo "FILE ENCRYPTED TO " . $result; $result = decryptFile($result, $key, $fileName . '.dec'); if ($result) { echo "<BR>FILE DECRYPTED TO " . $result; } } ?> |
Saturday, February 15, 2020
How to write a simple React plugin, publish it to npm, and deploy it to Github pages
Getting startedOur target is to create and publish a ReactJS plugin so we can access it via NPM directly. I'm going to creat react plugin using create-react-library which is a CLI for easily creating reusable react libraries. This CLI has a bunch of features and will help us in generating a full featured project as well as plugin. To use create-react-library, we’ll need to install it globally: npm install -g create-react-libraryThe above command will install create-react-library globally and we can generate a new module from any directory. Now execute following command to create an module which will ask you some basic questions about your plugin and will take few minutes to complete installation of reactjs plugin: create-react-library |
After plugin project created navigate to project directory using cd react-profile-image-boxNow, you need to run the plugin (for watching any changes that you make to it) and the example. In one tab, you can run: npm startAnd, in another tab, you need to run the example app: cd ./example && npm startThe last command will run a create-react-app project which imports your plugin. If you make any changes to your plugin, it will get reflected in the example app. You can view the current status of your plugin by visiting http://localhost:3000. |
import React, { Component } from 'react' import PropTypes from 'prop-types' import styles from './styles.css' export default class ProfileImageBox extends Component { /** * src: The src for img tag * alt: Alt text for img tag * allowUpload: Boolean field to set if image can be changed or not * onFileChange: A function that will receive file change event */ static propTypes = { src: PropTypes.string, alt: PropTypes.string, allowUpload: PropTypes.bool, onFileChange: PropTypes.func } static defaultProps = { allowUpload: false, onFileChange: function(e, additionalParams) { alert("You need to implement onFileChange(e) method") } } constructor (props) { super(props) } render() { const { src, alt, allowUpload, onFileChange } = this.props return ( <div className={styles.react_profile_image_box_container}> {allowUpload ? (<input className={styles.react_profile_image_box_upload_profile_image_input} onChange={(e) => onFileChange(e)} type="file"/>) : ''} <img className={styles.react_profile_image_box_rounded_circle} alt={alt} src={src} data-holder-rendered="true"/> </div> ) } } |
You should use above plugin as below: |
import React, { Component } from 'react' import ProfileImageBox from 'react-profile-image-box' export default class App extends Component { state = { src: "http://test.com/avatar_images_by_user/72" } onFileChange(e, additionalParams) { console.log(e.target.files); console.log(additionalParams); this.setState({src: "http://test.com/avatar_images_by_user/70"}); // YOU SHOULD UPLOAD YOUR FILE FROM HERE // AND SET SCR AGAIN TO SEE LATEST PRICTURE } render () { return ( <div> <ProfileImageBox alt="Alt Text" allowUpload={true} onFileChange={(e) => this.onFileChange(e, {type: 'user-image'})} src={this.state.src}/> </div> ) } } |
You can now push your code to git repository |
Our main target is to publishing our plugin to npmcreate-react-library already has a feature through which we can deploy the example folder to Github pages. You just need to run the following command: Be sure run npm login to login to npm server and then run npm publish. Npm package is published now https://www.npmjs.com/package/react-profile-image-box |
Saturday, February 1, 2020
ReactJS Create React Modal Open Popup Using reactjs-popup Dependency
In this tutorial, we will use the react-popup package which is a simple and Powerful react component. It's simple just add dependency import Popup from "reactjs-popup";which you can add to your project by following commandnpm add reactjs-popup --save |
Because reactjs-popup provides a child as function pattern, you have full control on Popup state |
Full code example given below: |
import React, { Component } from "react"; import "./styles.css"; import Popup from "reactjs-popup"; class App extends Component { constructor() { super(); this.state = { open: false }; this.openModal = this.openModal.bind(this); this.closeModal = this.closeModal.bind(this); this.popupOnClose = this.popupOnClose.bind(this); } openModal() { this.setState({ open: true }); } closeModal() { this.setState({ open: false }); } popupOnClose() {} render() { return ( <div> <span onClick={this.openModal}>Click here to open Popup</span> <Popup open={this.state.open} className="popup-modal-container-box" modal onOpen={e => this.popupOnClose(e)} onClose={this.popupOnClose} lockScroll={true} closeOnDocumentClick={false} > <h1>HELLO POPUP</h1> <span onClick={this.closeModal}>CLOSE</span> </Popup> </div> ); } } export default App; |
Full example is created on CodeSandbox.IO https://codesandbox.io/s/reactjs-create-react-modal-open-popup-using-reactjs-popup-dependency-qthyq |
Friday, January 31, 2020
ReactJS - You tried to redirect to the same route you're currently on
It's a common problem when you redirect on same route will give a warning like You tried to redirect to the same route you're currently on: /profile/2. It's because of when we define Route we can not define for every parameters like 1, 2, 3 etc. Normally we define our Route like: <Route path="/profile/:id" component={Profile} /> And this will handle every URL like http://example.com/profile/1, http://example.com/profile/2 etc. |
But sometimes when we use Redirect component to redirect to another profile page from current profile page using the below code return <Redirect to={"/profile/" + this.state.id} push={true} />; The above warning thrown because our Route is same for all URL like /profile/1 as well as /profile/2. |
To avoid this warning we need to define key to our Route like below <Route path="/profile/:id" render={props => { return <Profile {...props} key={props.match.params.id} />; }} /> |
Full example is created on CodeSandbox.IO https://codesandbox.io/s/you-tried-to-redirect-to-the-same-route-youre-currently-on-063ot |
Thursday, January 2, 2020
Request Mocking In Grails For Back-end/Background Threads | Mock Request With Session
Request Mocking In Grails For Back-end/Background Threads | Mock Request With Session
And use be like below:
package com.pkm.util import grails.gsp.PageRenderer import grails.util.Holders import org.codehaus.groovy.grails.web.servlet.mvc.GrailsHttpSession import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest import org.springframework.web.context.request.RequestContextHolder import javax.servlet.ServletContext import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpSession /** * Created by pritom on 16/08/2017. */ class HibernateRequestUtils { static GrailsWebRequest getRequest() { return RequestContextHolder.getRequestAttributes() } static HttpSession getSession() { return request?.session } static void setValueToSession(String key, def value) { session.putAt(key, value) } static def getValueFromSession(String key) { return session.getAt(key) } static boolean isBound() { HttpServletRequest.isBound() } static boolean hasSession() { session != null } static def mock(Closure closure = null) { return HttpServletRequest.mock(closure) } static { HttpServletRequest.metaClass.static.with { isBound = { RequestContextHolder.requestAttributes != null } mock = { closure = null -> HttpServletRequest _request = PageRenderer.PageRenderRequestCreator.createInstance("/page/dummy") _request.IS_DUMMY = true _request."javax.servlet.include.servlet_path" = "/page/dummy.dispatch" GrailsWebRequest webRequest = new GrailsWebRequest( _request, PageRenderer.PageRenderResponseCreator.createInstance(new PrintWriter(new StringWriter())), Holders.servletContext ) { private MockedHttpSession _session MockedHttpSession getSession() { if (this._session == null) { this._session = new MockedHttpSession() } return this._session } } RequestContextHolder.setRequestAttributes(webRequest) if (closure) { def returned = closure() RequestContextHolder.resetRequestAttributes() return returned } return webRequest } } } } class MockedHttpSession extends GrailsHttpSession { MockedHttpSession() { super(null) } private LinkedHashMap attributes = [:] Object getAttribute(String name) { attributes[name] } Enumeration getAttributeNames() { Collections.enumeration(attributes.keySet()) } long getCreationTime() { 0 } long getLastAccessedTime() { 0 } int getMaxInactiveInterval() { 0 } ServletContext getServletContext() { return Holders.servletContext } @Deprecated String[] getValueNames() { [] as String[] } @Deprecated void putValue(String name, Object value) {} @Deprecated void removeValue(String name) {} void invalidate() {} boolean isNew() {true} void removeAttribute(String name) { attributes.remove(name) } void setAttribute(String name, Object value) { attributes[name] = value } void setMaxInactiveInterval(int arg0) {} }
And use be like below:
if (HibernateRequestUtils.isBound()) { DO YOU CODE IN HTTP REQUEST } else { HibernateRequestUtils.mock { DO YOUR CODE IN MOCK REQUEST AS YOU DO IN REAL REQUEST } }
Subscribe to:
Posts (Atom)