0

if I have an array like this:

var msg = [ {name: ["a1", "a2"], value: "this is A"},
            {name: ["b1", "b2"], value: "this is B"},
            ...
          ]

The array contains global errors messages for client-side form validations. I have managed to pass in faulty inputs (e.g. "a1") and now am wondering how to get the corresponding message out of my ill-constructed array.

Question
What would be the best way to loop through this array? for example, if I have "a1" as parameter passed into my function, how do I extract "this is A" as corresponding message?

inArray doesn't really help, because I need the corresponding message and not the position of a1. I'm also not sure if this is the best way to store my error messages... ideas welcome!

Thanks for help!

5
  • Why can you have multiple names, but only one value? Commented Feb 17, 2012 at 0:44
  • because some inputs have the same error message. I guess it would be easier if I separated these, woudn't it? Commented Feb 17, 2012 at 0:45
  • Posted an answer with the codes and messages split :) Commented Feb 17, 2012 at 0:51
  • If you want to have better performance, you need to separate them. Commented Feb 17, 2012 at 0:52
  • @Joe: I think I like :-) Commented Feb 17, 2012 at 0:52

4 Answers 4

3

Re-arrange your data structure:

var my_param = 'b1';

// This is an object, so we can have key/value pairs
var error_codes =
{
    'a1': 0,
    'a2': 0,
    'b1': 1,
    'b2': 1
};

// This is an array because we only need values
var error_messages =
[
    'This is A',
    'This is b'
];

alert(error_messages[error_codes[my_param]]);

This makes it really easy to set up new error codes and messages, and is extremely easy to understand. The only gotcha is error_codes[my_param] - it's an object, but we can't do error_codes.my_param because it'll look for the element called 'my_param', so using array notation, we can look up the object key.

The only other potential trap is making sure you don't have any trailing commas:

var error_codes = { 'a1': 1, }; // NO!

Also knows as the trailing comma of death!

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

1 Comment

VERY NICE! Thanks everybody, but I like this best!
1

This would be how I'd do it

var myMsg = findMsg('a1')


function findMsg(msgType){
  msg.forEach(function(obj){
    if(inArray(msgType, obj.name) !== -1){
      return obj.value
    }
  })
}

function inArray(key, obj){
 return obj.join().indexOf(key)
}

Comments

0

$.each is the jQuery way for taking action on each element of an array or each enumerable property of an object.

var value;
$.each(msg, function (i, el) {
  if (el.name.indexOf(name) >= 0) {
    value = el.value;
    return false;  // Stops iteration.
  }
});

If name is "a1" then after running the above, value === "this is A".

2 Comments

What's wrong with the JS for ... in for iterating over JS objects? :P Easy enough, and doesn't have the jQ overhead
It's fine for an Object but certainly not fine for an Array (where for(var i = 0; i < foo.length; ++ i) is preferred.) Using for .. in with an Array would include properties in Array.prototype.
0

Nice and simple:

var getMessage = function (name)
{
    var msg = [ ... ];

    for(var i = 0; i < msg.length; ++ i)
        if (msg [i].name.indexOf (name) != -1)
            return msg [i].value;
}

Returns either the corresponding message or undefined if the name wasn't found.

You may need a shim for indexOf depending on which browsers you want to support:

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.