Skip to content
This repository has been archived by the owner on Feb 7, 2024. It is now read-only.

Error when using @ProvideReactive: Cannot redefine property #277

Open
PeterPanZH opened this issue Nov 5, 2019 · 20 comments
Open

Error when using @ProvideReactive: Cannot redefine property #277

PeterPanZH opened this issue Nov 5, 2019 · 20 comments
Labels

Comments

@PeterPanZH
Copy link

When I upgrade vue-property-decorator to 8.3.0, it comes with a TypeError: Cannot redefine property on line Object.defineProperty(rv[reactiveInjectKey], provide.managedReactive[i], {.
I think it was related to #249 and caused by #264 .

const InjectKey = Symbol();

@Component
class ParentComponent extends Vue {
    @ProvideReactive(InejctKey) foo: any = {};
}

@Component
class ChildComponent extends Vue {
    @InjectReactive({
        from: InejctKey,
        default: ({})
    })
    readonly foo!: any;
}
@fluidsonic
Copy link

fluidsonic commented Nov 5, 2019

I just ran into the same issue. When a second instance of a component that uses @ProvideReactive is being created TypeError: Cannot redefine property is thrown.

Downgrading to 8.2.2 fixes the issue.

@gmoneh
Copy link
Contributor

gmoneh commented Nov 15, 2019

Yes. The ProvideReactive/InjectReactive feature is broken in 8.3.0 after this change. In my child components, I get:
Injection "reactiveInject" not found

@micene09
Copy link

any news here? I'm getting this error too.

@Mrminfive
Copy link

set inject: [] in Component options

const InjectKey = Symbol();

@Component({ inject: [] })
class ParentComponent extends Vue {
    @ProvideReactive(InejctKey) foo: any = {};
}

@Component
class ChildComponent extends Vue {
    @InjectReactive({
        from: InejctKey,
        default: ({})
    })
    readonly foo!: any;
}

because

// inject parent reactive services (if any)
if (!Array.isArray(componentOptions.inject)) {
    componentOptions.inject = componentOptions.inject || {};
    componentOptions.inject[reactiveInjectKey] = { from: reactiveInjectKey, default: {}};
}

@PeterPanZH
Copy link
Author

@Mrminfive That works in 8.3.0. For a temporarily solution.

@Jonny-china
Copy link

@Mrminfive thanks!

@LYnnProspery
Copy link

set inject: [] in Component options

const InjectKey = Symbol();

@Component({ inject: [] })
class ParentComponent extends Vue {
    @ProvideReactive(InejctKey) foo: any = {};
}

@Component
class ChildComponent extends Vue {
    @InjectReactive({
        from: InejctKey,
        default: ({})
    })
    readonly foo!: any;
}

because

// inject parent reactive services (if any)
if (!Array.isArray(componentOptions.inject)) {
    componentOptions.inject = componentOptions.inject || {};
    componentOptions.inject[reactiveInjectKey] = { from: reactiveInjectKey, default: {}};
}

it will lead the injects in component get undefined

@tsofist
Copy link

tsofist commented May 30, 2020

Any updates for this issue?

it will lead the injects in component get undefined

This (new) problem affected from v8.4.0

I'm rollback to v8.3.0 😞

@redakzter01
Copy link

redakzter01 commented Jul 30, 2020

I just ran into the same issue. When a second instance of a component that uses @ProvideReactive is being created TypeError: Cannot redefine property is thrown.

Downgrading to 8.2.2 fixes the issue.

Same here again ...with version 9.0.0 😕

Edit: Ok, i dont't know why but in package.json i got version 9.0.0. Since the last one is 8.4.2 i changed to it and now seems to work fine. The affected version i were using before was 8.3.0.

@Joebayld
Copy link

Joebayld commented Sep 2, 2020

I'm having this issue on v8.5.1. Is everyone still just using 8.3.0 for now?

I can look into a PR if anyone has insight as to what exactly broke..

@GrzegorzKazana
Copy link

FYI, this would be fixed in PR #330.

@bodograumann
Copy link

bodograumann commented Sep 24, 2020

Same problem here on 9.0.0.
This makes me wonder. Could I use the following as a replacement?

@Provide() foo = Vue.observable({ key: value });

Update: The above seems to work fine for me.

@rodsscg
Copy link

rodsscg commented Oct 1, 2020

Same problem here (v.8.4.0)

@spb-web
Copy link

spb-web commented Oct 27, 2020

Same problem here on 8.5.1

@seamory
Copy link

seamory commented Nov 5, 2020

Same problem here (v.8.5.2).
How terrible is it.

@seamory
Copy link

seamory commented Nov 5, 2020

Same problem here on 9.0.0.
This makes me wonder. Could I use the following as a replacement?

@Provide() foo = Vue.observable({ key: value });

Update: The above seems to work fine for me.

actually, you no need to use Vue.observable to create a observer object. just let foo = {key: value}.

@kaorun343 kaorun343 added the bug label Nov 20, 2020
@latel
Copy link

latel commented Nov 25, 2020

any progress?

@Cyclodex
Copy link

Cyclodex commented Dec 4, 2020

I think it is fixed now in latest: 9.1.2, isn't it?
At least in my project it looks better now...

@marked42
Copy link

This issue is fixed since v9.0.2. Refer to this https://github.com/kaorun343/vue-property-decorator/blob/v9.0.2/src/vue-property-decorator.ts#L69.

function produceProvide(original: any) {
  let provide: provideFunc = function (this: any) {
    let rv = typeof original === 'function' ? original.call(this) : original
    rv = Object.create(rv || null)
    // set reactive services (propagates previous services if necessary)
    rv[reactiveInjectKey] = Object.create(this[reactiveInjectKey] || {})
    for (let i in provide.managed) {
      rv[provide.managed[i]] = this[i]
    }
    for (let i in provide.managedReactive) {
      rv[provide.managedReactive[i]] = this[i] // Duplicates the behavior of `@Provide`
      Object.defineProperty(rv[reactiveInjectKey], provide.managedReactive[i], {
        enumerable: true,
        get: () => this[i],
      })
    }
    return rv
  }
  provide.managed = {}
  provide.managedReactive = {}
  return provide
}

Provided reactive object is changed from

rv[reactiveInjectKey] = this[reactiveInjectKey] || {}

to

rv[reactiveInjectKey] = Object.create(this[reactiveInjectKey] || {})

rv[reactiveInjectKey] actually refers to VueComponent.options.inject so it's always the same object got called by Object.defineProperty which causes this issue.

After this fix, every time a newly created object is provided to avoid Object.defineProperty called multiples on same object.

By the way, it seems to fix another issue, but coincidentally fixes this issue too, which explains why this issue is still open.

@qisi007
Copy link

qisi007 commented Dec 22, 2020

我将vue-property-decorator更新到9.1.2解决了此问题

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests