Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[labs/context] @provide decorator does not work with Babel #3806

Closed
augustjk opened this issue Apr 14, 2023 Discussed in #3804 · 2 comments
Closed

[labs/context] @provide decorator does not work with Babel #3806

augustjk opened this issue Apr 14, 2023 Discussed in #3804 · 2 comments

Comments

@augustjk
Copy link
Member

augustjk commented Apr 14, 2023

See discussion below.

Decorators work fine with TS.

With Babel:

@provide() on its own does not work.
@provide() @property() does not work.
@property() @provide actually seems to make the context providing work but value is not accessible from the host component.

Discussed in #3804

Originally posted by jrj2211 April 13, 2023
I have an element that is providing some async loaded data from an API. I have children inside the element consuming the context, which is working.

I need my provider to also use the data being provided in the context, but it the property just comes back undefined?

import { userContext } from './contexts/user.js';

export class UserView extends LitElement {
  @property({ attribute: false })
  @provide({ context: userContext })
  user;

  render() {
    return html`
      <user-contact></user-contact>
      <div>${this.user?.name}</div>
    `;
  }

  async connectedCallback() {
    super.connectedCallback();
    const user = await App.client.service('users').findOne(this.id});
    this.user = user;
    console.log('provider', 'user', user) // not undefined
    console.log('provider', 'user', this.user) // is undefined?
  }
}

Logging out the loaded user, its undefined. The child user-contact that @consumes the userContext, gets the data.

Is this correct? The documentation show adding @property along with @provide, so why isn't the value available in the provider element via this.user?

@augustjk
Copy link
Member Author

Here are some findings after investigating.

The @lit-labs/context decorators make use if decorateProperty()

export const decorateProperty =

When this is used without providing a descriptor and only finisher as it is done with @provide(), in Babel mode this ends up creating the property on the instance with placement: "own" rather than the prototype, so the setter defined in the finisher ends up getting masked. It happened to be that if you do @property() @provide(), the @property() decorator was overriding this behavior and not creating an instance property, allowing the setter to work, but since the @provide() never sets a getter, its value is still not accessible.

When doing @provide() @property(), the finisher defined for @provide() never gets the correct property key as it gets the Symbol() from the @property() decorator. The code that's meant to handle this

// Note, the @property decorator saves `key` as `originalKey`
// so try to use it here.
const key =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(protoOrDescriptor as any).originalKey ??
(protoOrDescriptor as ClassElement).key;
does not actually work as it seems originalKey is not carried over in Babel's implementation for chaining decorators.

I think the single @provide() use for babel is fixable by either making decorateProperty() always set the placement to prototype instead of own, and make sure the @provide() decorator accounts for data descriptors that have writable and value, or have the @provide() implementation just provide the getter/setter with the descriptor option for decorateProperty(). The latter has implications with chaining decorators or when the user provides getter/setter of their own.

Considering that Babel's removing support for the "2018-09" version (babel/babel#12712), I wonder if it's worth our time to even consider fixing this.

cc: @justinfagnani

@rictic
Copy link
Collaborator

rictic commented Jul 6, 2023

Not planning on supporting the nonstandard 2018 Babel transform with context

@rictic rictic closed this as completed Jul 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

2 participants