olavim / objection-cursor

Cursor based pagination plugin for Objection.js
MIT License
30 stars 8 forks source link

Support for Customer Serializers #20

Closed Smtih closed 4 years ago

Smtih commented 4 years ago

I'm trying to have objection automatically take one of my columns values and wrap it in a utility class. In order to do this I'm using $parseDatabaseJson and $formatDatabaseJson to construct a class when it's parsed, and to serialise it when it's formatted.

This seems to work well, however in the cursor, it JSON stringifies the class version and then attempts to pass the objection version into a where clause causing issues.

Having a look through the code, you already have the concept of a TypeSerializer which I think could handle this issue? Perhaps there's another way?

olavim commented 4 years ago

Could you provide a code example of what you're trying to do? It would help me understand what you're asking.

Smtih commented 4 years ago
class ModelWithResource extends PaginatedModel {
  $parseDatabaseJson(json: Pojo): Pojo {
    json = super.$parseDatabaseJson(json);
    if (json.resource) {
      json.resource = new Resource(json.resource);
    }
    return json;
  }

  $formatDatabaseJson(json: Pojo): Pojo {
    json = super.$formatDatabaseJson(json);
    if (json.resource instanceof Resource) {
      json.resource = json.resource.toString();
    }

    return json;
  }
}

The main issue when doing this is that you can't pass a Resource instance into a where statement.

When making a query and i have orderBy resource The first page will load fine however the following would be in the cursor

(json){<Json.Strigified version of Resource instance>} Which on the second page will be rehydrated, and used in a whereClause to filter out all entries that were before the cursor.

olavim commented 4 years ago

I think you could leverage the existing JSON type serializer just fine. If you add a toJSON method to your Resource class, you can tell JSON.stringify what to stringify. So maybe something like this?

toJSON() {
  return this.resource; // The column data you gave in the constructor
}
Smtih commented 4 years ago

Ah, I didn't know this was a thing. Perfect. Thanks for your teachings!

olavim commented 4 years ago

@Smtih I considered this a bug. The serializers should take custom model formatters such as yours into account when serializing/deserializing the cursor. This is now fixed in v1.2.2, and you don't need the toJSON method in your class anymore.