Prompt user with beforeunload on browser tab close React App

You might have a form created in your React App that user might try to close by closing the tab, reloading the page or close the browser directly. You might want to prompt the user in this case to alert them that there might be unsaved changes that might be lost.

The following example binds the “beforeunload” event to the App Component and the unbinds it on the componentwillunmount event. This could apply to form component and not the Parent App component.

export default class App extends React.Component {
  constructor(props) {
    this.handleUnload = this.handleUnload.bind(this);

  componentDidMount() {
    window.addEventListener('beforeunload', this.handleUnload);

  componentWillUnmount() {
    window.removeEventListener('beforeunload', this.handleUnload);

  handleUnload(e) {
    var message = "\o/";

    (e || window.event).returnValue = message; //Gecko + IE
    return message;


You can even call an API to make the necessary changes required for your App at the back-end before the browser unloads the Page. But please be careful in case the user decides to cancel and stays on the page. I’ve tested the above code on Google Chrome and Edge Chromium.

I haven’t really found a way that let’s you customize the prompt message in the modern browsers. And there is no way to capture the Leave/Cancel (stay) button click events. Let me know if you find a way to capture these events. However, I believe the browser has given control to the user more than the Page in case of unload.

How to create XML in JavaScript

Though this is pretty rarely used scenario, I tried to create XML document using the DOMParser. Since JavaScript handles XML with ‘XML DOM objects’, you can create such an object by parsing a string containing serialized XML.

Below code is just a method that I implemented which returns the XML object:

getXMLString() {
    var parser = new DOMParser();
    var xml = "<?xml version=\"1.0\" standalone=\"yes\" ?>";
    xml = xml + "<PlanInfo UserId=\"" + this.props.UserId + "\" UpdatedBy=\"" + Number(localStorage.getItem("userId")) + "\" UpdatedOn=\"" + this.formatDate(new Date()) + "\"><Plans>";
    for(var i=0; i<15; i++) {
      xml = xml + "<Plan ID=\"" + this.props.myColl[i].dataId + "\" Comment=\"" + this.props.myColl[i].comment + "\" />";
    xml = xml + "</Plans></PlanInfo>";
    var xmlDoc = parser.parseFromString(xml, "application/xml");
    return xmlDoc;

The above code is an implementation in ReactJS that reads the props from redux and loop through the data to create the XML. Please note that XML tag names are case-sensitive.

Below is the sample output:

<?xml version="1.0" standalone="yes" ?>
<PlanInfo UserId="234" UpdatedBy="123" UpdatedOn="13 May 2020">
        <Plan ID="1" Comment="test comments"/>
	<Plan ID="2" Comment="test comments2"/>

When you have obtained an XML DOM object (e.g. xmlDoc above), you can use methods to manipulate it as shown below:

var node = xmlDoc.createElement("Plan");
var elem = xmlDoc.getElementsByTagName("Plans");

Format Date in javascript to dd mmm yyyy

There is a simple way to write a function in Javascript to format the date as dd mmm yyyy. I’m using this method in my ReactJS code to simply format the date and set the state with the returned string wherever required.

formatDate(date) {
    if (date !== undefined && date !== "") {
      var myDate = new Date(date);
      var month = [
      var str = myDate.getDate() + " " + month + " " + myDate.getFullYear();
      return str;
    return "";

You can call this method from your JS code like this:

formatDate(new Date());

How to create Material UI Dialog with OK Cancel

Install the latest Material UI core package from npm:

npm install @material-ui/core @latest

Import the following components required for the Dialog box:

import React from "react";
import { withStyles } from "@material-ui/core/styles";
import Checkbox from "@material-ui/core/Checkbox";
import Dialog from "@material-ui/core/Dialog";
import DialogContent from "@material-ui/core/DialogContent";
import DialogActions from '@material-ui/core/DialogActions';
import { DialogContentText } from "@material-ui/core";
import MuiDialogTitle from "@material-ui/core/DialogTitle";
import CloseIcon from '@material-ui/icons/Close';
import Typography from '@material-ui/core/Typography';
import Button from "@material-ui/core/Button";
import IconButton from '@material-ui/core/IconButton';

Add the following styles for the Dialog content and buttons:

const styles = theme => ({
    root: {
      margin: 0,
      padding: theme.spacing(2),
    closeButton: {
      position: 'absolute',
      right: theme.spacing(1),
      top: theme.spacing(1),
      color: theme.palette.grey[500],
    dialogText: {

The following component will be used in the Dialog Title bar:

const DialogTitle = withStyles(styles)(props => {
    const { children, classes, onClose, ...other } = props;
    return (
      <MuiDialogTitle disableTypography className={classes.root} {...other}>
        <Typography variant="h6">{children}</Typography>
        {onClose ? (
          <IconButton aria-label="close" className={classes.closeButton} onClick={onClose}>
            <CloseIcon />
        ) : null}

Add the class Component that will render the Dialog box:

class MyForm extends React.Component {
    constructor(props) {
	  this.handleChange = this.handleChange.bind(this);
	  this.handleDialogClose = this.handleDialogClose.bind(this);
	  this.handleDialogOK = this.handleDialogOK.bind(this);
	  this.state = {
		dialogText: '',
        isDialogOpen: false,
		isChecked: false
	handleDialogOK() {
      console.log('Clicked OK!');
        isDialogOpen: false
	handleDialogClose() {
        isDialogOpen: false
	handleChange(e) {
      const target =;
	  const value = target.checked;
		isChecked: value,
		isDialogOpen: true
	  }, ()=> {console.log('Open Dialog')});
	render() {
      const { classes } = this.props;
      return (
			<Checkbox id="chkOpenDialog" onChange={this.handleChange} checked={this.state.isChecked}></Checkbox>
              <DialogTitle id="customized-dialog-title" onClose={this.handleDialogClose}>
                  {"Message from Application"}
                <DialogContentText id="alert-dialog-description" className={classes.dialogText}>
                  <Button color="primary" onClick={this.handleDialogOK}>
                  <Button color="primary" onClick={this.handleDialogClose}>

export default withStyles(styles, { withTheme: true })(MyForm);

Setting the isDialogOpen to true on clicking checkbox will open the Dialog box with OK and Cancel Action buttons. Each Action button has it’s own handler.

Download word file using axios get from WebAPI

The below code is using axios get method with Headers token to be passed with credentials which in this case would be Windows Authentication to the WebAPI.

The response returned by the Promise contains the header “content-disposition” which has the name of the file being downloaded.

The content-disposition header value is as below:

attachment; filename="SomeFile.docm"; filename*=UTF-8''SomeFile.docm

The content-type required for this file from the API is:


The returned response has the blob in the data property which then requires to be converted to a downloadble link. The filename is being extracted from the content-disposition header.

const HTTP1 = axios.create({
                  withCredentials: true
const response = HTTP1.get('http://path/worddoc?userid=<someid>', {
		        headers: {
		          'token': 'xxxxx'
				responseType: 'blob'
		      }).then((response) => {
				const headerval = response.headers['content-disposition'];
				var filename = headerval.split(';')[1].split('=')[1].replace('"', '').replace('"', '');
				const downloadUrl = window.URL.createObjectURL(new Blob([]));
				const link = document.createElement('a');
				link.href = downloadUrl;
				link.setAttribute('download', filename); //any other extension

For IE11 browser, downloading blob response type directly does not work. A workaround for this is to recognize the browser via User Agent modify the above code in Javscript for IE:

var ua = window.navigator.userAgent;
var msie = ua.indexOf(".NET ");

if(msie>0) {
          window.navigator.msSaveBlob(new Blob([]), filename);

Using Fetch with React example async await

I’ve created a basic React App as described in my previous post. This is just a demo on how you can use fetch API to load data in the componentDidMount() lifecycle method with/without
async/await. I’ve not used any error handling yet.

The basic structure of the React App contains index.js and index.html files. The code is added to my Github profile.

Replace the code of the index.js file as below:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));

Create App.js file under the src directory and add the below code:

import React, { Component } from "react";
import MyComp from "./MyComp";
export default class App extends Component {
    render() {
        return (
          <div className="App">
            <MyComp />

It’s time to create MyComp which is the sample component that will call the placeholder JSON API to show the list of users using Fetch GET request.

The code for MyComp is as shown below:

import React from "react";
export default class MyComp extends React.Component {
    constructor(props) {
        this.state = {
            usernames : []
    componentDidMount() {
            .then(res => res.json())
            .then(json => this.setState({ usernames: json }));
    render() {
                Hey guys!
                { => (
                    <li key={user.username}>
                    Hello, {user.username}

Run the App using as below:

npm start

The above code will now use async/await. It is a clean asynchronous way to call the API by writing unblocking code just like promises and callbacks.

Run the following command in the terminal:

npm i @babel/preset-env @babel/plugin-transform-runtime @babel/runtime --save

Replace the componentDidMount() code as below:

async componentDidMount() {
        const response = await fetch(``);
        const json = await response.json();
        this.setState({ usernames: json });

The async function which in this case is the componentDidMount contains the await expression that pauses the execution of the async function. It waits until the passed Promise is resolved. It then resumes the async function’s execution and evaluates as the resolved value.

Run the App again to see the results which are the same in this case.

You can also include headers and credentials in the Fetch call as shown below:

const myHeaders = new Headers();
myHeaders.append('token', 'xxxx');
const response = fetch(`http://someurl/home/details?username=someuser`, {
	credentials: 'include',
	headers: myHeaders,
	cors: 'cors'

Prevent form submission with Javascript button click

Suppose you have a html form and you need to prevent the submission of a form based on the input provided in a textbox.
The html input type should be “button” in this case.

<input type="button" value="Submit" onclick="checkInput();">

Below is the Javascript code that gets called on the button click:

function checkInput() {
	var form = document.getElementById('form1');
	var str = document.getElementById("txtBox").value; 
	if (str == "") {
		var r = confirm("Do you want to add the detail in the input box?");
		if (r == true) {
		} else {
	else {

The above code will submit the form if field is not blank. If the field is blank, focus gets set to the textbox field named “txtBox” when clicking on OK button. Clicking on Cancel will again submit the form.

Difference between href with blank pound and javascript void 0

The below options I have tried out in a Classic asp application for the anchor link href attribute in HTML:

Using href=”” will reload the current page.

Using href=”#” will scroll the current page to the top.

href=”javascript: void(0)” will do nothing. However, this fires the onbeforeunload event. I had a problem in my classic asp application that was causing the progress bar which was called in the onbeforeunload event, to show up every time the href was clicked to open a pop-up window.

You can get the same effect of javascript: void(0) by returning false from the click event handler of the anchor with either of the other two methods as well.

Use the below anchor link:

<a id="my-link" href="#">Link</a> 

and then bind an event handler to the click listener somewhere in my javascript like:

document.getElementById('my-link').onclick = function(){ 
    // Do something
    return false;

This way, since you’re using #, even if the user has javascript disabled, the page won’t reload (it will just scroll to the top), and it’s a lot cleaner looking than javascript: void(0).

Also, this does not fire the window.onbeforeunload event.

Handle client side routes with IIS on Page refresh React App

When trying to handle Client side routing for your React App hosted on IIS say using react-router-dom, you might need to handle situations where users access specific sections of your App like http://testapp/courses. Users might even save these URLs in their favorites and try to access them later.

This problem is not known while debugging the App in localhost until you host the App on an IIS Server. Since your React App is a Single Page Application (SPA), the Server is unaware of any static files like courses and will give 404 error. To solve this, send all your requests back to IIS with URL rewrite to the index.html static file and let the React App handle the routing.

First install the URL Rewrite module on the IIS Server. Then create a web.config file for your App or create a new one with code as shown below:

<?xml version="1.0" encoding="UTF-8"?>
			<rule name="ReactRouter Routes" stopProcessing="true">
			  <match url=".*" />
			  <conditions logicalGrouping="MatchAll">
				<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
			  <action type="Rewrite" url="index.html" />


This should work well for your App when the user tries to access a Client side route and refresh the page or when trying to access the route later.

Host create-react-app on IIS Server

Install the latest version of nodejs from site.

Install create-react-app globally as below:

npm i -g create-react-app

Create the react-app in the folder of your choice on your local machine:

create-react-app hell-world-app

Modify the index.js file as shown below:

import React from "react";
import ReactDOM from "react-dom";

const element = <h1>Hello World</h1>;


ReactDOM.render(element, document.getElementById("root"));

Test the app on localhost:

npm start

Build the production optimized app:

npm run-script build

Copy the contents of the build folder and paste it on the Server at the location where you want to host it e.g. C:\data\testreactapp. Open IIS on the Server and add Website by right-clicking on Sites as shown below. Give it the required hostname or port to test it in browser e.g. http://helloworldapp.

The index.html file is already present at the Physical path created by the build which the IIS Server will look for as the default document.

Authentication can be Anonymous for testing purpose. However, please change as per your requirement. The AppPool by default runs with CLR 4.0 version and Integrated mode.

This approach is especially helpful when you have a back-end .Net Web API hosted on the same IIS Server to improve speed.