listener
listener

Reputation: 47

How to handle different optional callbacks in the same function?

Node.js

I have a function that works with different callbacks. Now I'm wondering if there is a better solution handling different callback functions.

My situation:

function prepare(type, callback){
    let obj = {}; //in real is this an external database

    for(let i=1; i<= 10; i++){
        obj['progress_'+i] = 0;
    }

    if(type === 'createNewUser'){
        callback(obj); //callback for function createNewUser(obj);
    }
    if(type === 'addToExistingUser'){
        callback(obj); //callback for function addToExistingUser(obj);
    }
}

My callback functions are:

createNewUser(obj){
    //create new user with obj;
}

addToExistingUser(obj){
    //add obj to existing user
}

2 ways to use prepare();

prepare('createNewUser', createNewUser);
prepare('addToExistingUser', addToExistingUser);

What is the best practice for this case? I would like to write good code.

Upvotes: 0

Views: 131

Answers (5)

arizafar
arizafar

Reputation: 3122

I am not sure why you need type when you know what method to call or clarify if the type is not hardcoded, you simply can use prototypes as per your defined requirements.

function Prepare(obj) {
	this.obj = obj;

}

Prepare.prototype = {
	createNewUser(obj = this.obj) {
		console.log('existing', obj);
	},
	
	addToExistingUser(obj = this.obj) {
		console.log('new', obj)
	}
}

let prep = new Prepare({a:1});
prep.createNewUser();
//or
prep.createNewUser({c: 3});

prep.addToExistingUser({b:2})

If the type is not hardcoded

function Prepare(type, obj) {
	this.obj = obj;
	this.callback = this[type];
}

Prepare.prototype = {
	createNewUser(obj = this.obj) {
		console.log('existing', obj);
	},
	
	addToExistingUser(obj = this.obj) {
		console.log('new', obj)
	}
}

//if type is not hardcoded
let prep = new Prepare('createNewUser');
prep.callback({d: 4});

Upvotes: 0

Ahmed El-sayed
Ahmed El-sayed

Reputation: 329

replace

if(type === 'createNewUser'){
    callback(obj); //callback for function createNewUser(obj);
}
if(type === 'addToExistingUser'){
    callback(obj); //callback for function addToExistingUser(obj);
}

With

fnc = window[callback];
if( fnc && typeof fnc === "function" ) {  //make sure it exists and it is a function
    fnc();  //execute it
}

Upvotes: 0

Cid
Cid

Reputation: 15247

If type is a string containing the name of the function to call, you can use window[functionName]()

function foo()
{
    console.log("called foo");
}

function bar()
{
    console.log("called bar");
}

function baz(str)
{
  window[str]();
}

baz('foo');
baz('bar');

Or you can create your own object and store the functions in it :

const FunctionObject = {}

FunctionObject.foo = function ()
{
    console.log("called foo");
};

FunctionObject.bar = function ()
{
    console.log("called bar");
};

function baz(str)
{
  FunctionObject[str]();
}

baz('foo');
baz('bar');

Upvotes: 0

Mrk Fldig
Mrk Fldig

Reputation: 4486

How about this?

Basically it's called bracket notation you create a map that has REFERENCE to the function, you can call that function with the desired params.

var callbacks = {

  createNewUser : createNewUserCallback,
  addToExistingUser: addToExistingUserCallback
}


function prepare(type){
    let obj = {};

    for(let i=1; i<= 10; i++){
        obj['progress_'+i] = 0;
    }

    callbacks[type](obj)
}

function addToExistingUserCallback(obj) {
     // Do stuff
}

function createNewUserCallback(obj) {
    // Do stuff
}

OR

var callbacks = {

  createNewUser : (obj) => { // function code goes here.} ,
  addToExistingUser: (obj) => {// function code goes here.} 
}


function prepare(type){
    let obj = {};

    for(let i=1; i<= 10; i++){
        obj['progress_'+i] = 0;
    }

    callbacks[type](obj)
}

To be fair option 1 is more readable.

Upvotes: 1

Durgesh
Durgesh

Reputation: 205

You can try below example and add multiple callbacks in the same function according to your requirement -

function prepare(type, callback, secondcallback) {
    let obj = {};

    for (let i = 1; i <= 10; i++) {
        obj['progress_' + i] = 0;
    }

    if (type === 'createNewUser') {
        callback(obj); //callback for function createNewUser(obj);
    }
    if (type === 'addToExistingUser') {
        secondcallback(obj); //callback for function addToExistingUser(obj);
    }
}


prepare('createNewUser', function (data) {
    console.log('First Callback data:', data);
}, function (data) {
    console.log('Second Callback data:' + data);
})


prepare('addToExistingUser', function (data) {
    console.log('First Callback data:', data);
}, function (data) {
    console.log('Second Callback data:' + data);
})

Upvotes: 0

Related Questions