Reputation: 23836
I have created a JS class. Here is following code:
export default class Service {
constructor(
serviceId,
serviceName,
serviceDescription,
serviceImageName,
categoryId,
servicePrice,
currencyCode,
acceptPayment,
serviceDuration,
multipleBookingPerSlot,
mode,
tzSupport,
minOptionCount
) {
try{
this.id = serviceId;
this.title = serviceName;
this.subTitle = serviceDescription;
this.imageUrl = serviceImageName;
this.categoryId = categoryId;
this.price = servicePrice;
this.currencyCode = currencyCode;
this.acceptPayment = acceptPayment;
this.meetingDuration = serviceDuration;
this.multipleBookingPerSlot = multipleBookingPerSlot;
this.serviceName = serviceName;
this.mode = mode;
this.tzSupport = tzSupport;
this.session = minOptionCount
} catch(e){
if(e instanceof ReferenceError){
console.error("Service data missing.")
}
}
}
}
My goal is whenever new object of Service
creates like new Service('1')
if any of key is missing code should throw error and stop execution. How can i achieve this?
Upvotes: 1
Views: 180
Reputation: 1075587
You won't get a ReferenceError
if the caller doesn't supply enough arguments, you'll just see undefined
in the parameters.
You have 13 parameters (which is far, far too many). You could do the brute-force thing:
if (arguments.length < 13) {
throw new Error("Missing arguments");
}
Instead, though, I suggest using the builder pattern or an options object instead of 13 discrete parameters. More than three parameters is fairly hard to manage.
For instance, with an options object:
export default class Service {
constructor(
options
) {
["id", "title", "subTitle", "imageUrl", "categoryId", "price", "currencyCode",
"acceptPayment", "meetingDuration", "multipleBookingPerSlot", "serviceName",
"mode", "tzSupport", "session"].forEach(name => {
if (!options.hasOwnProperty(name)) {
throw new Error(name + " is a required option");
}
});
Object.assign(this, options);
}
}
Usage:
let s = new Service({id: 1, title: "foo", /*...etc...*/});
That way, the caller isn't lost in a sea of parameters.
However, if it's important to validate the parameter values are present, isn't it important to validate their values, too? Nothing's to stop me from calling new Service
with 13 completely-invalid arguments (undefined
repeated 13 times, for instance).
So I would probably use an options object (because it's much easier for the caller) combined with parameter destructuring, and then individual validation, e.g.:
export default class Service {
constructor({ // <== Notice the {
id,
name,
decription,
imageUrl,
categoryId,
price,
currencyCode,
acceptPayment,
meetingDuration,
multipleBookingPerSlot,
mode,
tzSupport,
minOptionCount
}) { // <== And the }
this.id = validate.positiveNumber(id);
this.title = validate.nonBlank(name);
this.subTitle = validate.nonBlank(description);
this.imageUrl = validate.URL(imageUrl);
this.categoryId = validate.positiveNumber(categoryId);
this.price = validate.price(price);
this.currencyCode = validate.currencyCode(currencyCode);
this.acceptPayment = validate.boolean(acceptPayment);
this.meetingDuration = validate.duration(meetingDuration);
this.multipleBookingPerSlot = validate.boolean(multipleBookingPerSlot);
this.serviceName = this.title; // Already validated
this.mode = validate.mode(mode);
this.tzSupport = validate.tzSupport(tzSupport);
this.session = validate.whateverThisIs(minOptionCount);
}
}
...where validate
is a set of reusable validations. Usage is the same as above:
let s = new Service({id: 1, title: "foo", /*...etc...*/});
Upvotes: 2
Reputation: 138537
As i already commented assigning undefined to an objects property is completely valid. The solution might be to check for the values of the arguments Arraylike against undefined:
constructor(a,b,c){
if(arguments.length!=3){//check length
return;
}
for(var a=0;a<arguments.length;a++){
if(arguments[a]===undefined){//check against undefined
return;
}
}
//your code
}
http://jsbin.com/vugepakama/edit?console
Upvotes: 0