Let's move to another important section, which is the default value for the model, in that sense, we want to set initial values for the model, for example, we want to set the published
column to be false
if the column itself does not exist.
However, this should only be done in the create
operation, not in the update
operation as we might later want to remove that column from that certain document.
Now let's go and add it.
// src/core/database/model/model.ts
import { Document, ModelDocument } from "./types";
export default abstract class Model extends CrudModel {
// ...
/**
* Define Default value data that will be merged with the models' data
* on the create process
*/
public defaultValue: Document = {};
}
We defined an empty object here which will be used to store the default values for the model.
Now let's update the save
method to apply the default values.
// src/core/database/model/model.ts
import { Document, ModelDocument } from "./types";
import Is from "@mongez/supportive-is";import {
areEqual,
except,
get,
merge,
only,
set,
} from "@mongez/reinforcements";
export default abstract class Model extends CrudModel {
// ...
/**
* Perform saving operation either by updating or creating a new record in database
*/
public async save(mergedData: Document = {}) {
this.merge(mergedData);
// check if the data contains the primary id column
if (this.data._id && !this.isRestored) {
// perform an update operation
// check if the data has changed
// if not changed, then do not do anything
if (areEqual(this.originalData, this.data)) return;
this.data.updatedAt = new Date();
await queryBuilder.update(
this.getCollectionName(),
{
_id: this.data._id,
},
this.data,
);
} else {
// creating a new document in the database
const generateNextId =
this.getStaticProperty("generateNextId").bind(Model);
// check for default values and merge it with the data
this.checkDefaultValues();
// if the column does not exist, then create it
if (!this.data.id) {
this.data.id = await generateNextId();
}
const now = new Date();
// if the column does not exist, then create it
if (!this.data.createdAt) {
this.data.createdAt = now;
}
// if the column does not exist, then create it
if (!this.data.updatedAt) {
this.data.updatedAt = now;
}
this.data = await queryBuilder.create(
this.getCollectionName(),
this.data,
);
}
}
/**
* Check for default values
*/
protected checkDefaultValues() {
// if default value is empty, then do nothing
if (Is.empty(this.defaultValue)) return;
// merge the data with default value
this.data = merge(this.defaultValue, this.data);
}
}
We added in the create process a new method called checkDefaultValues
which will be called before the data is saved to the database.
In this method, we checked if the default value property is empty, if it is, then we do nothing, otherwise, we merge the default value with the data.
The merge will merge data deeply, so if the data already has a column, then it will not be overridden.
Now let's give it a try!
// src/app/users/models/user.ts
import { Model } from "core/database";
import { Document } from "core/database/model/types";
export default class User extends Model {
/**
* Collection name
*/
public static collectionName = "users";
/**
* {@inheritDoc}
*/
public defaultValue: Document = {
published: true,
};
}
We added published
column to be true by default.
Now let's create a new user and see what happens.
// src/app/users/routes.ts
import User from './models/user';
const user = await User.create({
name: 'hasan',
});
console.log(user.data); // {id: 1, name: 'hasan', published: true, _id: '...', createdAt: '...', updatedAt: '...'}
We'll see something like this:
And that's it!
๐จ Conclusion
In this section, we learned how to set default values for the model, and we also learned how to use the merge
method to merge data deeply.
๐ Project Repository
You can find the latest updates of this project on Github
๐ Join our community
Join our community on Discord to get help and support (Node Js 2023 Channel).
๐๏ธ Video Course (Arabic Voice)
If you want to learn this course in video format, you can find it on Youtube, the course is in Arabic language.
๐ฐ Bonus Content ๐ฐ
You may have a look at these articles, it will definitely boost your knowledge and productivity.
General Topics
- Event Driven Architecture: A Practical Guide in Javascript
- Best Practices For Case Styles: Camel, Pascal, Snake, and Kebab Case In Node And Javascript
- After 6 years of practicing MongoDB, Here are my thoughts on MongoDB vs MySQL
Packages & Libraries
- Collections: Your ultimate Javascript Arrays Manager
- Supportive Is: an elegant utility to check types of values in JavaScript
- Localization: An agnostic i18n package to manage localization in your project
React Js Packages
Courses (Articles)
Top comments (0)