96

Below piece of code does not work in IE 11, it throws a syntax error in the console

g.selectAll(".mainBars")
    .append("text")
    .attr("x", d => (d.part == "primary" ? -40 : 40))
    .attr("y", d => +6)
    .text(d => d.key)
    .attr("text-anchor", d => (d.part == "primary" ? "end" : "start"));

Using d3.js bipartite chart for visualization

This code causing the issue in above statement d=>(d.part=="primary"? -40: 40)

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
prakashkadakol
  • 1,227
  • 1
  • 14
  • 29
  • 22
    IE11 does not support the arrow notation for anonymous functions. Rewrite it as `function (d) { return d.part == "primary" ? -40 : 40; }`. – Phylogenesis Oct 24 '16 at 10:23
  • 1
    @Phylogenesis: Not all arrow functions are anonymous. This one isn't, for instance: `var f = () => "foo";` – T.J. Crowder Oct 24 '16 at 10:26
  • 2
    See [here for which browsers support this syntax](http://caniuse.com/#feat=arrow-functions) – Liam Oct 24 '16 at 10:26
  • 2
    ^^ ... or [the docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Browser_compatibility). – Teemu Oct 24 '16 at 10:26
  • As a bonus, it doesn't even support the `=>` comparison operator (as in `if (a=>0)`). (if anyone was googling that and landed here, like me) – David Balažic Feb 01 '19 at 10:16
  • 2
    @David Balažic Your code is wrong. `if (a=>0)` is always true. This is because what you did was create a function, not a comparison and functions are truthy. `if (a<=0)` would be the correct way to write that. – user3654410 Apr 04 '19 at 20:31
  • @user3654410 it works as expected in Firefox and Chrome – David Balažic Apr 05 '19 at 17:52
  • `a=>0` is a function that always returns 0. Write it in your console now `x = a=>0` and inspect x. Or try `(a=>0)()`. All comparison operators are supported in all browsers. – user3654410 Apr 09 '19 at 13:51
  • `=>` is not a comparison function. It's an arrow function if the browser supports it, otherwise it's a syntax error. – Suncat2000 Sep 15 '20 at 18:30

5 Answers5

130

You're using arrow functions. IE11 doesn't support them. Use function functions instead.

Here's Babel's translation of that to ES5:

g.selectAll(".mainBars").append("text").attr("x", function (d) {
  return d.part == "primary" ? -40 : 40;
}).attr("y", function (d) {
  return +6;
}).text(function (d) {
  return d.key;
}).attr("text-anchor", function (d) {
  return d.part == "primary" ? "end" : "start";
});

Since none of the code uses this, you don't have to worry about preserving arrow function this behavior (since traditional functions get their this by how they're called, but arrow functions close over this). But if the code did use this and you wanted it to behave like an arrow function would, you'd want to use the usual techniques for that.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 4
    don't forget about `this`: `var f = (a) => {a.some1(); this.some2();};` to `var f = function(a) {a.some1(); this.some2();}.bind(this);` – user1742529 Jun 27 '18 at 09:50
  • To clarify @user1742529's comment, the arrow function automatically binds `this` where `function(){...}` does not. In systems like VueJS, it will cause issues. `function(){...}.bind(this)` is more similar to arrow functions. – Nathan Goings Jul 13 '21 at 18:15
  • @user1742529 & Nathan - None of the code in the question uses `this`, hence no need to do anything to preserve it. But I've added a paragraph. – T.J. Crowder Jul 13 '21 at 18:17
22

Avoid use of arrow functions if you need to support IE 11 as it is not supported

Change those to regular functions and your code should work as you expect

g.selectAll(".mainBars").append("text").attr("x",function(d) { 
  return d.part=="primary"? -40: 40;
}).attr("y",function(d){
  return +6;
}).text(function(d) { 
  return d.key;
}).attr("text-anchor", function(d) { 
  return d.part=="primary"? "end": "start";
});
Felipe Sabino
  • 17,825
  • 6
  • 78
  • 112
21

In general, before arrow functions were arrow functions, they were regular JS functions. So with IE11 we just have to take a step back in time

var fruits=["apple","banana","orange"];

var modernResult=fruits.find(e => e.includes("nana"));
console.log(modernResult);

var IEresult=fruits.find(function(e){return e.includes("nana")});
console.log(IEresult);

Szél Lajos
  • 449
  • 4
  • 11
  • 1
    This code doesn't resemble the code in the question at all (and "don't use arrow functions" says nothing that every other answer hasn't already said) – Quentin May 17 '19 at 13:34
  • 11
    True, however this question is the first search result for "arrow function not working in IE" and I gave a simple and less specific (more general) explanation. But I understand it's against the rules, apologies. – Szél Lajos May 17 '19 at 20:58
1

IE doesn't support the arrow notation as of now but there is a handy and fast way for transpiling your ES6 codes to ES5.1 for working in IE. visit the Babel website then paste your codes in the left box and copy the right box code that is transpiled to the earlier version of JavaScript.

For example, your code is transpiled to:

"use strict";

g.selectAll(".mainBars").append("text").attr("x", function (d) {
   return d.part == "primary" ? -40 : 40;
}).attr("y", function (d) {
   return +6;
}).text(function (d) {
   return d.key;
}).attr("text-anchor", function (d) {
   return d.part == "primary" ? "end" : "start";
});
zainul
  • 108
  • 12
AmerllicA
  • 29,059
  • 15
  • 130
  • 154
0

Internet Explorer(IE) doesn't support the ES6 functions at all, but you could install BabelJS. But you can also write the vanillaJS functions instead.

For example:

const hasBrownEyes = eye.color === "brown" ? true : false

Or just vanilla.js:

var hasBrownEyes = false; // default answer, it will be overwritten if it has a brown eye

if (eye.color === "brown") {
    return true;
}

Valdemar Vreeman
  • 177
  • 2
  • 16