3

I've gone bonkers hitting Stackflow and Google trying to find solutions, and finally am asking for ideas after being at this for a couple of hours.

This is my array:

endangered = '#FFA500';
shutdown = '#FF0000';
active = '#00BB00';

// Build state array
var state = {};
state = {
        NV: {
            status: shutdown,
            name: 'Las Vegas Charter School for the Deaf',
            SchoolLink: 'http://www.lvcsd.org',
            SourceLink: 'http://www.lvrj.com/news/charter-school-for-deaf-signs-off-in-bankruptcy-141399423.html',
            ClosureDate: 'March 5, 2012',
            Comment: 'Closure due to bankruptcy. State also adopted exclusive mainstreaming approach.'
        },
        WY: {
            status: shutdown,
            name: 'Wyoming School for the Deaf',
            SchoolLink: 'http://www.wyomingdeaf.com/',
            SourceLink: 'http://trib.com/news/local/article_94be7523-5bc5-5031-97ee-9431a205cfe9.html',
            ClosureDate: '2000',
            Comment: 'School replaced by a mainstream school. State also adopted exclusive mainstreaming approach.'
        }
}

Accessing it then at this point would be something like:

stateCode = 'NV';
currentColor = state[stateCode].status; 

It'd check the state array, look up the 'NV' array which has its own array, then finally look up the status, which also has its own variable, which references the color associated with that status. In this case, it'd be returning '#FF0000' for shutdown.

If I do the code like that, it fails saying 'undefined'. If I however do it like this:

currentColor = state['NV'].status; 

It then works perfectly. But this defeats the purpose, as it becomes static. I need to be able to keep stateCode dynamic, as it's based on feedback from a function, and will always be changing.

I could do it like this:

if(stateCode === 'NV') currentColor = state['NV'].status;
if(stateCode === 'WY') currentColor = state['WY'].status;

But it'd quickly become bloated. There has to be a better way to handle this. Any ideas?

Don Cullen
  • 403
  • 1
  • 4
  • 21
  • Please specify exactly what you mean by "it fails saying 'undefined'" Is that a console error message? If so please show the whole message. – HBP Jul 19 '12 at 05:26
  • Figured out the cause (but not the solution). It's a matter of variable scope. JSFiddle: http://jsfiddle.net/n7hTw/1/ demonstrates the problem. It should be alerting the status, when it's not. – Don Cullen Jul 19 '12 at 09:30

2 Answers2

2

By the way, what you are constructing are Objects and not Arrays

If you want to keep the code dynamic, keep a color object:

var colors = {
 endangered: '#FFA500',
 shutdown: '#FF0000',
 active: '#00BB00'
};

Then use a string to indicate the status rather than a variable on your state objects:

var state = {};
state = {
    NV: {
        status: 'shutdown',

And evaluate your current color like this:

var currentColor = colors[state[stateCode].status]; 

Always prefix var to your variables unless you want to construct a global variable, but normally, local variables suffize

Beat Richartz
  • 9,474
  • 1
  • 33
  • 50
  • You have the right concept, but seems to fail when used inside a function while using the variables outside the function. I suspect it's due to the matter of scope, but for the life of me, I can't see why since both state and colorCodes are pretty much at the head outside any functions, and should be global. Working Version: http://jsfiddle.net/n7hTw/ Non-Working Version: http://doncullen.net/map/tests/index.html (click on a state and look at console to see undefined error I'm referring to. It's occurring at line 197.) – Don Cullen Jul 19 '12 at 08:55
  • The error occuring on line 197 is due to `state['TX']` returning undefined. You have to define all the states you want to call in your state object (unless you want to assign them dynamically, but then you would have to do *that*). – Beat Richartz Jul 19 '12 at 09:14
  • Definitely a matter of scope. Added this to your code: var testFunc = function () { thestatus = state[stateCode].status; alert('thestatus = '+thestatus ); } this will fail to access the state and color variables. – Don Cullen Jul 19 '12 at 09:19
  • Yes, if `state[stateCode]` returns undefined, you cannot call status on it. If `state[stateCode]` returns a state object, then you will be able to call `status` on it. This will then return a String. This string your map to the colors object like this: `colors[theStatus]`. But first, `state['TX']` in your code has to return something else than undefined, which you can achieve by defining 'TX' on your `state` object – Beat Richartz Jul 19 '12 at 09:23
  • See JSFiddle update containing your code, and the internal function I added: http://jsfiddle.net/n7hTw/1/ That's the exact reason why my code is failing; it's the scope. Edit: JSFiddle references 'NV', which is in the **state** object. – Don Cullen Jul 19 '12 at 09:26
  • Figures, had to define the variables inside the local function. Why would that be needed, if you don't mind explaining? I've already accepted your solution as the answer. – Don Cullen Jul 19 '12 at 09:38
  • 1
    The `var` declaration prevents that your variables are always defined in the global scope. [Here's an excellent post on variable scope](http://stackoverflow.com/questions/500431/javascript-variable-scope). While this was not exactly the problem in your case, you should avoid using global variables unless you really need to put something in the global scope. – Beat Richartz Jul 19 '12 at 09:47
1

This structure isn't an array, this is an object initializer. Anyway you need something like this:

var colorCodes = {
    endangered: '#FFA500',
    shutdown: '#FF0000',
    active: '#00BB00'
};

var state = {
    // What you have there
};

var stateCode = '[State Code]';
var currentColor = colorCodes[state[stateCode].status];
micnic
  • 10,915
  • 5
  • 44
  • 55