13

I'm trying a tutorial for a basic react web app and it works perfectly in chrome. Here is my code:

import React, {Component} from 'react';

export default class App extends Component {
  async componentDidMount() {
    const [r1,r2] = await Promise.all([
        fetch('http://api.mywebsite.com/content/cars'),
        fetch('http://api.mywebsite.com/content/aircrafts'),
    ]);
    this.setState({content:await r1.json(),content2: await r2.json()});

  }
  render() {
    if(this.state) {
      console.log(this.state);
    }
    return (
        <div>hello</div>
    )
  }
}

This works exactly as I expect in Chrome - load up the react component, fetch some data, set the state, and print the state to console.

However, this code will not run in Internet Explorer 11. All I get is a blank page, and in my developer tools, I get the error

Expected '}'

When I click on the link to the error, it highlights this segment of code:

  _createClass(App, [{
    key: 'componentDidMount',
    value: async function componentDidMount() {
      var _ref = await Promise.all([fetch('http://new.evermight.com/content/index'), fetch('http://new.evermight.com/content/index')]),
          _ref2 = _slicedToArray(_ref, 2),

With an arrow pointing to the line value: async function componentDidMount() {.

How do I make this work in Internet Explorer 11? I only want setState to fire after the fetch calls and such are complete. I need the await behaviour.


EDIT

I am using webpack to compile my project. And if it helps, here is my package.json file:

{
  "name": "scroll",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "animated": "^0.2.1",
    "es2015": "0.0.0",
    "gsap": "^1.20.3",
    "history": "^4.7.2",
    "jquery": "^3.2.1",
    "react": "^16.1.1",
    "react-dom": "^16.1.1",
    "react-ga": "^2.4.1",
    "react-router-dom": "^4.2.2",
    "react-scripts": "0.9.5",
    "react-transition-group": "^1.2.0",
    "scrollmagic": "^2.0.5",
    "video-element": "^1.0.3"
  },
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.1",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "clean-webpack-plugin": "^0.1.17",
    "css-loader": "^0.25.0",
    "eslint": "^4.13.0",
    "eslint-config-aqua": "^2.0.1",
    "eslint-plugin-react": "^7.5.1",
    "file-loader": "^0.9.0",
    "node-sass": "^3.10.1",
    "sass-loader": "^4.0.2",
    "style-loader": "^0.13.1",
    "uglifyjs-webpack-plugin": "^1.1.6",
    "url-loader": "^0.5.7",
    "webpack": "^3.8.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

And here is my webpack.config.js

var webpack = require('webpack');
var CleanPlugin = require('clean-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  entry: {app:'./src/Index.js'},

  output: {
    filename: '[name].bundle.js',
    chunkFilename: '[id].[hash].bundle.js',
  path: '/var/www/html/public/build',
    publicPath: '/build/'
  },
  plugins: [
        // This plugin minifies all the Javascript code of the final bundle

        new UglifyJsPlugin({
          uglifyOptions:{
            mangle:   true,
            compress: {
                warnings: false, // Suppress uglification warnings
            },
          }
        }),

        new webpack.optimize.CommonsChunkPlugin({
            name:      'main', // Move dependencies to our main file
            children:  true, // Look for common dependencies in all children,
            minChunks: 2, // How many times a dependency must come up before being extracted
        })
  ],
  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' },
      { test: /\.scss$/, loaders: [ 'style-loader', 'css-loader', 'sass-loader' ]},
      { test: /\.(jpg|gif|png|otf|eot|woff|svg|ttf)(\?.*)?$/, loader: "file-loader" }
    ]
  }
}
John
  • 32,403
  • 80
  • 251
  • 422
  • async-await are not supported in IE, you should use promises instead – Shubham Khatri Jan 20 '18 at 19:09
  • 2
    IE11 doesn't support neither async/await nor Promise. But last you can use actually if you'll inject babel polyfill. But we need to understand how exactly you are running your web app. Did you try to use create-react-app? As I remember it's has some polyfills preinstalled from the box. If you don't, do you use webpack? I'm just trying to understand. I mean IE11 also doesn't support classes, so you can't actually run this code 'naked' – Alexey Avdeyev Jan 20 '18 at 19:32
  • @AlexeyAvdeyev Thank you for your suggestion. I added notes under the EDIT section that shows my package.json and webpack.config.js if that helps? – John Jan 20 '18 at 19:36
  • 1
    yes. just add another package from https://babeljs.io/docs/usage/polyfill/ and follow ease guide to inject this in your project. after that you can use Promise example from Shubham Khatri answer. and forget for now about async/await – Alexey Avdeyev Jan 20 '18 at 19:38
  • it looks you installed babel but did not configure webpack to use it – Tamas Hegedus Jan 21 '18 at 00:24

2 Answers2

13

Actually, I did get async and await to work in IE11. In my question, I also had a problem with fetch not being supported in IE11. Here's what I did to solve both problems. I went to my bash terminal and typed this

npm install --save es6-promise
npm install --save-dev babel-polyfill
npm install --save-dev babel-plugin-transform-async-to-generator
npm install --save isomorphic-fetch

Next, I added these two lines to the very beginning of my src/Index.js before any other code because it is my entry point:

import "babel-polyfill";
import "isomorphic-fetch";

Then I ran the webpack command, and now my IE11 supports the code I created with async await and it supports the fetch command.

John
  • 32,403
  • 80
  • 251
  • 422
6

async-await is not supported in IE.

Check the MDN docs

You need to use Promises instead like

 componentDidMount() {
    Promise.all([
        fetch('http://api.mywebsite.com/content/cars'),
        fetch('http://api.mywebsite.com/content/aircrafts'),
    ]).then(([r1, r2]) => {
        this.setState({content:r1.json(),content2: r2.json()});
    })

 }

Also in order to support promises in IE, you need to use a 3rd party Polyfill libraries like BlueBird or use babel-polyfill

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • I tried your solution but got `Promise is undefined` AND some `in Unknown` errors – John Jan 20 '18 at 19:22
  • Sorry for the copy paste error, await was not need in setState – Shubham Khatri Jan 20 '18 at 19:23
  • As it turns out even Promise isn't supported in IE. Check this https://stackoverflow.com/questions/36016327/how-to-make-promises-work-in-ie11 to fix it – Shubham Khatri Jan 20 '18 at 19:25
  • the `babel-polyfill` helped. I did the `npm install --save babel-polyfill`, then I added the line `import "babel-polyfill"` to the top of my `src/Index.js` file, which is my entry file. – John Jan 20 '18 at 19:56
  • 2
    But then afterwards, I got a `fetch is undefined error`. So I then did a `npm install --save isomorphic-fetch` and `npm install --save es6-promise`. And then I added the line `import "isomorphic-fetch"` so my `src/Index.js` immediately after the `import "babel-polyfill"`. That fixed my fetch error. – John Jan 20 '18 at 19:57
  • Actually, I got both async await and fetch to work in IE11. Async just needed the `babel-plugin-transform-async-to-generator`. And fetch worked as described in previous comment. I created a new answer to this question with all the steps that I followed to make everything work in IE11. – John Jan 26 '18 at 02:50