Dave Chen
Dave Chen

Reputation: 10975

Array/Object as index

In a jQuery ajax request, I have error handling that happens with callback:

success: function(a) {
    if (a.error) switch (a.error) {
    case "formError":
    case "clientError":
    case "limitError":
        doErrorCorrection();
        alert("Client-sided error: " + a.errorMessage);
        break;
    case "serverError":
    case "500Error":
        doRollback();
        doTransactions();
        break;
    case "generalError":
        alert("One plus one is: " + (1+1));
    } else doActionsWith(a)
}

I would like to move this into an object of it's own such as:

var errors = {
    ...
    formError: function() {...},
    generalError: function() {...},
    ...
};

With that, I could say:

success: function(a) {
    if (a.error) return errors[a.error](a.errorMessage);
    doActionsWith(a)
}

The issue is that I have tons of reflow from switch, and if I were to translate this to an object, that would mean repetition of the same functions over and over.

var errors = {
    formError: function() { methodA() },
    clientError: function() { methodA() },
    limitError: function() { methodA() },
    ...
    //more if I had more reflows
};

So I thought of having an array/list as the index. I messed around setting an index like:

var arr = {
    test: 'hello world'
};

var index = ['a', 'b', 'c'];

arr[index] = 'array as index';

It worked, but only partially. When I ran the keys through, they returned as a string:

for (var key in arr) console.log(key)
//test
//a,b,c

Running the same test with an object, index = {'a' = true} only set the string index object Object to array as index.

Okay, so an array/object as an index won't work, how should I restructure my switch into an object?

Upvotes: 3

Views: 144

Answers (2)

Ja͢ck
Ja͢ck

Reputation: 173582

When you use arrays as object property names, they're turned into a string equivalent, so [1,2,3] gets used as "1,2,3"; it won't work like "if value is either of these values".

For your particular problem I would create a dedicated error handler object like this:

function ErrorHandler(map, handlers)
{
    this.map = map;
    this.handlers = handlers;
}

ErrorHandler.prototype.handle = function(a) {
    var handler = this.handlers[this.map[a.error]];

    if (handler) {
        handler(a);
    }
}

The constructor takes an error map and handling functions; when .handle() is called, it will find the handler and run it. This is how you instantiate it:

var myHandler = new ErrorHandler({
    "formError": "clientError",
    "clientError": "clientError",
    "limitError": "clientError",
    "serverError": "serverError",
    "500Error": "serverError"
    "generalError": "genericError"
}, {
    clientError: function(a) {
        doErrorCorrection();
        alert("Client-sided error: " + a.errorMessage);
    },
    serverError: function(a) {
        doRollback();
        doTransactions();
    },
    genericError: function(a) {
        alert("One plus one is: " + (1+1));
    }
});

To use it:

success: function(a) {
    if (a.error) {
        myHandler.handle(a);
    } else doActionsWith(a)
}

Upvotes: 1

Mohit Pandey
Mohit Pandey

Reputation: 3833

You can maintain an array of objects like that:

var arr = [{ 
    msg: 'Hello World',
    val: ['a', 'b', 'c']
}, {
    msg: 'This is a dummy text.',
    val: ['d', 'e', 'f']
}];

// now perform your search
for (var obj in arr) {
    var idx = arr[obj].val.indexOf('a');
    if (idx !== -1) { // if val is found
        alert(arr[obj].msg);    // alerts "Hello World"
    }
}

Upvotes: 1

Related Questions