Wednesday, December 7, 2022

React Example - Insert New Object in an Array

In this tutorial we'll see how to insert an object into an array of objects in your React application especially when you are storing that array in state. What you need to keep in mind is that the you should not mutate an array when you store them in state. You should rather create a new array with the required changes and set state to use this new array.

Inserting into an array - React

As stated above you need to create a new array which should contain the existing elements and then the new element at the end.

Preferred way to do it, in React, is to use spread operator to get all the existing elements and then add the new array element.

As an example, we'll have a ProductForm component to add a new Product to an array. There is also a Products component that shows the products which are in the array.

Products.js

import { Fragment } from "react";
const Products = (props) =>{
    return(
        <Fragment>
            <h2>Product List</h2>
            <ul>{
                props.products.map((product) => (
                    <li key={product.id}>
                        Id- {product.id} <br />
                        Name- {product.name}                    
                    </li>
                ))
            }
            </ul>
        </Fragment>
    );
}
export default Products;

List of products is passed to the Products component from the parent component (App.js), that is why it is accessible here through props.

ProductForm.js

import { Fragment } from "react";
import { useState } from "react";

const ProductForm = (props) => {
    const [prodName, setProdName] = useState('');
    const clickHandler = () => {
        props.onAddProduct(prodName);
        setProdName('');
    }
    return(
        <Fragment>
            <h2>Product Form</h2>
            <input
                value={prodName}
                onChange={e => setProdName(e.target.value)}
            />
            <button onClick={clickHandler}>Add Product</button>
        </Fragment>
    );
}

export default ProductForm;

Some point to note in ProductForm component-

  1. Uses useState hook to maintain the product name state.
  2. On the click of the button, clickHandler() function is called which in turn calls the onAddProduct function in another component, that is why it is called using props.

App.js

const productList = [
  { id: 1, name: 'Laptop', price: 455.50 },
  { id: 2, name: 'Mouse', price: 15.89 },
  { id: 3, name: 'USB', price: 10.00 },
  { id: 4, name: 'HDD', price: 55.50 },
];
function App() {
  const [products, setProducts] = useState(productList);
  const addProductHandler = (productName) => {
    setProducts([
      ...products,
      { id: Math.round(Math.random() * 10), name: productName }
    ]);
  }
  return (
    <div>
      <ProductForm onAddProduct={addProductHandler}/>
      <hr />
      <Products products={products}/>

    </div>
  );
};

export default App;

Important points to note here-

  1. An array is created with some existing product objects in it.
  2. The array is stored in the state.
  3. In addProductHandler() function new array is created by adding the existing products (using spread operator) and then adding the new product object (Math.random is used to create new ID here, not an ideal way but does the job here!). This new array is then set as new state by passing it to setProducts().
    setProducts([
      ...products,
      { id: Math.round(Math.random() * 10), name: productName }
    ]);
    
  4. Reference to the addProductHandler function is passed in <ProductForm> tag as props.
    <ProductForm onAddProduct={addProductHandler}/>
    
  5. products Array is passed in Products tag as props.
    <Products products={products}/>
    

With everything done if a new product "Keyboard" is added through the form, it should be added to the products array.

That's all for the topic React Example - Insert New Object in an Array. If something is missing or you have something to share about the topic please write a comment.


You may also like

Monday, December 5, 2022

React Example - Update Object in an Array of Objects

It is a very common requirement to update one or more objects in an array of objects in your React application. What you need to keep in mind is that the you should not mutate an array when you store them in state. You should rather create a new array with the required changes and set state to use this new array.

Update object in array of objects

If you want to modify one or more items of an array, you can use map() to create a new array. Steps are as given below.

  1. Iterate the array using map() function.
  2. Function passed as first argument with in map() should have the condition to decide whether object should be updated or not.
  3. If condition is satisfied then update that object otherwise return the object as is. That way you will have a new array with all the objects including updated one.

As an example, let's have a shopping cart with certain products added. On the click of the button increase or decrease the product count.

import { useState } from "react";

const INITIAL_PRODUCTS = [{
    id: 1,
    name: 'Samosa',
    count: 5,
  }, 
  {
    id: 2,
    name: 'Roti',
    count: 4,
  }, 
  {
    id: 3,
    name: 'Chicken Tikka Masala',
    count: 2,
  },
  {
    id: 4,
    name: 'Matar Paneer',
    count: 1,
  }];

const ShoppingCart = () => {
    const [products, setProducts] = useState(INITIAL_PRODUCTS);
    const handleIncreaseClick = (productId) => {
        const updatedProducts = products.map(product => {
            // update count property of the matching object
            if(product.id === productId){
              return {...product, 
                      count:product.count + 1};
            }else{
              // return object unchanged
              return product;
            } 
          });
        setProducts(updatedProducts);
    }
    const handleDecreaseClick = (productId) => {
        let updatedProducts = products.map(product => {
            if(product.id === productId){
              return {...product, 
                      count:product.count - 1};
            }else{
              return product;
            } 
        });
        updatedProducts = updatedProducts.filter(p => p.count > 0);
        setProducts(updatedProducts);
    }
    return (
        <ul>
            {
                products.map(product => (
                    <li key={product.id}>
                        {product.name}
                        -
                        {product.count}
                        <button onClick={()=> {
                            handleIncreaseClick(product.id)
                        }}>+</button>
                        <button onClick={()=> {
                            handleDecreaseClick(product.id)
                        }}>-</button>
                    </li>
                ))
            }
        </ul>
    );
}

export default ShoppingCart;

Important points to note in the code are-

  1. Array is initialized with some product objects.
  2. Clicking the ‘+’ button triggers the handleIncreaseClick() function with the id of the product passed as an argument. In the handleIncreaseClick() function create a new array by going through all the products, the product for which the id matches increase the count by 1, otherwise return the product without any change.
  3. Then set the products state by passing this new array.
  4. Clicking the ‘-’ button triggers the handleDecreaseClick() function with the id of the product passed as an argument. If the product id matches, decrease the count by 1. One more thing is to later check for the products with count as 0 to remove them from the array. For that filter() is used.
Update object in array of objects

That's all for the topic React Example - Update Object in an Array of Objects. If something is missing or you have something to share about the topic please write a comment.


You may also like

Friday, December 2, 2022

How to Split a String in Java

This post shows how you can split a String in Java using split() method. String you need to split may be delimited using pipe, tab or spaces so let’s see how to use split() method to split such delimited data strings in Java. Note that if you are using any special symbol with in the regular expression then you do need to escape it using escape character (\).

Splitting String delimited using pipe(|) symbol - Java code

public class SplitString {
  public static void main(String[] args) {
    String str = "A001|BOA|Ronda|5000";
    String[] data = str.split("\\|");
    System.out.println("Name- " + data[2]);
  }
}
Output
Name- Ronda

Splitting data in Java delimited using tab (\t)

public class SplitString {
  public static void main(String[] args) {
    String str = "A001	BOA	Ronda	5000";
    String[] data = str.split("\t");
    System.out.println("Amount- " + data[3]);
  }
}
Output
Amount- 5000

Splitting data delimited using spaces- Java code

public class SplitString {
  public static void main(String[] args) {
    String str = "A001  BOA Ronda 5000";
    // Matches any number of spaces
    String[] data = str.split("\\s+");
    System.out.println("Amount- " + data[3]);
  }
}
Output
Amount- 5000

Splitting data delimited using single space

public class SplitString {
  public static void main(String[] args) {
    String str = "A001 BOA Ronda 5000";
    // Matches any number of spaces
    String[] data = str.split("\\s");
    System.out.println("Name- " + data[2]);
  }
}
Output
Name- Ronda

That's all for the topic How to Split a String in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

Wednesday, November 30, 2022

Java Condition Interface

Condition interface which resides in java.util.concurrent.locks has methods for inter thread communication similar to Object class monitor methods (wait, notify and notifyAll). Condition provides methods like await(), signal(), signalAll(). Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods.

Some of the methods defined in java.util.concurrent.locks.Condition interface are given below.

  • await()- Causes the current thread to wait until it is signalled or interrupted.
  • await(long time, TimeUnit unit)- Causes the current thread to wait until it is signalled or interrupted, or the specified waiting time elapses.
  • awaitNanos(long nanosTimeout)- Causes the current thread to wait until it is signalled or interrupted, or the specified waiting time elapses.
  • awaitUninterruptibly()- Causes the current thread to wait until it is signalled.
  • awaitUntil(Date deadline)- Causes the current thread to wait until it is signalled or interrupted, or the specified deadline elapses.
  • signal()- Wakes up one waiting thread.
  • signalAll()- Wakes up all waiting threads.

How to get Condition instance

A Condition instance is intrinsically bound to a lock. To obtain a Condition instance for a particular Lock instance use its newCondition() method.

Example using Condition interface methods

Following producer consumer program uses the methods of the Condition interface for intercommunication between two threads.

In the example Consumer thread starts removing items from buffer only when buffer is full till then the Consumer thread is in wait state because of await() method.

package com.knpcode.proj.Programs;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ProduceConsume {
  public static void main(String[] args) {
    int capacity = 5;
    // shared object
    Buffer buffer = new Buffer(capacity);
    Thread t1 = new Thread(new Producer(buffer, capacity), "Producer");
    Thread t2 = new Thread(new Consumer(buffer, capacity), "Consumer");
    t1.start();
    t2.start(); 
  }

  // Producer class to add elements to buffer
  static class Producer implements Runnable{
    Buffer buffer;
    int capacity;
    Producer(Buffer buffer, int capacity){
      this.buffer = buffer;
      this.capacity = capacity;
    }
    @Override
    public void run() {
      for(int i = 1; i <= capacity; i++){
        try {
          buffer.put(i);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
    }
  }
  // Consumer class to remove elements from buffer
  static class Consumer implements Runnable{
    Buffer buffer;
    int capacity;
    Consumer(Buffer buffer, int capacity){
      this.buffer = buffer;
      this.capacity = capacity;
    }
    
    @Override
    public void run() {
      for(int i = 1; i <= capacity; i++){
        try {
          System.out.println("Item removed- " + buffer.take());
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
    }
  }
	
  static class Buffer {
    private Object[] items;
    final Lock lock = new ReentrantLock();
    // Conditions
    final Condition notFull  = lock.newCondition(); 
    final Condition notEmpty = lock.newCondition(); 
    int putptr, takeptr, count;
    public Buffer(int capacity){
      items = new Object[capacity];
    }
		
    public void put(Object x) throws InterruptedException {
      lock.lock();
      try {
        while (count == items.length)
          notFull.await();
        items[putptr] = x;
        System.out.println("Putting- "+ x);
        if (++putptr == items.length) { 
          putptr = 0;
        }
        ++count;
        notEmpty.signal();
      } finally {
        lock.unlock();
      }
    }

    public Object take() throws InterruptedException {
      lock.lock();
      try {
        while (count == 0) {
          notEmpty.await();
        }
        Object item = items[takeptr];
        if (++takeptr == items.length) {
          takeptr = 0;
        }
        --count;
        notFull.signal();
        return item;
      } finally {
        lock.unlock();
      }
    }
  }
}
Output
Putting- 1
Putting- 2
Putting- 3
Putting- 4
Putting- 5
Item removed- 1
Item removed- 2
Item removed- 3
Item removed- 4
Item removed- 5

That's all for the topic Java Condition Interface. If something is missing or you have something to share about the topic please write a comment.


You may also like

Tuesday, November 29, 2022

React Portals With Examples

Normally in React when a component is rendered, it is mounted into the DOM as a child of the nearest parent node. This works fine for most of the scenarios but sometimes you may want to insert a child into a different location in the DOM. Portals in react provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.

Why React portal

So, why is it important to render children into a DOM node outside the parent hierarchy sometimes? There are couple of advantages which are visible when you are using a modal, hovercards or tooltips, basically something which should be displayed as an overlay not as part of the parent component.

  • First advantage is to have a semantically correct HTML. Logically a modal or hovercard should not be part of “root” element, it should be rendered in a separate DOM node.
  • Poroperties for the child node are inherited from the parent component. For example, height, width, overflow: hidden, z-index which may cause modal, tooltip or hover card to be cropped or some part of it hidden.

To avoid the above-mentioned issues, you can use portals in React to render children into a separate DOM node.

React portal Syntax

A portal is created using createPortal() method which is part of react-dom package.

ReactDOM.createPortal(child, container)

Parameters

child- Something that can be rendered such as an element, string, or fragment.

container- DOM node location where child should be injected.

React portal example

As an example, we'll create a Modal dialog box where we need to have a backdrop and the modal box itself. If you click anywhere on the backdrop, modal box should close. There will also be a close button with in the box.

Initially we won't use React portal to render this Modal box which means it will be rendered with in the Parent component.

ModalDialog.js

import './ModalDialog.css'
const ModalDialog = (props) => {
    return (
        <div className="modal-backdrop" onClick={props.handleClose}>
            <div className="modal-content">
                {props.children}
                <button onClick={props.handleClose}>Close</button>
            </div>

        </div>
    );
}

export default ModalDialog;

ModalDialog.css

.modal-backdrop {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    z-index: 20;
    background-color: rgba(0, 0, 0, 0.75);
}

.modal-content {
    top: 12vh;
    left: 5%;
    width: 50%;
    height: 40%;
    background-color: white;
    padding: 1rem;
    border-radius: 10px;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem; 
}

App.js

Here we have state management for modal (open or closed) using useState hook. There is also a button to open Modal box, clicking this button sets the isModalOpen to true which results in modal box being displayed.

Closing the modal triggers the closeHandler() function which is kind of child to parent component communication by lifting the state up.

import ModalDialog from "./Components/UI/ModalDialog";
function App() {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const closeHandler = () => {
    setIsModalOpen(false);
  }
  return (
    <div>
      <button onClick={() => setIsModalOpen(true)}>
          Click to Open Modal
      </button>
      {isModalOpen && <ModalDialog handleClose={closeHandler}> 
        This is Modal Content
      </ModalDialog>}
    </div>
  );
};
React Portals

As you can see Modal is rendered as a Child component of App component wrapped with in root element.

Let's make changes to render Modal outside the DOM hierarchy of the parent component.

In public\index.html add another <div> element. This <div> element is the container for injecting the Modal.

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

In the ModalDialog.js wrap the code with in createPortal() method.

import reactDom from 'react-dom';
import './ModalDialog.css'
const Modal = (props) => {
    return (
        <div className="modal-backdrop" onClick={props.handleClose}>
            <div className="modal-content">
                {props.children}
                <button onClick={props.handleClose}>Close</button>
            </div>

        </div>
    );
}
const portalElement = document.getElementById('modalOverlay');
const ModalDialog = (props) => {
    return reactDom.createPortal(<Modal handleClose={props.handleClose}>{props.children}</Modal>, portalElement);

}

export default ModalDialog;

Points to note here-

  1. First you need to import from react-dom. You can also import createPortal directly
    import { createPortal } from 'react-dom';
    	
  2. createPortal() method takes two arguments, first is the child that has to be rendered. To make it more readable what constitutes a child has been assigned to a constant Modal.
  3. Second argument to the createPortal() method is a container. We already added one <div> element in the index.html with id as “modalOverlay”. That element is assigned to another constant portalElement.
  4. Use of portal only changes the DOM tree structure not the parent child component relationship. <ModalDialog> is still used in App.js to render the child component. props are also used to have parent-child communication the same way as before.
React Portals Example

Now Modal component is rendered into a separate DOM node outside the DOM hierarchy of the parent component.

That's all for the topic React Portals With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Sunday, November 27, 2022

JDBC Driver Types

JDBC API in Java programming language provides a standard, universal way to connect to databases. It is the responsibility of different DB vendors to provide the implementation of the interfaces in JDBC API and that implementation by DB vendors is provided as JDBC drivers.

Types of JDBC drivers

Based on these different implementations JDBC drivers are categorized into four types.

  • Type 1 driver: JDBC-ODBC bridge JDBC driver
  • Type 2 driver: Written partly in Java and partly in native code
  • Type 3 driver: Pure Java client and middleware server translating client request to data source.
  • Type 4 driver: Written completely in Java.

Type 1 JDBC Driver

Type 1 JDBC driver implements the JDBC API as a mapping to another data access API, such as ODBC (Open Database Connectivity).

The JDBC-ODBC Bridge driver is an example of type 1 JDBC driver that maps JDBC API requests to ODBC requests.

Disadvantages
  1. Type 1 driver is an old driver that is not supported any more by Oracle.
  2. These drivers are not fully written in Java and depends on native library so Type 1 drivers are not portable.
  3. Each JDBC call is mapped to ODBC request and then to DB making it very slow.
Type 1 JDBC driver

Type 2 JDBC Driver

Type 2 JDBC drivers are written partly in the Java programming language and partly in native code. These drivers use native client side libraries specific to the data source to which they connect to.

Oracle's OCI (Oracle Call Interface) client-side driver is an example of a Type 2 driver.

Disadvantages
  1. Since native libraries are required so there is platform dependency.
  2. JDBC calls are translated to native calls using native libraries making it a slow driver though not as slow as Type 1 driver.
  3. Native API must be installed on the client machines.
Type 2 JDBC Driver

Type 3 JDBC Driver

In Type 3 JDBC driver client is written in Java which connects to a middleware server using a database independent protocol. JDBC calls from the client are translated by middleware server to the vendor specific DB calls and then forwarded to the data source.

Disadvantages
  1. Requires a middleware server.
  2. Since there are two stages; JDBC call to midleware server then vendor specific translation and communication to the DB so the JDBC call processing takes more time.
Type 3 JDBC Driver

Type 4 JDBC Driver

Type 4 JDBC drivers are written completely in Java and don't require any native code libraries or middleware server to sit in the middle. Type 4 drivers implement the network protocol for a specific data source and connect directly to data source.

Type 4 JDBC drivers are also known as thin drivers

Disadvantages
  1. Since driver itself implements the vendor specific network protocol so Type 4 drivers are DB specific and generally supplied by the DB vendors.
Type 4 JDBC Driver

That's all for the topic JDBC Driver Types. If something is missing or you have something to share about the topic please write a comment.


You may also like

Friday, November 25, 2022

React useContext Hook With Examples

In React application, props is one way to pass data from parent to child component. But it may become an overhead to maintain props in each component if you have a big hierarchy of nested components. React Context API provides another way to maintain global state. Once a context is created with some value in a component, that context will be available to all the nested child components without using "props". The useContext hook in React is used to read the context value in a component where it is needed.

Why useContext hook in React

First let's try to understand what exactly is the problem with props where useContext hook provides a better alternative than "props-drilling".

As an example, we have 3 components ComponentA, ComponentB and ComponentC and we have to pass data from parent component (ComponentA) to child component.

ComponentA.js

From ComponentA, value for theme is passed to the child component, ComponentB.

import ComponentB from "./ComponentB";
const ComponentA = () => {
    return(
        <ComponentB theme="dark"></ComponentB>
    );
}    
export default ComponentA;

ComponentB.js

The same theme value has to be passed to the ComponentC so you'll again use props to pass it further down.

import ComponentC from "./ComponentC";
const ComponentB = (props) => {
    return(
     <ComponentC theme={props.theme}></ComponentC>
    );
}    
export default ComponentB;

ComponentC.js

const ComponentC = (props) => {
    return (
        <p>Current theme is- {props.theme}</p>
    );
}    
export default ComponentC;

Though a simple example with not much nesting but the problem here, as you can notice, is that ComponentB has to do the task of passing the props further down to make it available to ComponentC. You don't have any mechanism to pass that data directly from ComponentA to ComponentC so that all the components in the hierarchy don't have to manage props.

Context provides you with that mechanism to provide data to the nested components without the overhead of managing props.

How to work with useContext

In order to understand how useContext works you'll have to understand the working of React Context API which has three main steps.

  1. Create context using React.createContext.
  2. Enclose the component with <CreatedContext.Provider>. Using Provider lets you provide a context value.
    <CreatedContext.Provider value="ctxValue">
        <SomeComponent />
    </CreatedContext.Provider>
    

    React Context guarantees that this SomeComponent component and any components inside it, no matter how deep, will be able to access the passed context values.

    If the passed context values change, React will re-render the components reading the context as well.

  3. Read the context value in the Component where you need it using useContext() hook.

useContext hook syntax

const value = useContext(SomeContext)

parameters

SomeContext: The argument passed to the useContext() is the context that you've previously created with createContext.

useContext returns the context value for the calling component.

useContext React example

If we take the same example of 3 components ComponentA, ComponentB and ComponentC where we have to pass some data from parent component (ComponentA) to child component. This time we'll use Context to pass data.

1. Creating Context

First step is to create Context. Since many components in different files will need access to the same context so it's common to declare contexts in a separate file.

Contexts.js

import { createContext } from 'react';
export const ThemeContext = createContext('light');

You can pass default value while creating context. If matching context provider is not present default value acts as a fallback value. If you don't have any meaningful default value, pass null while creating context.

Note that Context value can be anything an object, function handle, string. Here we are using a string value.

2. Providing context

createContext() returns a context object which in itself doesn’t hold any information. Typically, you will enclose your higher component with the <Context.Provider> specifying the context value.

App.js

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ComponentA></ComponentA>
    </ThemeContext.Provider>
  );
};

export default App;

Now the ComponentA component and any components inside it, no matter how deep, will be able to access the passed context values.

ComponentA.js

import ComponentB from "./ComponentB";

const ComponentA = () => {
    return(
        <ComponentB />
    );
}    
export default ComponentA;

As you can see now there is no need to pass theme value using props.

ComponentB.js

import ComponentC from "./ComponentC";
const ComponentB = () => {
    return(
     <ComponentC />
    );
}    
export default ComponentB;

3. Accessing Context value.

Read the context value in the Component where you need it using useContext() hook which lets you read and subscribe to context from your component.

ComponentC.js

import { useContext } from "react";
import { ThemeContext } from "./Contexts";

const ComponentC = () => {
    const themeCtx = useContext(ThemeContext);
    return (
        <p>Current theme is- {themeCtx}</p>
    );
}    
export default ComponentC;

Passing dynamic data via context

In the above example value passed with Context provider is hardcoded but most of the times you will want it to be a dynamic value. To update context, you need to combine it with useState hook. Declare a state variable in the parent component and pass the current state down as the context value to the provider.

Here is the changed App.js where we have a checkbox to select theme, which is managed in a state variable named isDarkMode. In the context provider value is now changed dynamically using the current state.

import './App.css';
import { useState } from 'react';
import { ThemeContext } from './components/Examples/Contexts';
import ComponentA from './components/Examples/ComponentA';

function App() {
  const [isDarkMode, setIsDarkMode] = useState(0);
 
  return (

    <div>
      <input
        type="checkbox"
        checked={isDarkMode}
        onChange={e => setIsDarkMode(e.target.checked)}
      />
      Dark mode

      <hr />
      <ThemeContext.Provider value={isDarkMode? 'dark-mode' : 'light-mode'}>
        <ComponentA></ComponentA>
      </ThemeContext.Provider>
    </div>  
  );
}
export default App;
useContext hook React
useContext hook example

For example where context value is an object, check this post- React Context API With Examples

That's all for the topic React useContext Hook With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like