0

i have a method and i want to perform two different things based on the arguments passed.

i have the method defined like below,

create_at = (x, y, point_3d) => {
    if (!point_3d) {
        this.props.pick_point([x, y]).then(picked => {
            let next;
            let some_var1 = this.state.some_var;
            if (some_var1 === undefined) {
                this.setState({
                    some_var1: some_var1,
                    point: {x: x, y: y},
                });
            } else {
                next = this.some_drawings;
                this.setState({
                    var_1: var_1,
                });
            }
            next = this.add_path(
                picked[0], picked[1], picked[2]);//this statement varies as 
            //well
            this.props.something_changed(next);
        }).catch(no_op);
    } else {
            let next;
            let some_var1 = this.state.some_var;
            if (some_var1 === undefined) {
                this.setState({
                    some_var1: some_var1,
                });
            } else {
                next = this.some_drawings;
                this.setState({
                    var_1: var_1,
                });
            }
        next = this.add_path(
                point_3d[0], point_3d[1], point_3d[2]);
            this.props.something_changed(next);
        }
    };

i call this create_at method like below...

this.create_at(x, y) 

and other time like this

this.create_at(point_3d)

now calling this.create_at(x,y) works fine.

but calling this.create_at(point_3d) doesn't work meaning point_3d is undefined and gets into if statement of create_at method...

i want to change this create_at method such that should work when user passes only x, y values like this.create_at(x,y) and also when user passes only point_3d like this.create_at(point_3d)

what is expected?

when user has x,y values then he calls this.create_at(x,y) and the code inside if statement should execute.

when user has only point_3d value he calls this.create_at(point_3d) and the code inside else statement should execute.

if you take a closer look into code all the statements inside if and else are same except updating state for point is skipped in else clause.

How can i make this code work with less repetitive statements. could someone help me with this. thanks.

someuser2491
  • 1,848
  • 5
  • 27
  • 63
  • 2
    Does this answer your question? [Function overloading in Javascript - Best practices](https://stackoverflow.com/questions/456177/function-overloading-in-javascript-best-practices) – Anonymous Duck Nov 06 '19 at 11:47

3 Answers3

0

Pass both the arguments since the method is expecting that. For ex:

this.create_at(null, null, point_3d);

and vice versa for x, y variation

UPDATE

In that case, I would suggest putting your repetitive code in a separate function and then pass the necessary arguments to decide which condition should have what line of statements.

Something like below

function commonExecution(x, y, point_3d, picked) {
   let next;
   let some_var1 = this.state.some_var;
   if (some_var1 === undefined) {
      this.setState({
          some_var1: some_var1,
      });
      //The only place where I see you are using this condition
      if(x && y){
         this.setState({
            point: {x: x, y: y},
         });
      }
   } else {
      next = this.some_drawings;
      this.setState({
          var_1: var_1,
      });
   }

   if(x && y && picked){
      next = this.add_path(
            picked[0], picked[1], picked[2]);
   } else if(point_3d) {
      //else if for point_3d to be on the safer side
      next = this.add_path(
            point_3d[0], point_3d[1], point_3d[2]);
   }
   this.props.something_changed(next);
}

create_at = (x, y, point_3d) => {
    if (!point_3d) {
        this.props.pick_point([x, y]).then(picked => {
             commonExecution(x,y,point_3d, picked);
        }).catch(no_op);
    } else {
        commonExecution(x,y,point_3d, null);
    }
}
Guruprasad J Rao
  • 29,410
  • 14
  • 101
  • 200
0

You can do that by testing the types of the parameters. When you pass just one parameter, it doesn't matter what its name is, it will go into the first one, or "x". You can getting your point_3d in the x parameter.

You can use typeof to determine the type of the first variable and use that, then use the 2nd only if you need:

create_at = (x, y) => {
    if (typeof x === 'number') {
        this.props.pick_point([x, y]).then(picked => {
            let next;
            let some_var1 = this.state.some_var;
            if (some_var1 === undefined) {
                this.setState({
                    some_var1: some_var1,
                    point: {x: x, y: y},
                });
            } else {
                next = this.some_drawings;
                this.setState({
                    var_1: var_1,
                });
            }
        }).catch(no_op);
    } else if (typeof x === 'object') {
            ... do something with x as if it is point_3d
        }
    };
Garr Godfrey
  • 8,257
  • 2
  • 25
  • 23
0

As I can understand you want to distinct function call based on the number of passed arguments.

An option would be to use arguments.length and depending on its value adapt your code.

function myFunc(arg1,arg2,arg3){
  if(arguments.length == 2){
    console.log('Function called with 2 arguments')
  }else if(arguments.length == 1){
    console.log('Function called with 1 argument')
  }
}

myFunc(1,2);
myFunc(1);

Reference.

leopal
  • 4,711
  • 1
  • 25
  • 35