Failed to register controller error on older version of browsers

Hi there,

I see this error in console: Failed to register controller: xxx. SyntaxError: Unexpected token =

Example browser versions: Chrome v64, Safari v13 etc.

Error occurs when using static values or static targets.

It works fine on latest version of browsers, but not on older ones, and a few of our customers have reported this, which means there is a good number of people still use those versions, since they are not very old.

Looking at the Stimulus installation documentation:

Browser Support

Stimulus supports all evergreen, self-updating desktop and mobile browsers out of the box. Stimulus 3+ does not support Internet Explorer 11 (but you can use Stimulus 2 with the @stimulus/polyfills for that).

To be honest I don’t understand what that means and cannot find any other information anywhere.

Please help…

Are you using any tools to finalize your assets before deploying?

see also:

Also, have you tried using Stimulus 2 as suggested in the docs?

Just install the polyfill package using npm or importmap and then put import @stimulus/polyfills before import controllers.

I’m using standard Rails 7 with default gems such as:

gem 'importmap-rails'
gem 'turbo-rails'
gem 'stimulus-rails'

Same issue is present in development environment as well as production on Heroku.

Looking at the supported browsers in the link above, it looks like it should work, but it’s not the case.

The other link to Stack Overflow link, I’m not sure if that is relevant?

have you tried using Stimulus 2 as suggested in the docs?

No, because I feel more comfortable to use the latest version, unless no option.

You could try changing to a static get method:

export default class extends Controller {
- static targets = [ "query", "errorMessage", "results" ]
+ static get targets() {
+   return [ "query", "errorMessage", "results" ]
+ }
 // …
}

Oh! amazing, that works. You saved me! Thanks so much!!

So what is the explanation behind? Why should one use the other one then, when it breaks on older browsers, even though not very old? Similarly, are we risking anything by making the switch?

Static Methods

Browsers initially added support for static methods

class Shape {
  static color() {
    return 'blue';
  }
}

Shape.color() //=> 'blue'

or with a getter method (don’t need parens when calling)

class Shape {
  static get color() {
    return 'blue';
  }
}

Shape.color //=> 'blue'

see: Browser Supporting: static methods

Static Fields

They eventually added support for static fields

class Shape {
  static color = 'blue';
}

Shape.color //=> 'blue'

see: Browser Supporting: static fields

Use static fields or static methods?

The static keyword defines a static method or field for a class. Both static methods and fields are still valid and can even be used together

class Shape {
  static color = 'blue';

  static getColor() {
    return this.color;
  }

  getMessage() {
    return `Shape is of ${this.color} color` ;
  }
}

Shape.color //=> 'blue'
Shape.getColor() //=> 'blue'

const myShape = new Shape()
myShape.getMessage() //=> "Shape is of blue color"

Possible downsides I can think or are 1) field is simpler (one liner). And 2) fields are cached as a class variable, where the method is evaluated on every call. For this scenario my guess is the performance difference is likely negligible.

Thanks again for nice explanation!
So if I switch to static method, is it possible that future versions of browser will not work?
I’m just thinking should we stay with the latest version (static field), in which case a few users will be at harm, but if I move to static method, performance issue as you mentioned, and also fearness if future browser stops working.
What would you suggest?

While a static method getter can mimic a static field, and static field cannot dynamically calculate a value like a static getter method. They both serve different purposes. I don’t see static field as a replacement for static methods. I’m not on the committee to decide the javascript standards, but I can’t imagine them removing them anytime soon.

In my application market, I’m comfortable requiring customers to use updated browsers, so we just stick with static fields. I have worked in markets where customers were far behind in upgrading and we had to make different decisions. Good luck on the decision.

Thanks! I also prefer to stay up-to-date and use what is officially being guided. In this case because hotwired documentation is using static field so I will keep that.

I wonder if it is possible to show a message to the visitors in the case of using unsupported browser?