Create your own BelongsTo Required relation Mixin in loopback NodeJs

A mixin is nothing more than a method of two parameters: function(Model, options):

  1. “Model” is the model on which the mixin will be applied
  2. “options” are the options that may be defined in the model.json under themixins key. To add a mixin you only need to add mixinName: true. If instead of true you provide an object, then this object is the optionsparameter of the mixin function.

Step-by-step guide:

Following steps involved to create a mixin in loopback:

  1. First create a mixins folder in project/common directory.
  2. Now, create a file RequiredRelation.js (any name) in mixins folder.
  3. Open a file and write a following code:
'use strict';
let _ = require('lodash');
module.exports = function(Model, options) {
Model.observe('before save', checkBelongsToIntegrity);
};
let checkBelongsToIntegrity = function(ctx, next) {
if (ctx.instance) {
let Model = ctx.Model;
let msg = '';
let promiseArray = [];
let relationsArray = relationsArrayData(ctx);
relationsArray.forEach(function(relation) {
if (relation.type == 'belongsTo') {
let parentModelName = relation.modelName;
let parentModel = Model.app.models[parentModelName];
let parentId = '';
let keyName = parentModelName.charAt(0).toLowerCase() + parentModelName.slice(1) + 'Id';
if (relation.fk) {
parentId = ctx.instance[relation.fk];
} else {
parentId = ctx.instance[keyName];
}
if (parentId) {
if (parentId != 0) {
promiseArray.push(parentModel.findById(parentId).then(function(parentInstance) {
if (parentInstance === null) {
msg += 'No ' + parentModelName + ' with "' + parentId + '" id. ';
}
}));
} else {
msg += 'No ' + parentModelName + ' with "' + parentId + '" id. ';
promiseArray.push(msg);
}
} // end of parentId
else if (relation.fkReq == true) {
msg += parentModelName + ' Id is required.';
promiseArray.push(msg);
} else {
if (parentId == 0) {
msg += 'No ' + parentModelName + ' with "' + parentId + '" id. ';
promiseArray.push(msg);
}
} // end of else
} // end of if relation.type
});
if (promiseArray.length > 0) {
Promise.all(promiseArray).then(function() {
next(msg);
}, console.error).catch(function(err) {
next(err);
});
} else {
next();
}
} else {
next();
}
};
let relationsArrayData = function(ctx) {
let relations = ctx.Model.definition.settings.relations;
let relationsArray = _.map(relations, rel => {
return {modelName: rel.model,
fkReq: rel.foreignKeyRequired, fk: rel.foreignKey, type: rel.type};
});
return relationsArray;
};

4. After this add your custom mixin in any model json e.g Account.json.

{
"name": "Account",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"mixins": {

"RequiredRelation": {}
},
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}

This is it! Here are the links to the corresponding files in my project:

  1. RequiredRelation.js

Leave a Reply

Your email address will not be published. Required fields are marked *