April 12, 2024

How to Convert float to String in Java

This post shows how you can convert float to String in Java.

1. Converting float to String using Float.toString() method

Wrapper class Float in Java has toString() method that returns a string representation of the passed float argument.

public class FloatToString {
  public static void main(String[] args) {
    float val = 28.92f;
    String strVal = Float.toString(val);
    System.out.println("Converted String value = " + strVal);
  }
}
Output
Converted String value = 28.92

2. Convert using String.valueOf() method

String.valueOf(float f)- Returns the string representation of the float argument.

public class FloatToString {
  public static void main(String[] args) {
    float val = 28.92f;
    String strVal = String.valueOf(val);
    System.out.println("Converted String value = " + strVal);
  }
}
Output
Converted String value = 28.92

3. Converting using String concatenation

You can concatenate the float value with an empty string ("") that will return the result as a String. That's one way to convert float to String

public class FloatToString {
  public static void main(String[] args) {
    float val = 108.256f;
    String strVal = val + "";
    System.out.println("Converted String value = " + strVal);
  }
}
Output
Converted String value = 108.256

4. Converting using append method of StringBuilder or StringBuffer class

Both StringBuilder and StringBuffer classes have append() method where you can pass float as an argument. The append() method will append the string representation of the float argument to the sequence.

public class FloatToString {
  public static void main(String[] args) {
    float val = -49.12f;
    StringBuilder sb = new StringBuilder();
    sb.append(val);
    System.out.println("Converted String value = " + sb.toString());
  }
}
Output
Converted String value = -49.12

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


You may also like

April 11, 2024

How to Convert double to int in Java

In this post we’ll see how to convert double to int in Java.

Considerations while converting double to int in Java

While converting double to int two things you need to consider are-

  1. Range of double is much more than the int, if the double you are trying to convert to int is out of range for int then how to handle that.
  2. In double value there are fractional parts where as int doesn’t have fractional part so what to do with fractional part is another thing to consider. Fractional part can be truncated or you need to round the double value to the nearest integer.

Converting using intValue() method or by type casting

You can convert double to int using intValue() method of the Double class (needs a Double object) or by explicitly type casting double value to int. In fact intValue() method implementation also do the type casting and returns the value of this Double as an int after a narrowing primitive conversion. Problem with these two methods is that the rounding to the nearest integer doesn’t happen while converting double to int, fractional part is truncated.

1. Converting double to int using intValue() method
public class DoubleToInt {
  public static void main(String[] args) {
    Double d = 147.89d;
    int val = d.intValue();
    System.out.println("Converted int value- " + val);
  }
}
Output
Converted int value- 147

Couple of things to note here- double value is truncated while converting it to int and this way of conversion needs an instance of Double class.

2. Converting double to int using explicit casting
public class DoubleToInt {
  public static void main(String[] args) {
    double d = 147.89d;
    int val = (int)d;
    System.out.println("Converted int value- " + val);
  }
}
Output
Converted int value- 147

3. Converting double to int with rounding to nearest integer

Though the above two ways convert double to int but truncate the fractional part rather than rounding the double to the nearest integer which is not what you’d want in most of the scenarios. In order to do the rounding you have to use Math.round(double d) method which returns the closest long to the passed argument.

Since the returned value is long so further casting is required to convert the long value to int.

Math.round() method also takes care of the special cases-

  • If the argument is NaN, the result is 0.
  • If the argument is negative infinity or any value less than or equal to the value of Integer.MIN_VALUE, the result is equal to the value of Integer.MIN_VALUE.
  • If the argument is positive infinity or any value greater than or equal to the value of Integer.MAX_VALUE, the result is equal to the value of Integer.MAX_VALUE.

Converting double to int using Math.round()

public class DoubleToInt {
  public static void main(String[] args) {
    double d = 147.89d;
    int val = (int)Math.round(d);
    System.out.println("Converted int value- " + val);
  }
}
Output
Converted int value- 148

As you can see here rounding is done to the nearest integer. Since the returned value from the method Math.round(double d) is long so casting to int is also required.

Example with different double arguments

public class DoubleToInt {
  public static void main(String[] args) {
    double val1 = 1456.12;
    int i1 = (int)Math.round(val1);
    System.out.println("Converted int value- " + i1);
    double val2 = -567.99;
    int i2 = (int)Math.round(val2);
    System.out.println("Converted int value- " + i2);
    double val3 = 236.5646;
    int i3 = (int)Math.round(val3);
    System.out.println("Converted int value- " + i3);
  }
}
Output
Converted int value- 1456
Converted int value- -568
Converted int value- 237

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


You may also like

April 10, 2024

Race Condition in Java With Examples

Race condition in Java may occur in a multi-threaded language like Java when two or more threads try to access a shared resource. If all the threads are just reading a shared object that poses no problem but modifying or writing a value may lead to incorrect results because of race condition.

In a multi-threaded environment, a thread after executing few steps may be preempted by another thread. That may leave the shared data in an inconsistent state. For example take the simple task of incrementing a counter– counter++;

This simple task of incrementing a counter is actually comprised of three steps-

  1. Read the value of counter variable.
  2. Increment the value by 1.
  3. Store the value of counter variable.

If there are two threads sharing this variable then the following scenario may happen-

int counter = 0;
counter = counter + 1; // Thread 1
counter = counter + 1; // Thread 2 started before thread 1 could save the new 
                      //value of counter, so Thread 2 also got the initial value of counter as 0.
store counter value // Thread 1
store counter value // Thread 2

So you end up with the counter value as 1 rather than the correct value 2 because of the interleaving threads. That’s what race condition can do to a shared object in a multi-threaded environment.

Error scenarios because of race condition

Because of the race condition, executing thread may read a stale value of shared object which may result in any of the following scenario.

  1. If a thread has to execute some logic based on the value of the variable. Because thread may end up reading a wrong value it may not act the way it was supposed to. This scenario is known as check-then-act race condition.
  2. A thread has to read the current value, modify it and store the new value. Again because of the race condition thread may end up reading and modifying a stale value. This scenario is known as read-modify-write race condition.

Example of race condition in Java

Here is a simple example where a shared integer variable is incremented and the value is displayed. Ten threads are created and each thread increments and then displays the value of the variable. Expected behavior is that each thread should get a unique value between 1-9.

public class RaceConditionDemo {
  int counter = 0;
  public  void incrementCounter(){
    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    counter++;
  }
  public int getCounter(){
    return counter;
  }
  public static void main(String[] args) {
    RaceConditionDemo rc = new RaceConditionDemo();
    for(int i = 0; i < 10; i++){
      new Thread(new Runnable() {			
        @Override
        public void run() {
          rc.incrementCounter();
          System.out.println("value for " + Thread.currentThread().getName() + " - " + rc.getCounter());
        }
      }).start();
    }	
  }
}
Output
value for Thread-0 - 1
value for Thread-2 - 2
value for Thread-1 - 3
value for Thread-4 - 4
value for Thread-5 - 6
value for Thread-3 - 6
value for Thread-6 - 6
value for Thread-9 - 8
value for Thread-8 - 9
value for Thread-7 – 8

In one of the run the output came as above (note that the output may vary). As you can see Thread 5, 3 and 6 have got the same value 6, Thread 7 and 9 have also got the same value 8.

Avoiding race condition in Java

Now when you know what is race condition and seen an example too where interleaving threads read the same value of the shared object. That brings us to the question how to avoid race condition in Java.

It is clear that you need to restrict access to the critical section (code where shared resource is modified). In Java that’s what synchronized keyword does; synchronizes the access to the shared resource. Using synchronization ensures that the atomic operations are executed as a single operation without thread interference.

In the example showed above synchronizing the method call should avoid the race condition.

public class RaceConditionDemo {
  int counter = 0;
  public  void incrementCounter(){
    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    counter++;
  }
  public int getCounter(){
    return counter;
  }
  public static void main(String[] args) {
    RaceConditionDemo rc = new RaceConditionDemo();
    for(int i = 0; i < 10; i++){
      new Thread(new Runnable() {			
        @Override
        public void run() {
          synchronized(rc){
            rc.incrementCounter();
            System.out.println("value for " + Thread.currentThread().getName() + " - " + rc.getCounter());
          }
        }
      }).start();
    }	
  }
}
Output
value for Thread-0 - 1
value for Thread-8 - 2
value for Thread-7 - 3
value for Thread-9 - 4
value for Thread-6 - 5
value for Thread-4 - 6
value for Thread-5 - 7
value for Thread-3 - 8
value for Thread-2 - 9
value for Thread-1 – 10

As you can see now every thread gets a unique value.

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


You may also like

Deadlock in Java With Examples

In a multi-threaded environment there may come a situation when one thread is waiting for a resource that is locked by another thread, which in turn is waiting for another thread and so on until this dependency loops back to the first waiting thread. Thus all the threads are waiting for each other to release the resources to make any further progress and blocked forever in the process. This scenario is called deadlock in multi-threading.

Deadlock example

To explain deadlock in Java we can take a simple scenario of two threads Thread1 and Thread2, where Thread1 holds a lock on obj1 and waiting to acquire a lock on obj2. At the same time Thread2 has a lock on obj2 and waiting to acquire lock on obj1. Here both threads are blocked in a circular loop where Thread1 is waiting to acquire lock on obj2 and Thread2 is waiting to acquire lock on obj1 thus creating a deadlock.

Deadlock in Java

Deadlock in Java scenarios

You may get deadlock in Java because of the improper use of the synchronized keyword. Scenarios when deadlock may happen are as follows.

  1. Nested synchronized blocks with reverse ordering of objects.
  2. Calling one synchronized method from another where methods are not using the same object to synchronize.

Deadlock in Java example

First example shows the scenario when there are nested synchronized blocks with reverse ordering of objects.

class ThreadA implements Runnable{
  private Object obj1;
  private Object obj2;
  ThreadA(Object obj1, Object obj2){
    this.obj1 = obj1;
    this.obj2 = obj2;
  }
  @Override
  public void run() {
    synchronized(obj1){
      System.out.println(Thread.currentThread().getName() + " acquired " + "obj1 lock");
      synchronized(obj2){
        System.out.println(Thread.currentThread().getName() + " acquired " + "obj2 lock");
      }
    }       
  }  
}

class ThreadB implements Runnable{
  private Object obj1;
  private Object obj2;
  ThreadB(Object obj1, Object obj2){
    this.obj1 = obj1;
    this.obj2 = obj2;
  }
  @Override
  public void run() {
    synchronized(obj2){
      System.out.println(Thread.currentThread().getName() + " acquired " + "obj2 lock");
      synchronized(obj1){
        System.out.println(Thread.currentThread().getName() + " acquired " + "obj1 lock");
      }
    }   
  }
}

public class DLDemo {
  public static void main(String[] args) {
    Object obj1 = new Object();
    Object obj2 = new Object();
    Thread t1 = new Thread(new ThreadA(obj1, obj2));
    Thread t2 = new Thread(new ThreadB(obj1, obj2));
    t1.start();
    t2.start();
  }
}
Output
Thread-0 acquired obj1 lock
Thread-1 acquired obj2 lock

In ThreadA’s run method synchronization is first done on obj1 and later on obj2. In ThreadB’s run method synchronization is reversed, it is first done on obj2 and later on obj1. That may result in a deadlock where t1 gets a lock on obj1 and waiting to acquire a lock on obj2. At the same time obj2 has acquired a lock on obj2 and waiting to acquired a lock on obj1.

Another deadlock Java example shows the scenario where one synchronized method is called from another.

public class DLDemo {
  public synchronized void method1(DLDemo obj){
    System.out.println(Thread.currentThread().getName() + " In Method1");
    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    //Calling another synchronized method
    obj.method2(this);
  }
		 	 
  public synchronized void method2(DLDemo obj2){
    System.out.println("In Method2");
  }

  public static void main(String[] args) {
    DLDemo obj1 = new DLDemo();
    DLDemo obj2 = new DLDemo();
		
    new Thread(new Runnable() {
      public void run() { obj1.method1(obj2); }
    }).start();

    //Thread 2  
    new Thread(new Runnable() {
      public void run() { obj2.method1(obj1); }
    }).start();
  }
}
Output
Thread-0 In Method1
Thread-1 In Method1

In the code there are two instances of DLDemo class, one thread calls the synchronized method method1 using obj1 and another thread calls it using obj2. Which means Thread1 holds a lock on obj1 and Thread2 holds a lock on obj2.

With in the synchronized method method1 there is a call to another synchronized method method2, both of the threads are trying to call method2 with the object whose lock is held by another object thus leading to a deadlock.

How to avoid deadlock in Java

With multi-threading programming deadlock may occur and there is no language support as such to prevent deadlocks. You will have to write your code used by multiple threads carefully to avoid deadlocks. Here we’ll go through the scenarios shown above and see how deadlocks can be avoided in those scenarios.

1. As shown in the previous scenarios one of the reason for the deadlock in Java is the way locks are acquired, if you have nested synchronization then you can acquire the object locks in the same order rather than in reverse order for both threads.

Changed nested synchronization code

class ThreadA implements Runnable{
  private Object obj1;
  private Object obj2;
  ThreadA(Object obj1, Object obj2){
    this.obj1 = obj1;
    this.obj2 = obj2;
  }
  @Override
  public void run() {
    synchronized(obj1){
      System.out.println(Thread.currentThread().getName() + " acquired " + "obj1 lock");
        synchronized(obj2){
          System.out.println(Thread.currentThread().getName() + " acquired " + "obj2 lock");
        }
    }       
  }  
}

class ThreadB implements Runnable{
  private Object obj1;
  private Object obj2;
  ThreadB(Object obj1, Object obj2){
    this.obj1 = obj1;
    this.obj2 = obj2;
  }
  @Override
  public void run() {
    synchronized(obj1){
      System.out.println(Thread.currentThread().getName() + " acquired " + "obj1 lock");
      synchronized(obj2){
        System.out.println(Thread.currentThread().getName() + " acquired " + "obj2 lock");
      }
    }   
  }
}
Output
Thread-0 acquired obj1 lock
Thread-0 acquired obj2 lock
Thread-1 acquired obj1 lock
Thread-1 acquired obj2 lock

As you can see from the output now the deadlock is avoided.

2. Using synchronized block to minimize the synchronization to the critical section code only will also help in avoiding the deadlock in Java.

In the second scenario rather than synchronizing the whole method synchronized block can be used.

public class DLDemo {
  public void method1(DLDemo obj){
    System.out.println(Thread.currentThread().getName() + " In Method1");
    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    synchronized(this){
      //Calling another synchronized method
      obj.method2(this);
    }
  }
		  
  public void method2(DLDemo obj2){
    System.out.println("In Method2");
    synchronized(this){
      System.out.println("In Method2 synchronized block");
    } 
  }

  public static void main(String[] args) {
    DLDemo obj1 = new DLDemo();
    DLDemo obj2 = new DLDemo();
    
    new Thread(new Runnable() {
      public void run() { obj1.method1(obj2); }
    }).start();

    //Thread 2  
    new Thread(new Runnable() {
      public void run() { obj2.method1(obj1); }
    }).start();
  }
}

3- By using static synchronization in Java. If two object instances are used two threads using two separate objects can still enter a synchronized method or block with their separate object locks. Static synchronization helps in this case because the lock will be acquired at the class level then.

How to debug a deadlock in Java

Detecting a deadlock in Java is not easy, even logs may be of little help. If you observe that your multi-threaded code is not performing as well as it was then it may be due to a deadlock and best thing is to get a thread dump of the application and analyze it.

You can use jstack utility to get a thread dump by providing the pid of the Java application. That pid can be obtained by running jps command. For example, if I run the program where deadlock was created due to nested synchronization, then I can get the thread dump using following steps.

1- By using jps command I can get the pid of the Java application.

Jps

5968
7408 DLDemo
13960 Jps

2- Run the jstack command with the pid as argument.

Jstack 7408

3- Get the thread dump and analyze it. Here some of the relevant portion of the thread dump is displayed.

"Thread-1" #11 prio=5 os_prio=0 tid=0x000000001b3e1000 nid=0x145c waiting for monitor entry [0x000000001bade000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.knpcode.ThreadB.run(DLDemo.java:33)
        - waiting to lock <0x00000000d5bfaff0> (a java.lang.Object)
        - locked <0x00000000d5bfb000> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)

"Thread-0" #10 prio=5 os_prio=0 tid=0x000000001b3e0000 nid=0x379c waiting for monitor entry [0x000000001b9de000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.knpcode.ThreadA.run(DLDemo.java:15)
        - waiting to lock <0x00000000d5bfb000> (a java.lang.Object)
        - locked <0x00000000d5bfaff0> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)



"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000004d4c800 nid=0x2b34 in Object.wait() [0x000000001acee000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d5b88ec0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        - locked <0x00000000d5b88ec0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000004d42000 nid=0x6cc in Object.wait() [0x000000001abef000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d5b86b68> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Unknown Source)
        at java.lang.ref.Reference.tryHandlePending(Unknown Source)
        - locked <0x00000000d5b86b68> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)


Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x0000000004d47868 (object 0x00000000d5bfaff0, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x0000000004d4a0f8 (object 0x00000000d5bfb000, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at com.knpcode.ThreadB.run(DLDemo.java:33)
        - waiting to lock <0x00000000d5bfaff0> (a java.lang.Object)
        - locked <0x00000000d5bfb000> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)
"Thread-0":
        at com.knpcode.ThreadA.run(DLDemo.java:15)
        - waiting to lock <0x00000000d5bfb000> (a java.lang.Object)
        - locked <0x00000000d5bfaff0> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)

Found 1 deadlock.

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


You may also like

April 9, 2024

HTTP PUT Method in React - fetch, Axios

In this post we'll see how to use HTTP PUT method from React applications in order to update resources on a server. We'll see how to make PUT requests using both fetch method in Fetch API and Axios with the help of examples.

fetch()- This method is used to call APIs across the network. GET is the default for fetch method.

With fetch() method you pass the URI and the body in case of PUT and it returns a promise that resolves with a Response object.

Fetch syntax for PUT method

fetch('url', {
  method: 'PUT',
  body: JSON.stringify(DATA),
  headers: {                
    'Content-type': 'application/json',                 
  },
}) 
.then(response => response.json())
.then(data => console.log(data))
.catch((error) => console.log(error.message));

Axios- It is a promise-based HTTP Client for node.js and the browser. To make a PUT request using Axios, you can use the axios.put() method.

axios.post(url[, data[, config]])

For API calls JSONPlaceholder is used which is a free fake API for testing and prototyping.

PUT request in React with fetch returning Promise

In the example there is a Component named UpdatePost. With in the component there is a form to fill post data (id, userId, title and body) to update an existing post. When the form is submitted, using fetch method a PUT request is sent with the post data to the given URI (Where postId is added to the URI 'https://jsonplaceholder.typicode.com/posts/:id'). JSONPlaceholder returns the updated post.

UpdatePost.js

import { useState } from "react";

const UpdatePost = () => {
  const [formFields, setFormFields] = useState({
    id: 0,
    title: '',
    body: '',
    userId: 0
  });
  const handleInputChange = (event) => {
    const target = event.target;
    const value = target.value;
    const name = target.name;
  
    setFormFields((prevState) => {
      return {...prevState, [name]: value};
    });
  }
  const formSubmitHandler = (event) => {
    event.preventDefault();
    const url = 'https://jsonplaceholder.typicode.com/posts/' + formFields.id;
    const putOptions = {
      method: 'PUT',
      body: JSON.stringify({...formFields}),
      headers: {'Content-type': 'application/json'}
    }
    fetch(url, putOptions)    
    .then((response) => response.json())
    .then((resData) => console.log('Updated Post ', resData))
    .catch((error) => console.log(error.message));
  }

  return(
    <div className="container">
      <h2>Post</h2>
      <form onSubmit={formSubmitHandler}>
        <div className="mb-3 mt-3">
          <label className="form-label" htmlFor="id">ID: </label>
          <input className="form-control" type="text" placeholder="Enter ID" name="id" id="id" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3 mt-3">
          <label className="form-label" htmlFor="title">Title: </label>
          <input className="form-control" type="text" placeholder="Enter Title" name="title" id="title" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3">
          <label className="form-label" htmlFor="body">Body: </label>
          <input className="form-control" type="text" placeholder="Enter Post Content" name="body" id="body" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3">
          <label className="form-label" htmlFor="userId">User ID: </label>
          <input className="form-control" type="text" placeholder="Enter UserID" name="userId" id="userId" onChange={handleInputChange}></input>
        </div>
        <button className="btn btn-info" type="submit" onClick={formSubmitHandler}>Update Post</button>
      </form>
    </div>
  )
}

export default UpdatePost;

In the code-

  1. useState() hook is used to maintain form data.
  2. fetch() methos is called when the form is submitted, method is set as ‘PUT and as the body form data is sent (Which is the modified data for an existing post).
  3. Content-Type is set as application/json which means that the request body format is JSON.
  4. When you update a resource in JSONPlaceholder, updated post object is returned by the API.
  5. fetch() method returns a Promise, using promise chaining first the response object is converted to JSON data and then that is displayed on the console.
  6. To handle any error there is also a catch method, which just logs the error message.
  7. Note that Bootstrap 5 is used for styling here. Refer Bootstrap with React to know how to install Bootstrap in your React application.
PUT request React example

PUT request using async/await with fetch

Here is the same example which uses async/await to wait for completion of PUT request rather than using Promise with .then chaining. You can use try/catch to handle errors with async/await.

import { useState } from "react";

const UpdatePost = () => {
  const [formFields, setFormFields] = useState({
    id: 0,
    title: '',
    body: '',
    userId: 0
  });
  const handleInputChange = (event) => {
    const target = event.target;
    const value = target.value;
    const name = target.name;

    setFormFields((prevState) => {
        return {...prevState, [name]: value};
    });
  }
  const formSubmitHandler = async (event) => {
    event.preventDefault();
    try{
      const url = 'https://jsonplaceholder.typicode.com/posts/' + formFields.id;
      const putOptions = {
        method: 'PUT',
        body: JSON.stringify({...formFields}),
        headers: {'Content-type': 'application/json'}
      }
      const response = await fetch(url, putOptions);
      if(!response.ok){
        throw new Error('Error while fetching post data');
      } 
      const resData = await response.json(); 
      console.log('Updated Post ', resData)
    }catch(error){
      console.log(error.message);
    }
  }

  return(
    <div className="container">
      <h2>Post</h2>
      <form onSubmit={formSubmitHandler}>
        <div className="mb-3 mt-3">
          <label className="form-label" htmlFor="id">ID: </label>
          <input className="form-control" type="text" placeholder="Enter ID" name="id" id="id" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3 mt-3">
          <label className="form-label" htmlFor="title">Title: </label>
          <input className="form-control" type="text" placeholder="Enter Title" name="title" id="title" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3">
          <label className="form-label" htmlFor="body">Body: </label>
          <input className="form-control" type="text" placeholder="Enter Post Content" name="body" id="body" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3">
          <label className="form-label" htmlFor="userId">User ID: </label>
          <input className="form-control" type="text" placeholder="Enter UserID" name="userId" id="userId" onChange={handleInputChange}></input>
        </div>
        <button className="btn btn-info" type="submit" onClick={formSubmitHandler}>Update Post</button>
      </form>
    </div>
  )
}

export default UpdatePost;

Few points to note in the code-

  1. formSubmitHandler method is async.
  2. You need to wait for the response so await is used with the fetch method.
  3. Await is also used while converting response data to json.
  4. Check for the response status and throw an error if response status is not ok.
  5. Code is enclosed in try/catch block to handle the thrown error.

PUT request using async/await with error message

In the above React fetch method example with async/await, error message is logged to the console. If you want to display the error to the user then you can create one more component for Error. In the UpdatePost component have the state for Error and set the Error in case one is thrown.

ErrorMessage.js

Uses the Bootstrap alert to show the error message.

const ErrorMessage = (props) => {
  return(
    <>
      <div className="alert alert-warning alert-dismissible fade show" role="alert">
        <p>{props.message}</p>
              
        <button type="button" className="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
      </div>
    </>
  )
}
export default ErrorMessage;

UpdatePost.js

Updated to have Error state variable and the logic to show error.

import { useState } from "react";
import ErrorMessage from "./ErrorMessage";

const UpdatePost = () => {
  const [formFields, setFormFields] = useState({
    id: 0,
    title: '',
    body: '',
    userId: 0
  });
  const [error, setError] = useState();
  const handleInputChange = (event) => {
    const target = event.target;
    const value = target.value;
    const name = target.name;

    setFormFields((prevState) => {
      return {...prevState, [name]: value};
    });
  }
  const formSubmitHandler = async (event) => {
    event.preventDefault();
    try{
      const url = 'https://jsonplaceholder.typicode.com/post/' + formFields.id;
      const putOptions = {
        method: 'PUT',
        body: JSON.stringify({...formFields}),
        headers: {'Content-type': 'application/json'}
      }
      const response = await fetch(url, putOptions);
      if(!response.ok){
        throw new Error('Error while fetching post data');
      } 
      const resData = await response.json(); 
      console.log('Updated Post ', resData)
    }catch(error){
      setError(error);
    }
  }
  if(error){
    return (
      <ErrorMessage message={error.message}></ErrorMessage>
    )
  }
  return(
    <div className="container">
      <h2>Post</h2>
      <form onSubmit={formSubmitHandler}>
        <div className="mb-3 mt-3">
          <label className="form-label" htmlFor="id">ID: </label>
          <input className="form-control" type="text" placeholder="Enter ID" name="id" id="id" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3 mt-3">
          <label className="form-label" htmlFor="title">Title: </label>
          <input className="form-control" type="text" placeholder="Enter Title" name="title" id="title" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3">
          <label className="form-label" htmlFor="body">Body: </label>
          <input className="form-control" type="text" placeholder="Enter Post Content" name="body" id="body" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3">
          <label className="form-label" htmlFor="userId">User ID: </label>
          <input className="form-control" type="text" placeholder="Enter UserID" name="userId" id="userId" onChange={handleInputChange}></input>
        </div>
        <button className="btn btn-info" type="submit" onClick={formSubmitHandler}>Update Post</button>
      </form>
    </div>
  )
}

export default UpdatePost;

Now in case something goes wrong while updating an existing post you'll get an error message.

PUT Method in React - fetch, Axios

Using HTTP PUT method in React with Axios

If you want to use Axios library to make HTTP calls then the first thing is to install the Axios library.

Using npm

$ npm install axios

Using yarn

$ yarn add axios

Put request using Axios returning Promise - React Example

Uses the same example as used with fetch where we have a Component named UpdatePost. With in the component there is a form to fill post data (id, userId, title and body) to update an existing post. When the form is submitted, using axios a PUT request is sent with the post data to the given URI (Where postId is added to the URI 'https://jsonplaceholder.typicode.com/posts/:id'). JSONPlaceholder returns the updated post.

Axios serializes JavaScript objects to JSON by default so no need to explicitly do it when using Axios.

import { useState } from "react";
import ErrorMessage from "./ErrorMessage";
import axios from "axios";

const UpdatePost = () => {
  const [formFields, setFormFields] = useState({
    id: 0,
    title: '',
    body: '',
    userId: 0
  });

  const [error, setError] = useState();

  const handleInputChange = (event) => {
    const target = event.target;
    const value = target.value;
    const name = target.name;

    setFormFields((prevState) => {
      return {...prevState, [name]: value};
    });
  }

  const formSubmitHandler = (event) => {
    event.preventDefault();
    const url = 'https://jsonplaceholder.typicode.com/post/' + formFields.id;
    axios.put(url, formFields)
    .then(resData => console.log('Updated Post ', resData.data))
    .catch(error => setError(error));
  }

  if(error){
    return (
      <ErrorMessage message={error.message}></ErrorMessage>
    )
  }
  return(
    <div className="container">
      <h2>Post</h2>
      <form onSubmit={formSubmitHandler}>
        <div className="mb-3 mt-3">
          <label className="form-label" htmlFor="id">ID: </label>
          <input className="form-control" type="text" placeholder="Enter ID" name="id" id="id" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3 mt-3">
          <label className="form-label" htmlFor="title">Title: </label>
          <input className="form-control" type="text" placeholder="Enter Title" name="title" id="title" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3">
          <label className="form-label" htmlFor="body">Body: </label>
          <input className="form-control" type="text" placeholder="Enter Post Content" name="body" id="body" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3">
          <label className="form-label" htmlFor="userId">User ID: </label>
          <input className="form-control" type="text" placeholder="Enter UserID" name="userId" id="userId" onChange={handleInputChange}></input>
        </div>
        <button className="btn btn-info" type="submit" onClick={formSubmitHandler}>Update Post</button>
      </form>
    </div>
  )
}

export default UpdatePost;

Some points to note here-

  1. Axios returns a Promise that resolves to a response object which has a data property containing the fetched data.
  2. With Axios default behavior is to reject every response that returns with a status code that falls out of the range of 2xx and treat it as an error.
  3. Error message gives a quick summary of the error message and the status it failed with.
  4. There is no change in ErrorMessage component. Please refer the above example to get the code for ErrorMessage component.

Using async/await with Axios PUT request - React Example

Here is the same example which uses async/await rather than using Promise with .then chaining. You can use try/catch to handle errors with async/await.

import { useState } from "react";
import ErrorMessage from "./ErrorMessage";
import axios from "axios";

const UpdatePost = () => {
  const [formFields, setFormFields] = useState({
    id: 0,
    title: '',
    body: '',
    userId: 0
  });

  const [error, setError] = useState();

  const handleInputChange = (event) => {
    const target = event.target;
    const value = target.value;
    const name = target.name;

    setFormFields((prevState) => {
      return {...prevState, [name]: value};
    });
  }

  const formSubmitHandler = async (event) => {
    event.preventDefault();
    try{
      const url = 'https://jsonplaceholder.typicode.com/posts/' + formFields.id;
      const resData = await axios.put(url, formFields)
      console.log('Updated Post ', resData.data)
    }catch(error){
      setError(error);
    }
  }

  if(error){
    return (
      <ErrorMessage message={error.message}></ErrorMessage>
    )
  }
  return(
    <div className="container">
      <h2>Post</h2>
      <form onSubmit={formSubmitHandler}>
        <div className="mb-3 mt-3">
          <label className="form-label" htmlFor="id">ID: </label>
          <input className="form-control" type="text" placeholder="Enter ID" name="id" id="id" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3 mt-3">
          <label className="form-label" htmlFor="title">Title: </label>
          <input className="form-control" type="text" placeholder="Enter Title" name="title" id="title" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3">
          <label className="form-label" htmlFor="body">Body: </label>
          <input className="form-control" type="text" placeholder="Enter Post Content" name="body" id="body" onChange={handleInputChange}></input>
        </div>
        <div className="mb-3">
          <label className="form-label" htmlFor="userId">User ID: </label>
          <input className="form-control" type="text" placeholder="Enter UserID" name="userId" id="userId" onChange={handleInputChange}></input>
        </div>
        <button className="btn btn-info" type="submit" onClick={formSubmitHandler}>Update Post</button>
      </form>
    </div>
  )
}

export default UpdatePost;

That's all for the topic HTTP PUT Method in React - fetch, Axios. If something is missing or you have something to share about the topic please write a comment.


You may also like

April 8, 2024

Can we Override start() Method in Java

In some Java interviews there is a question asked can we override start() method in Java. Since this is something you will hardly need to do, so some people do get confused that is it actually possible to override start() method of Thread class or not. Also there is a follow up question will your overridden start() method actually execute the thread and call the run() method or not.

Overriding start method in Java

Yes it is possible to override start() method of the Thread class in Java. Though it is hardly required to do that except for some rare scenarios where you do need some logic to be executed before calling the run() method.

From your overridden start() method ensure that you call super.start() method as Thread class’ start() method is a native method and has the logic to communicate with the OS to schedule the thread to run. Failing to call super.start() will mean run() method won’t be called.

Overriding start method example code

public class MyThread extends Thread {
  @Override
  public void start(){
    System.out.println("In overridden start method");
    // calling parent class start method
    super.start();
  }

  @Override
  public void run() {
    System.out.println("In run method " + "Thread Name - " 
        + Thread.currentThread().getName());
  }

  public static void main(String[] args) {
    Thread t1 = new MyThread();
    t1.start();
  }
}
Output
In overridden start method
In run method Thread Name - Thread-0

That's all for the topic Can we Override start() Method in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

April 7, 2024

Thread Interruption in Java

Thread interrupt is an indication to a thread that it should stop doing what it is currently doing and either terminate or do something else. What a thread does after being interrupted is up to you but the convention is that a thread should be terminated once interrupted.

How thread interruption in Java works

In Java Thread class there is a method interrupt() which interrupts the calling thread. Once the thread is interrupted its interrupt status is set to true and then based on whether the thread is currently blocked or not following activity takes place-

  1. If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared (set to false again) and it will receive an InterruptedException.
  2. If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
  3. If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
  4. If a thread that is not blocked is interrupted, then the thread's interrupt status will be set.

Methods related to thread interruption in Java Thread class

Apart from the method interrupt() already discussed above there are two more methods in java.lang.Thread class related to thread interruption interrupted() and isInterrupted().

  • void interrupt()- Interrupts this thread.
  • static boolean interrupted()- Checks whether the current thread has been interrupted. Also clears the interrupted status of the thread.
  • boolean isInterrupted()- Tests whether this thread has been interrupted. This method doesn't change the interrupted status of the thread in any way.

Thread interruption examples

Thread interruption in Java is generally used to terminate a blocking thread. So you can choose to just return after interrupting a sleeping or waiting thread.

public class InterruptDemo implements Runnable {
	
  @Override
  public void run() {
    for(int i = 0; i < 5; i++){
      System.out.println("Value - " + i);
      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        System.out.println("Thread " + Thread.currentThread().getName() + " interrupted, reason " + e.getMessage());
        System.out.println("Interrupted status- " + Thread.currentThread().isInterrupted());
        return;
      }
    }	
  }

  public static void main(String[] args) {
    Thread t = new Thread(new InterruptDemo());
    t.start();
    t.interrupt();
    System.out.println("In main method - Interrupted status " + t.isInterrupted());
  }
}
Output
In main method - Interrupted status true
Value - 0
Thread Thread-0 interrupted, reason sleep interrupted
Interrupted status- false

In the thread’s run method there is a loop to print number from 1 to 5, after each number display, sleep method is called on the thread. Thread’s interrupt method is also called in the mean time which interrupts the blocked thread. Also you can see that the interrupt status is true after the interrupt() method is called and later the interrupt status is cleared (set to false).

Wrapping and rethrowing the InterruptedException

Rather than just returning as done in the previous example you may choose to wrap the InterruptedException and rethrow it.

public class InterruptDemo implements Runnable {
  @Override
  public void run() {
    for(int i = 0; i < 5; i++){
      System.out.println("Value - " + i);
      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        System.out.println("Thread " + Thread.currentThread().getName() + " interrupted, reason " + e.getMessage());
        System.out.println("Interrupted status- " + Thread.currentThread().isInterrupted());
        throw new RuntimeException("Thread interrupted", e);
      }
    }	
  }

  public static void main(String[] args) {
    Thread t = new Thread(new InterruptDemo());
    t.start();
    t.interrupt();
    System.out.println("In main method - Interrupted status " + t.isInterrupted());
  }
}
Output
In main method - Interrupted status true
Value - 0
Thread Thread-0 interrupted, reason sleep interrupted
Interrupted status- false
Exception in thread "Thread-0" java.lang.RuntimeException: Thread interrupted
	at com.knpcode.InterruptDemo.run(InterruptDemo.java:14)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.knpcode.InterruptDemo.run(InterruptDemo.java:10)
	... 1 more

Interrupting a non-blocking thread

If you interrupt a thread that is not blocking then just the interrupt status of the thread changes. Using the isInterrupted() method you can check the interrupt status of the thread and choose to execute some logic in that condition.

public class InterruptDemo implements Runnable {
  @Override
  public void run() {
    for(int i = 0; i < 5; i++){
      System.out.println("Value - " + i);
      if(Thread.currentThread().isInterrupted()){
        System.out.println("Interrupted status- " + Thread.currentThread().isInterrupted());
      }
    }	
  }

  public static void main(String[] args) {
    Thread t = new Thread(new InterruptDemo());
    t.start();
    t.interrupt();
    System.out.println("In main method - Interrupted status " + t.isInterrupted());
  }
}
Output
In main method - Interrupted status true
Value - 0
Interrupted status- true
Value - 1
Interrupted status- true
Value - 2
Interrupted status- true
Value - 3
Interrupted status- true
Value - 4
Interrupted status- true

As you can see in this case interrupt status remains true, not cleared to false as happens for the blocked threads which are interrupted.

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


You may also like