4

I have this function:

function callWS(input) {
    var output = {
        "type"  : input["type"]  || "",
        "mark"  : input["mark"]  || "",
        "model" : input["model"] || "",
        "year"  : input["year"]  || ""
    };

    return output;
}

I want the user to call this function in many ways:

callWS(); ==> {"type":"","mark":"","model":"","year":""}
callWS({"type":"moto"}); ==> {"type":"moto","mark":"","model":"","year":""}
callWS({"type":"moto","mark":"audi"}); ==> {"type":"moto","mark":"audi","model":"","year":""}

And in case a parameters is undefined, to initialize it as an empty string. Currently my function does not work in the first case, but in the other is working.

When I call it like callWS() I get:

Uncaught TypeError: Cannot read property 'type' of undefined

To be honest I don't know why it works for the 2 and 3 case but I need to make it work for the first case also. I know that if I use:

if (input["type"])

will do the trick but I need an inline solution. Is this possible somehow?

6
  • 4
    You have to supply input itself with default value too. Just add input = input || {} to the beginning of callWS Commented Dec 13, 2016 at 16:36
  • 1
    Define your function as function callWS(input = {}). Commented Dec 13, 2016 at 16:38
  • @torazaburo - the project does not include ES6 Commented Dec 13, 2016 at 16:39
  • @François Wahl - Unfortunately the project does not use jQuery, it doesn't use any external library. Commented Dec 13, 2016 at 16:51
  • @paulalexandru hence the part, if you are not using jQuery you can write your own easily :) I only used JavaScript in my example too but you already have it sorted anyway :) Commented Dec 13, 2016 at 16:54

3 Answers 3

5

You have to supply input variable itself with default value too.

function callWS(input) {
   input = input || {};
   ...
}

Otherwise you access properties on unexisting (undefined) object which lead to error (what you have now).

On other hand accessing unexisting properties on existing object isn't treated as error in JS.

Sign up to request clarification or add additional context in comments.

2 Comments

yes @torazaburo but he wants the object with properties created and not undefined
@torazaburo ok now I understood, sorry, the tree dots made me mistake
0

You can write your own extend method and use that. That way you can have a default object, giving it which ever default values and then merge it with the object passed into the function.

function extend(a, b){
    for(var key in b){
        if(b.hasOwnProperty(key)){
            a[key] = b[key];
        }
    }

    return a;
}

function callWS(input) {
    var defaultInput = {
        "type": "",
        "mark": "",
        "model":"",
        "year": ""
    }
    
    var output = extend(defaultInput, input);

    return output;
}

console.log(callWS());
console.log(callWS({"type":"moto"}));
console.log(callWS({"type":"moto","mark":"audi"}));

Comments

0

In ES6, write this as

function callWS({type = "", mark = "", model = "", year = ""} = {}) {
  return {type, mark, model, year};
}

Here's another approach not involving ES6. Many libraries contain a default utility, which will apply some properties to another object if they are missing.

function deflt(obj, defaults) {
  var keys = Object.keys(defaults);
  for (var i = 0; i < keys.length: i++) {
    var key = keys[i];
    if (!(key in obj)) obj[key] = defaults[key];
  }
  return obj;
}

You can use this as follows:

function callWS(input) {
  input = input || {};
  deflt(input, {type: "", mark: "", model: "", year: ""});
  return input;
}

Note: as written this will return a modified version of the input. Adjust as necessary if this is not what you want.

1 Comment

Unfortunately, the project does not use ES6

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.