vegidio
vegidio

Reputation: 912

Using Typescript decorators with Parse SDK JS

I'm using Parse SDK JS in my Typescript project and I created a model class Person, extending Parse.Object, that will be used to same data on the server:

import * as Parse from 'parse/node'

class Person extends Parse.Object
{
    @ParseField
    name: string

    @ParseField
    age: number

    constructor() {
        super('Person')
    }
}

And I also created a property decorator called @ParseField that will inject a getter and setter on each field with the code to properly assign and retrieves the values from a Parse.Object.

The @ParseField decorator looks like this:

import * as Parse from 'parse/node'

function ParseField<T extends Parse.Object>(target: T, key: string): void
{
    const getter = () => {
        return target.get(key)
    }

    const setter = (value: unknown) => {
        target.set(key, value)
    }

    Object.defineProperty(target, key, {
        get: getter,
        set: setter,
        enumerable: true,
        configurable: true
    })
}

And finally, I try to save the Person class in the Parse Server:

const p = Person()
p.name = 'John'
p.age = 30
p.save().then(obj => console.log(obj))

But when the Parse.Object is saved on the server the fields name and age are undefined. I put some breakpoints in the setter of @ParseField and I can see that it's called when I assign some value, like p.name = 'John' or p.age = 30.

Does anybody know what's wrong in my implementation?

Upvotes: 1

Views: 626

Answers (1)

Morten Moeller
Morten Moeller

Reputation: 1

I happen to hit this when looking for the answer. Challenge with the decorator above is that target is the object prototype and not the instance, so you're calling set/get on the wrong object.

This decorator works for me:

export function ParseField<T>(target: Parse.Object, key: string): void
{
    Object.defineProperty(target, key, {
        get: function () {
            return this.get(key)
        },
        set: function (value: T) {
            this.set(key, value)
        },
        enumerable: true,
        configurable: true
    });
}

Upvotes: 0

Related Questions