简体   繁体   中英

Javascript es6 class handling error

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?

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, eg:

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...*/});

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM