vue-property-decorator icon indicating copy to clipboard operation
vue-property-decorator copied to clipboard

Error when using @ProvideReactive: Cannot redefine property

Open PeterPanZH opened this issue 4 years ago • 20 comments

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;
}

PeterPanZH avatar Nov 05 '19 05:11 PeterPanZH

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.

fluidsonic avatar Nov 05 '19 15:11 fluidsonic

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

gmoneh avatar Nov 15 '19 18:11 gmoneh

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

micene09 avatar Nov 18 '19 12:11 micene09

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: {}};
}

Mrminfive avatar Nov 26 '19 11:11 Mrminfive

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

PeterPanZH avatar Nov 27 '19 08:11 PeterPanZH

@Mrminfive thanks!

Jonny-china avatar Feb 29 '20 06:02 Jonny-china

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

LYnnProspery avatar May 20 '20 10:05 LYnnProspery

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 😞

tsofist avatar May 30 '20 10:05 tsofist

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.

redakzter01 avatar Jul 30 '20 00:07 redakzter01

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..

Joebayld avatar Sep 02 '20 00:09 Joebayld

FYI, this would be fixed in PR #330.

GrzegorzKazana avatar Sep 15 '20 17:09 GrzegorzKazana

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.

bodograumann avatar Sep 24 '20 15:09 bodograumann

Same problem here (v.8.4.0)

rodsscg avatar Oct 01 '20 23:10 rodsscg

Same problem here on 8.5.1

spb-web avatar Oct 27 '20 17:10 spb-web

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

seamory avatar Nov 05 '20 07:11 seamory

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}.

seamory avatar Nov 05 '20 07:11 seamory

any progress?

latel avatar Nov 25 '20 18:11 latel

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

Cyclodex avatar Dec 04 '20 09:12 Cyclodex

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.

marked42 avatar Dec 10 '20 11:12 marked42

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

qisi007 avatar Dec 22 '20 06:12 qisi007