graphiti-api/spraypaint.js

Add Typecasting for attributes

Opened this issue · 7 comments

The lack of typecasting on attributes is preventing the ability to override getters and setters for attributes when using typescript.

Is this for things like casting a date string to a Date? Yeah, I just worked around that with a hack that didn't feel good.

I have a branch with working typecasting (string dates to Date, etc), just need to dot some I's and cross some T's. A bit preoccupied with some other work, but should be able to get it out in the next couple weeks. I can also push up the branch if anyone wants to PR and bring it home!

hupf commented

Hi @richmolj, I suppose you were talking about this branch here: https://github.com/richmolj/spraypaint.js/commits/coercion

I've also stumbled on this shortcoming of Spraypaint.js with the same use case: to convert date strings into date objects and vice-versa. It would really be nice to have some sort of an extension point to transform attribute values when deserializing/serializing them.

The implementation in the branch with the extendable AttributeTypeRegistry looks promising! What is the state of the (almost two year old) branch and what are the "I's to dot and the T's to cross"?

Currently I've implemented a workaround using an additional getter and setter for each date attribute:

@Model()
class Todo extends ApplicationRecord {
  static jsonapiType = "todos";

  @Attr({ persist: true })
  dueAt: string;

  get dueAtDate(): Date {
    return parseISO(this.dueAt);
  }

  set dueAtDate(date: Date) {
    this.dueAt = formatISO(date);
  }
}

Since we generate the models from the schema, it's not tedious for us to do this. But the downside is, that we have to refer to dueAtDate instead of dueAt. Also for each access of dueAtDate a new date object is instanciated and returned.

Initially I guessed that the AttributeOptions.name would be the name of the actual JSON attribute (unfortunately these options are not documented), but the following doesn't work:

@Model()
class Todo extends ApplicationRecord {
  static jsonapiType = "todos";

  @Attr({ name: 'due_at', persist: true })
  rawDueAt: string;

  get dueAt Date {
    return parseISO(this.rawDueAt);
  }

  set dueAt(date: Date) {
    this.rawDueAt = formatISO(date);
  }
}

How do you handle this currently?

Hey @hupf - thanks for taking a look at this. I think that branch mostly just needed the additional types (and specs) and some testing around users adding their own custom types. IIRC I think we also needed to better test some of the writing/filtering logic.

For us, it ended up being less important. We basically hack around it with custom setters and getters as well. But I would love to see that branch become reality if you wanted to bring it over the line with a PR ❤️

Since we generate the models from the schema, it's not tedious for us to do this.

👀 Would love to see anything that you have in this arena if you can share!

Since we generate the models from the schema, it's not tedious for us to do this.

👀 Would love to see anything that you have in this arena if you can share!

Definite +1 for this as we were talking about doing something similar

Any news on this?