ciena-blueplanet / ember-prop-types

Improved property management for Ember apps and addons.
http://ciena-blueplanet.github.io/ember-prop-types/
MIT License
80 stars 36 forks source link

getDefaultProps() breaks the native class model of Ember Components. #183

Open ariesshrimp opened 5 years ago

ariesshrimp commented 5 years ago

BUG REPORT

Summary

getDefaultProps() breaks the native class model of Ember Components.

Expected Behavior

class Example extends Component {
  layout = hbs`<p>{{this.example}}</p>`
  propTypes = {
    example: PropTypes.string
  }
  getDefautProps() {
    return {
      example: "this string should be set as the value of this.example"
    }
  }
}
{{-- <p>this string should be set as the value of this.example</p> --}}
<Example/>

{{-- <p>something else</p> --}}
<Example @example="something else"/>

Actual Behavior

{{-- TypeError --}}
<Example @example="something else"/>
prop-types.js:112 Uncaught (in promise) TypeError: defaults.forEach is not a function
    at Example.init (prop-types.js:112)
    at Example.superWrapper (utils.js:366)
    at Example.init (component-prop-types.js:21)
    at Example.superWrapper [as init] (utils.js:366)
    at initialize (core_object.js:87)
    at Function.create (core_object.js:684)
    at FactoryManager.create (container.js:545)
    at CurlyComponentManager.create (glimmer.js:5437)
    at Object.evaluate (runtime.js:1494)
    at AppendOpcodes.evaluate (runtime.js:70)

Possible Solution

Steps to Reproduce

https://codesandbox.io/embed/54ojpz0rox

ember new my-app -b @ember/octane-app-blueprint
cd my-app && ember install ember-prop-types
# add component as shown in above examples
ember serve # runtime error in browser

Context

I want type checking of props passed to my components in templates. Static type checking is not there yet for ember templates. So it's gotta be run-time. But I don't want to be forced to choose between run-time checks and class syntax

Environment

EWhite613 commented 5 months ago

We moved off this in native class model as we just use typescript to define the interface and

class Example extends Component {
  layout = hbs`<p>{{this.example}}</p>`
  @argument example: string = "this string should be set as the value of this.example"
}

and the glimmer approach is to go through args so we have something like

interface ExampleArgs {
  example: string
}
class Example extends Component<ExampleArgs> {
  layout = hbs`<p>{{this.example}}</p>`
  example: string

  get example (): string {
  return this.args.example ?? 'this string should be set as the value of this.example'
  }
}