How do you fix the "Leading decorators must be attached to a class declaration" error?

Leading decorators must be attached to a class declaration

Howdy, trying to get ember-table going. Copying component.js from the documentation into a component.js file in my app. No matter what I get an error that states, “Leading decorators must be attached to a class declaration”. Here’s the code.

import { computed } from "@ember/object";

@computed
get columns() {
  return [
    { name: 'A', valuePath: 'A', width: 180 },
    { name: 'B', valuePath: 'B', width: 180 },
    { name: 'C', valuePath: 'C', width: 180 },
    { name: 'D', valuePath: 'D', width: 180 },
  ];
}

@computed
get rows() {
  return [
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
  ];
}

What’s the right move here?

I think the assumption in the docs is that you’d add that into a component definition, but in your snippet it looks like you might have only that content in your component file?

Specifically, tweak your snippet to something like:

import { computed } from "@ember/object";
import Component from "@ember/component";

export default class extends Component {
  @computed
  get columns() {
    return [
      { name: 'A', valuePath: 'A', width: 180 },
    ];
  }

  @computed
  get rows() {
    return [
      { A: 'A', B: 'B', C: 'C', D: 'D' },
    ];
  }
}

I think computed needs () at the end?

Nope. Everything but the Ember Data decorators has always worked without the parents, and those may have been updated by now as well.

This solution clears the leading errors problem but creates an unexpected character '@' (Fatal) error, which throws this in Console.

Uncaught Error: Assertion Failed: computed decorators must return an instance of an Ember ComputedProperty descriptor, received function COMPUTED_DECORATOR(target, key, propertyDesc, maybeMeta, isClassicDecorator$$1) {
      true && !(true
      /* EMBER_NATIVE_DECORATOR_SUPPORT */
      || isClassicDecorator$$1) && (0, _debug.assert)('Native decorators are not enabled without the EMBER_NATIVE_DECORATOR_SUPPORT flag', true || isClassicDecorator$$1);
      true && !(isClassicDecorator$$1 || !propertyDesc || !propertyDesc.get || propertyDesc.get.toString().indexOf('CPGETTER_FUNCTION') === -1) && (0, _debug.assert)("Only one computed property decorator can be applied to a class field or accessor, but '" + key + "' was decorated twice. You may have added the decorator to both a getter and setter, which is unecessary.", isClassicDecorator$$1 || !propertyDesc || !propertyDesc.get || propertyDesc.get.toString().indexOf('CPGETTER_FUNCTION') === -1);
      let meta$$1 = arguments.length === 3 ? (0, _meta2.meta)(target) : maybeMeta;
      desc.setup(target, key, propertyDesc, meta$$1);
      return {
        enumerable: desc.enumerable,
        configurable: desc.configurable,
        get: DESCRIPTOR_GETTER_FUNCTION(key, desc)
      };
    }
    at Object.assert (index.js:163)
    at computed.js:30
    at decorator.js:43
    at component.js:32
    at Array.reduce (<anonymous>)
    at _applyDecoratedDescriptor (component.js:31)
    at Module.callback (component.js:115)
    at Module.exports (loader.js:106)
    at Module._reify (loader.js:143)
    at Module.reify (loader.js:130)

They make it look so simple in the docs, I wish it worked that way. :man_facepalming:

On the other hand, if I add what’s missing into the documentation’s example, I still get the Parsing error: Unexpected character '@' (Fatal) problem in Atom, but an entirely different error at localhost.

So, this…

import { computed } from "@ember/object";
import Component from "@ember/component";

export default class extends Component {
  @computed
  get columns() {
    return [
      { name: 'A', valuePath: 'A', width: 180 },
      { name: 'B', valuePath: 'B', width: 180 },
      { name: 'C', valuePath: 'C', width: 180 },
      { name: 'D', valuePath: 'D', width: 180 },
    ];
  }

  @computed
  get rows() {
    return [
      { A: 'A', B: 'B', C: 'C', D: 'D' },
      { A: 'A', B: 'B', C: 'C', D: 'D' },
      { A: 'A', B: 'B', C: 'C', D: 'D' },
      { A: 'A', B: 'B', C: 'C', D: 'D' },
      { A: 'A', B: 'B', C: 'C', D: 'D' },
      { A: 'A', B: 'B', C: 'C', D: 'D' },
      { A: 'A', B: 'B', C: 'C', D: 'D' },
      { A: 'A', B: 'B', C: 'C', D: 'D' },
      { A: 'A', B: 'B', C: 'C', D: 'D' },
      { A: 'A', B: 'B', C: 'C', D: 'D' },
      { A: 'A', B: 'B', C: 'C', D: 'D' },
    ];
  }

Produces this…

Good times.

The snippet you posted (and the compile error message) seem to indicate that there isn’t a closing } for the component class?

Also, I don’t know what I’m talking about because I don’t use Atom and I haven’t played around with Octane much but I wouldn’t expect Atom to recognize Ember decorators properly yet so I wouldn’t trust the Atom syntax checker very much…

1 Like

Good catch on the closing curly brace. Fixed… Sadly, we’re back to ye ol’ Parsing error: ... '@', which is more than an Atom problem. It shows up in terminal directly after you ember s and Console says…

Uncaught Error: Assertion Failed: computed decorators must return an instance of an Ember ComputedProperty descriptor, received function COMPUTED_DECORATOR(target, key, propertyDesc, maybeMeta, isClassicDecorator$$1) {
      true && !(true
      /* EMBER_NATIVE_DECORATOR_SUPPORT */
      || isClassicDecorator$$1) && (0, _debug.assert)('Native decorators are not enabled without the EMBER_NATIVE_DECORATOR_SUPPORT flag', true || isClassicDecorator$$1);
      true && !(isClassicDecorator$$1 || !propertyDesc || !propertyDesc.get || propertyDesc.get.toString().indexOf('CPGETTER_FUNCTION') === -1) && (0, _debug.assert)("Only one computed property decorator can be applied to a class field or accessor, but '" + key + "' was decorated twice. You may have added the decorator to both a getter and setter, which is unecessary.", isClassicDecorator$$1 || !propertyDesc || !propertyDesc.get || propertyDesc.get.toString().indexOf('CPGETTER_FUNCTION') === -1);
      let meta$$1 = arguments.length === 3 ? (0, _meta2.meta)(target) : maybeMeta;
      desc.setup(target, key, propertyDesc, meta$$1);
      return {
        enumerable: desc.enumerable,
        configurable: desc.configurable,
        get: DESCRIPTOR_GETTER_FUNCTION(key, desc)
      };
    }
    at Object.assert (index.js:163)
    at computed.js:30
    at decorator.js:43
    at component.js:32
    at Array.reduce (<anonymous>)
    at _applyDecoratedDescriptor (component.js:31)
    at Module.callback (component.js:115)
    at Module.exports (loader.js:106)
    at Module._reify (loader.js:143)
    at Module.reify (loader.js:130)

Was able to clear the build errors thusly…

import Component from '@ember/component';
import { computed } from '@ember/object';

export default Component.extend({
  columns: computed(function() {
    return [
      { name: 'A', valuePath: 'A', width: 180 },
      { name: 'B', valuePath: 'B', width: 180 },
      { name: 'C', valuePath: 'C', width: 180 },
      { name: 'D', valuePath: 'D', width: 180 },
    ];
}),

rows: computed(function() {
  return [
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
    { A: 'A', B: 'B', C: 'C', D: 'D' },
  ];
})
});

Console is not impressed.

index.js:163 Uncaught Error: Assertion Failed: computed decorators must return an instance of an Ember ComputedProperty descriptor, received function COMPUTED_DECORATOR(target, key, propertyDesc, maybeMeta, isClassicDecorator$$1) {
      true && !(true
      /* EMBER_NATIVE_DECORATOR_SUPPORT */
      || isClassicDecorator$$1) && (0, _debug.assert)('Native decorators are not enabled without the EMBER_NATIVE_DECORATOR_SUPPORT flag', true || isClassicDecorator$$1);
      true && !(isClassicDecorator$$1 || !propertyDesc || !propertyDesc.get || propertyDesc.get.toString().indexOf('CPGETTER_FUNCTION') === -1) && (0, _debug.assert)("Only one computed property decorator can be applied to a class field or accessor, but '" + key + "' was decorated twice. You may have added the decorator to both a getter and setter, which is unecessary.", isClassicDecorator$$1 || !propertyDesc || !propertyDesc.get || propertyDesc.get.toString().indexOf('CPGETTER_FUNCTION') === -1);
      let meta$$1 = arguments.length === 3 ? (0, _meta2.meta)(target) : maybeMeta;
      desc.setup(target, key, propertyDesc, meta$$1);
      return {
        enumerable: desc.enumerable,
        configurable: desc.configurable,
        get: DESCRIPTOR_GETTER_FUNCTION(key, desc)
      };
    }
    at Object.assert (index.js:163)
    at computed.js:30
    at decorator.js:43
    at component.js:32
    at Array.reduce (<anonymous>)
    at _applyDecoratedDescriptor (component.js:31)
    at Module.callback (component.js:115)
    at Module.exports (loader.js:106)
    at Module._reify (loader.js:143)
    at Module.reify (loader.js:130)

Cue George Strait “I Hate Everything”.

For anyone following along at home, decided to abandon ember-table in favor of ember-light-table. All the errors, particularly around Typescript, just weren’t worth it for me. Was able to get it up and running thanks to this tutorial.

Cheers!

You mention “errors around TypeScript” but didn’t specify any upthread. Can you elaborate on what problems you had there? It’s possible there’s stuff the Ember TypeScript crew can do to address the pain points you ran into, including by helping the authors of ember-table with what they’re shipping.