Make React App compatible with IE11

IE11 is still among the most popular browsers in the world. Though Microsoft is promoting Edge Browser on Chromium engine. Many organizations have still not moved on to new offerings or taking their own time. Meanwhile, if you need to make your React Application compatible with IE11, check the steps below:

  1. Create the app, follow this post, if not already done.
  2. Add import 'react-app-polyfill/ie11'; as the first line in index.js file.
  3. For common standard functions like Array.find() that are not supported in IE 11 add import 'react-app-polyfill/stable'. This should be the 2nd line in index.js file.
  4. In package.json copy the production browserlist to development so you can test in IE11 and all other browsers that will work in production. Just add "ie 11" at the end of both production and development, browserlist section into package.json
  5. Delete the node_modules/.cache directory.
//index.js file:
import "react-app-polyfill/ie11";
import "react-app-polyfill/stable";
//browsers list in package.json file in reference to #4:
"browserslist": {
    "production": [
      "not dead",
      "not op_mini all",
      "IE 11"
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version",
      "IE 11"

If you are also using arrow functions so you’ll also need babel to update that for you. The babel-plugin-transform-arrow-functions is your best solution for this. Please check the documentation here.

you might still face some issues in your functionality like additional spaces added by Material UI date control which fails in IE11 but not other browsers. This might need to be taken care of individually on operations using that date value.

Setup React-Native for iOS and Android on Mac with VS Code

The very first step to start development in React-Native is to install the right tools to setup the environment correctly. I’m working on MacOS Catalina and I already have Xcode 11 installed on my machine which is one of the pre-requisites to run the iOS App.

Install the following dependencies for React-Native:


The recommended way to install Node is using Homebrew from your Terminal:

brew install node

Watchman: In react-native, Watchman watches the source code for any changes and rebuilds them.

brew install watchman

Install XCode from App Store.

Cocoapods: This is the Dependency Manager for iOS & Mac projects.

sudo gem install cocoapods

This requires you to enter system password.

Install Visual Studio Code for Mac from here. You might face issues on Mac OS Catalina to run VS Code due to Notarization requirements. You can check out this post for more details.

Create the folder inside say your Documents folder on your Mac as below:

mkdir Apps

Open VS Code and open New Terminal and type the following command to create a new React-Native App:

react-native init MyApp
cd MyApp
cd ios
pod install

Come back to the MyApp folder and run the below command to run your App in the iOS simulator:

react-native run-ios

This will install and launch the App in your iOS simulator. The first time might be very slow. It might be helpful to launch your simulator beforehand.

Running on Android:

Install the Android Studio from here, which will install the Android SDK and the required emulator. I’m using the Android 10 emulator for Pixel XL.

react-native run-android

Open the MyApp folder in VS Code to make further changes.


Running the Android App causes issues while launching the Emulator. The error message is: React Native adb reverse ENOENT

Starting with macOS Catalina, your Mac uses zsh as the default login shell and interactive shell. You can make zsh the default in earlier versions of macOS as well.

So on your Mac:

1 – Open your .zshrc file:

open ~/.zshrc

2 – if .zshrc file doesn’t exist, you need to create one & open again(Step 1)

touch ~/.zshrc

3 – Add this to your .zshrc file

export ANDROID_HOME=/Users/<username>/Library/Android/sdk
export PATH=/Users/<username>/Library/Android/sdk/platform-tools:$PATH

4 – Save and close

5 – Compile your changes

source ~/.zshrc

& make sure to restart your terminal.

Run the command in the Terminal and you’ll see something like below if everything is fine:


Android Debug Bridge version 1.0.41

Version 30.0.0-6374843

Installed as /Users/<username>/Library/Android/sdk/platform-tools/adb

You can also run the code in your VS Code Terminal and see the same output.

The path to Android SDK is available in the Configure button -> SDK Manager (at the bottom right) when you launch Android Studio.

Run VS Code on MacOS Catalina

Due to notarization requirements, currently you may face issue while opening Visual Studio code on MacOS Catalina. To resolve this, go to

System Preferences -> Security & Privacy. Click the lock to make changes -> Provide your password. You’ll get a notification at the bottom that the “App was blocked from opening because it is not from an identified developer”.

click ‘open anyway’.

Check the screen-shot below:

This would open Visual Studio code on your Mac.

Here is the Visual Studio Code Requirements Page:

Here is the Apple notarising documentation:

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.

Upload file in ReactJS to WebAPI

Create a new React App using create-react-app as explained in this Post. The sample ReactJS code is available here.

In the index.js file change the code as below:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

For the App.js file, change the code as below:

import React from 'react';       
import './App.css';
import Fileupload from './FileUpload'
function App() {    
  return (    
    <div className="App">    
export default App;

Now comes the FileUpload component as FileUpload.js:

import React from 'react';
import axios from 'axios';

class Fileupload extends React.Component {

    constructor(props) {    
            this.state = {    
                    file: '',    

    async submit(e) {    
        const url = `http://url`;    
        const formData = new FormData();    
        formData.append('body', this.state.file);    
        const config = {    
            headers: {    
                'content-type': 'multipart/form-data',
                'token': 'xxx'                
        const HTTP = axios.create({
            withCredentials: true

        //return post(url, formData, config);
        return, formData, config);
    setFile(e) {    
        this.setState({ file:[0] });    

    render() {    
        return (    
                <div className="container-fluid">    
                        <form onSubmit={e => this.submit(e)}>    
                                <div className="col-sm-12 btn btn-primary">    
                                        File Upload    
                                <h1>File Upload</h1>    
                                <input type="file" onChange={e => this.setFile(e)} />    
                                <button className="btn btn-primary" type="submit">Upload</button>    
export default Fileupload

Here I’m using axios to call the API via Post request. Passing the credentials in the call with create.
The token part is optional in the Headers, you can add/remove headers based on your requirement.

From the WebAPI end, I’m using .Net core. You can receive the file in the Action method as below:

public IActionResult UploadForm([FromQuery] string username)
	var request = HttpContext.Request;
	if (request.Form.Files.Count > 0)
		filename = request.Form.Files[0].FileName;
		extension = filename.Substring(filename.LastIndexOf(".")).ToLower();
		if (!string.IsNullOrEmpty(extension) && extension.Equals(".docx"))
			using (var memoryStream = new MemoryStream())
				// Upload the file if less than 2 MB
				if (memoryStream.Length < 2097152)
					string check = Service.CheckifValid(username);
					if (check.Equals("ok"))
						//Process the stream and pass the data to the back-end in the Service Layer.
						result = Service.UploadStream(memoryStream, filename, extension, username);
						return Ok(check);
					return BadRequest("File size too large");
			return BadRequest("File format not recognised.");
	//Other ToDos...

How to use Server.MapPath in core

Server.MapPath is not available in core. Instead, you can use IWebHostEnvironment interface to access any physical contents kept in the specified path.

Below is the Controller code using the IWebHostEnvironment ContentRootPath property which gets the absolute path to the directory that contains the Application content files:

public class DocumentController : ControllerBase
	private IDocumentService offService = null;
	private readonly IWebHostEnvironment _host;

	public DocumentController(IDocumentService offService, IWebHostEnvironment host)
		this.offService = offService;
		this._host = host;
	public IActionResult ExportToFile([FromQuery] int UserId)
		var username = HttpContext.User.Identity.Name.Split('\\')[1].ToString();
		//get the memoryStream by passing the absolute path:
		MemoryStream memoryStream = offService.GetWordStream(_host.ContentRootPath);
		memoryStream.Position = 0;
		return File(memoryStream, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "File.docx"); // returns a FileStreamResult

Use the path in the File IO methods, example below:

File.Copy(path + "\\DocPath\\File.docm", strFileName);

In the debug mode, this path is the WebAPI Project absolute path to the directory. During runtime, this path is the absolute path where the files are hosted on the Server.

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);

How to add folders in .net core webapi to Publish directory

When you add a folder in your project, your .csproj file gets modified as shown below:

	<Folder Include="AppData\" />
	<Folder Include="OfflineFiles\2019\" />

To add a folder to the Publish directory with some pre-existing contents, add the below ItemGroup in your .csproj file:

	<Content Include="OfflineFiles\**">

If you have a folder without any pre-existing content, add the below Target action in the .csproj file:

<Target Name="CreateAppDataFolder" AfterTargets="AfterPublish">
	<MakeDir Directories="$(PublishUrl)AppData" Condition="!Exists('$(PublishUrl)AppData')" />

If you check the WebPublishMethod (.pubxml file under Properties folder) which in this is case is FileSystem, the publishUrl contains the directory where the files are published:

<Project ToolsVersion="4.0" xmlns="">
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />

I’m using .net core 3.1 for the above method. This method might vary in other versions of .net core.