42-Nodejs Course 2023: Saving Models
Hasan Zohdy
Posted on November 6, 2022
So, we did some good methods in our model to manipulate our model data, but we didn't save it yet. So, let's do it.
You didn't make any check for updates, right?
Yes, i'm reminding you, we should keep our packages up to date, so, let's do it.
yarn update
If there are any updates, then install it and let's proceed to the next step.
Saving the model
The save method will work as follows:
If the data contains an id
field, then it will update the data, otherwise, it will create a new one.
Also, we need to check if the data has been modified or not, so if the data is not modified, then we will not save it.
// src/core/database/model/model.ts
export default abstract class Model extends CrudModel {
// ...
/**
* Save the model data
*/
public async save(mergedData: Document = {}) {
// we can pass data to be updated
this.merge(mergedData);
// get primary column
const primaryIdColumn = this.getStaticProperty("primaryIdColumn");
// if the primary column exists in the data object
// then perform update operation
// otherwise, create a new record in database
if (this.data[primaryIdColumn]) {
// check if the document data is changed
// if it is the same, then skip the update process
if (areEqual(this.data, this.originalData)) return;
// update the document
await queryBuilder.update(
this.getCollectionName(),
{
[primaryIdColumn]: this.data[primaryIdColumn],
},
this.data,
);
} else {
// generate new id
// the bind method is important here so the `this` can have a context to be taken from which is the Model.
const generateNextId = this.getStaticProperty("generateNextId").bind(Model);
this.data.id = await generateNextId();
// update the current document data to have it with the `_id` column
this.data = await queryBuilder.create(
this.getCollectionName(),
this.data,
);
}
}
}
Let's split it into parts:
The method surely must be a async
method.
The save method can accept a mergedData
object, which will be merged with the current data object, this will allow us to pass the data to be updated in our model.
const user = new User;
await user.save({
name: 'hasan'
});
Or we can just save the model without passing any data.
const user = new User({
name: 'hasan'
});
await user.save();
Next we got the primary column using the getStaticProperty
method, why? because the column is static, so we can get it from the class itself.
Next, we checked, does the data object contains that id, if so then the user is trying to update the data, otherwise, he is trying to create a new one.
If the user is trying to update the data, then we need to check if the data is changed or not, if it is not changed, then we will not update the data, because it is not necessary.
We're using areEqual function to check if the data is changed or not by comparing the original data with current data.
Next, we're using the update
method from the queryBuilder
to update the data, and we're passing the primary column value to the where
clause.
If the user is trying to create a new one, then we need to generate a new id for the user, and then we need to create a new record in the database.
We're using the create
method from the queryBuilder
to create a new record in the database.
Now let's test it.
import User from './models/user';
const user = new User({
name: 'hasan',
});
await user.save();
console.log(user.data); // { id: 1, name: 'hasan', _id: ObjectId('some_random_id') }
Amd that's it!
🎨 Conclusion
In this lesson, we learned how to save the model data, and we learned how to update the data if the data is changed.
🚀 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)
Posted on November 6, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.