From fbd2763ea61fd5842fdfc95e8c0bd204ca32e1d4 Mon Sep 17 00:00:00 2001 From: Madeorsk Date: Sun, 20 Apr 2025 20:30:27 +0200 Subject: [PATCH] Add assign function to assign properties values using any object, silently ignoring fields which are not properties. --- README.md | 12 ++++++++++++ src/model/model.ts | 16 ++++++++++++++++ tests/model.test.ts | 30 ++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/README.md b/README.md index b17d147..4bd104e 100644 --- a/README.md +++ b/README.md @@ -274,6 +274,18 @@ Get a model class (which has all the sharkitek models' functions) from a model i const model = definedModel.model(modelInstance); ``` +#### `assign(object)` + +Assign fields from a provided object to the model instance properties. Fields which are not properties of the target model are silently ignored. + +```typescript +const alteredModelInstance = definedModel.model(modelInstance).assign({ + anyProperty: "foo", + anotherOne: true, + not_a_property: "will be ignored", +}); +``` + #### `serialize()` Serialize the model. diff --git a/src/model/model.ts b/src/model/model.ts index 618ad48..c676e46 100644 --- a/src/model/model.ts +++ b/src/model/model.ts @@ -382,6 +382,22 @@ export class Model, Identifier ext return cloned.instance; // Returning the cloned instance. } + + /** + * Assign the provided fields to existing properties. + * Fields that cannot be matched to existing properties are silently ignored. + * @param fields The fields to assign to the model. + */ + assign(fields: Partial> & {[field: string]: any}): ModelInstance + { + for (const field in fields) + { // For each field, if it's a property, assign its value. + if ((this.definition.properties as any)?.[field]) + // Set the instance value. + this.instance[field as keyof T] = fields[field]; + } + return this.instance; + } } diff --git a/tests/model.test.ts b/tests/model.test.ts index d6c8393..ef3f34b 100644 --- a/tests/model.test.ts +++ b/tests/model.test.ts @@ -326,4 +326,34 @@ describe("model", () => { expect(TestModel.model.model(clonedDeserializedModel).serialize()).toStrictEqual({ id: 5, label: "testing" }); expect(clonedDeserializedModel.notAProperty.hello).toEqual("world"); }); + + it("assigns properties, ignoring fields which are not properties", () => { + const deserializedArticle = Article.model.parse({ + id: 1, + title: "this is a test", + authors: [ + { id: 52, name: "John Doe", email: "test@test.test", createdAt: "2022-08-07T08:47:01.000Z", active: true, }, + { id: 4, name: "Tester", email: "another@test.test", createdAt: "2022-09-07T18:32:55.000Z", active: false, }, + ], + text: "this is a long test.", + evaluation: "8.52", + tags: [ {name: "test"}, {name: "foo"} ], + comments: [ + { id: 542, author: { id: 52, name: "John Doe", email: "test@test.test", createdAt: "2022-08-07T08:47:01.000Z", active: true, }, message: "comment content", }, + ], + }); + + // Assign title and text, html is silently ignored. + Article.model.model(deserializedArticle).assign({ + title: "something else", + text: "fully new text! yes!", + html: "

fully new text! yes!

", + }); + expect((deserializedArticle as any)?.html).toBeUndefined(); + expect(Article.model.model(deserializedArticle).patch()).toStrictEqual({ + id: 1, + title: "something else", + text: "fully new text! yes!", + }); + }); });