SoftwareBrothers/adminjs-mongoose

Unable to unset optional fields on update

lucasaba opened this issue · 0 comments

When dealing with optional fields, adminjs-mongoose doesn't unset removed data.

Here's an example. I'm using io-ts to validate. Suppose I have the following codec:

export const ArticleCodec = t.intersection([
  uuid: t.string,
  title: t.string,
  t.partial({
    numberOfLike: NumberFromString, // This is because data is passed as a string
    avgRating: NumberFromString,
  }),
]);
export type ArticleType = t.TypeOf<typeof ArticleCodec>;

I also have the following mongoose schema:

export const ArticleSchema = new Schema<ArticleType>(
  {
    uuid: { type: String, required: true },
    title: { type: String, required: true },
    numberOfLike: Number,
    avgRating: Number,
  },
  { timestamps: true }
);

Lastly, I have the following resource:

const ArticleResource = (): ResourceWithOptions => ({
  [...]
  actions: {
      edit: {
        before: async (request) => {
          const { method, payload } = request;
          const unflattened = flat.unflatten(payload);
          const validated = ArticleCodec.decode(unflattened);

          if (validated._tag === "Left") {
            [...]
          }
          return request;
[...]

Suppose I create an article and erroneously set numberOfLike instead of avgRating. I have the following document in MongoDB:

{
   uuid: "e5436802-0e8f-428e-933f-7abc7d50b86c",
   title: "An amazing article",
   numberOfLike: 4
}

When I edit the entity, the request I receive has the following payload:

  "uuid": "e5436802-0e8f-428e-933f-7abc7d50b86c",
  "title": "An amazing article",
  "numberOfLike": "",
  "avgRating": 4,

This data is then passed to the update function which sets all data not un-setting numberOfLike.

Mongoose, also, converts the empty string to the number 0. So, the resulting document is the following:

{
   uuid: "e5436802-0e8f-428e-933f-7abc7d50b86c",
   title: "An amazing article",
   numberOfLike: 0,
   avgRating: 4,
}

While I would expect this document:

{
   uuid: "e5436802-0e8f-428e-933f-7abc7d50b86c",
   title: "An amazing article",
   avgRating: 4
}

I've been able to get around this problem by deleting the original document e removing all empty strings from the request payload but... I wonder if it could be possible to unset the optional values during the update.