How does one validate a model with a property, of type object in Sails JS?
I know that attributes with a simple value (e.g. string), is acceptable, however how does this work for nested JSONs?
Like the following:
{
name: 'John',
location: {
x: 23,
y: 15,
z: 50
}
}
So would it be of the form:
{
name: {
type: 'string',
required: true,
},
location: {
x: {
type: 'number',
required: true
},
y: {
type: 'number',
required: true
},
z: {
type: 'number',
required: true
}
}
}
Waterline (the Sails ORM) doesn't directly support nested schemas. You can use a custom validation rule to validate the attribute instead:
module.exports = {
types: {
location: function(val) {
// Make sure that x, y and z are present and are numbers.
// This won't allow numeric strings, but you can adjust to fit your needs.
return (_.isNumber(val.x) && _.isNumber(val.y) && _.isNumber(val.z));
}
},
attributes: {
location: {
type: 'json',
required: true, // If you want the whole attribute to be required
location: true // Validate that the attribute has the schema you want
}
...more attributes...
}
};
The most elegant solution I have found so far is to using the "machine" library (which powers the actions in sailsjs, built by sailsjs people) to define type validation "machines".
First you need a type define helper:
$ cat api/types/define.js
const buildWithCustomUsage = require("machine").buildWithCustomUsage;
function validateWith(machine, inputs) {
machine(inputs).now();
return true;
}
module.exports = function (def) {
const machine = buildWithCustomUsage({
def,
extraArginsTactic: "doNotCheck"
});
return {
machine,
validate: validateWith.bind(null, machine)
};
};
Then you can define a type like this:
$ cat api/types/QuoteRequest.js
module.exports = require("./define")({
description: "Quote request type definition",
inputs: {
input_currency_type: {
description: "Input currency type",
type: "string",
required: true
},
amount_requested: {
description: "Requested amount in input currency",
type: "string",
required: true
}
},
sync: true,
fn: function (inputs, exits) {
// your other validation logics
return exits.success();
}
});
You need to make sure you set sync: true
.
To use it in your controllers, do like this:
inputs: {
request: {
type: "json",
required: true,
custom: require("../../types/QuoteRequest").validate
}
},
Hope it helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With