Reputation: 336
//request is a node module
var request = require('request');
/**
* send REST web service message to server
* @function sendMessage
* @param {string} method - GET, POST, PUT, DELETE
* @param {string} url - server URL
* @param {object} json - The data to be send
* @param {object} cb - callback function
*@param{object}formData-The data related to file upload
* @returns void
*/
function sendMessage(type,url,method,json,retries,formData,cb){
var options={
url:url,
formData:formData,
json:true,
switch (method) {
case 'get':
request.get(options, cb);
break;
case 'post':
envelope.token = json.token;
envelope.package = json.package;
options.body = envelope;
request.post(options, cb);
break;
case 'put':
envelope.package = json.package;
envelope.token = json.token;
options.body = envelope;
request.put(options, cb);
break;
case 'delete':
request.delete(options, cb);
break;
}
Here sendMessage() fuction already written and well used in all the modules without FormData parameter(sendMessage(type,url,method,json,retries,cb)
),but for file upload we need to pass the file path using formData without alter all the other functions is that possible.
Upvotes: 0
Views: 2751
Reputation: 633
Create a new method that accepts an object as a parameter, which analyses the object and decides whether to proxy to the original function or perform your new requirement.
Mark the original method as deprecated and document to use your new method, and when the time is right, calls to the original method can be replaced. When they are all replaced, refactor your new function to remove the proxy and, when confident, remove the old method.
Try and abstract as much functionality as makes sense from the original method to keep the code DRY.
If possible, write a test that both original and new methods can pass.
Upvotes: 1
Reputation: 707238
If the two different calling schemes you want to support are this:
sendMessage(type,url,method,json,retries,formData,cb)
and this:
sendMessage(type,url,method,json,retries,cb)
And, the callback argument is always required, then, you can do that like this:
function sendMessage(type,url,method,json,retries,formDataArg,cbArg) {
var cb = cbArg, formData = formDataArg;
// if we don't have a cb arg, then it must have been called with the
// shorter form that doesn't have formData
if (!cb) {
cb = formDataArg;
formData = null;
}
// continue rest of function using cb and formData as the symbols
// for the last two arguments
// ... other code here ...
}
As others have said, when you get this many arguments, it's often better to use a single options object to which you attach properties. Then it becomes a lot easier to make some of the arguments optional.
You may also find this useful:
How to overload functions in javascript?
FYI, there is also the way you might solve something like this in a harder typed language. You'd create a second function that takes the extra argument and move the implementation there. Then, the original function just becomes a shell that calls the new function with null
for the new argument.
function sendMessage2(type,url,method,json,retries,formDataArg,cbArg) {
// full implementation here with all arguments, formDataArg may be null
}
// original function here, calling signature unchanged
function sendMessage(type,url,method,json,retries,cbArg) {
// call new implementation with arguments in the right place
return sendMessage2(type, url, method, json, retries, null, cbArg);
}
While this works and doesn't use overloading, it's kind of a one-time shot because you don't want to end up with sendMesage3, sendMessage4, etc... Probably sendMessage2 should use the options object which is a lot more extensible so you aren't forced into this again. Then, sometime later when you have more flexibility, you can switch the older code over to the options object and get rid of the whole two API scheme entirely.
That could look like this:
function sendMessageOptions(options, cb) {
// main code here that supports formData to send the message
// gets arguments from the options object
}
// original function here, calling signature unchanged
function sendMessage(type,url,method,json,retries,cbArg) {
// call new implementation with arguments in the right place
return sendMessageOptions({type: type, url: url: method: method, json: json: retries: retries});
}
Note, I left the callback out of the options object because this makes the function compatible with the typical async calling convention and makes inline callbacks for the caller cleaner to code.
Upvotes: 2