Antonio Pavicevac-Ortiz
Antonio Pavicevac-Ortiz

Reputation: 7729

Why do I get undefined rather the nested object property value in JavaScript?

I am wondering why I am getting:

outerObj.nestedObj.nestedObjMethod('url1'); // returns undefined

instead of http://foo.com

What am I missing?

Thanks in advance!

var outerObj = {

     nestedObj : {
           nestedObjMethod : function() {
                for (var i = 0; i < arguments.length; i++) {
                    var URLS = {
                        'url1': 'http://foo.com',
                        'url2': 'http://bar.com',
                        'url3': 'http://yay.com',                  
                    };
                }
                return URLS[arguments[i]];
            }
      }
 };

UPDATE There have been suggestions to expand upon my code because it was hard to tell why I was doing the above.

Below is the context; I had a created a module trying to make use of the revealing module pattern. This is the original code:

var MarkUpChecker = (function iffe() {
    'use strict';
    var publicAPI = {
        getURL: function() {
            for (var i = 0; i < arguments.length; i++) {
                return {
                    'url': 'http://url1.com',
                    'url1': 'http://url2.com',
                    'url2': 'http://url3.com',
                    'url3': 'http://www.url4.com',
                    'url4': 'http://www2.url5.com'
                }[arguments[i]];
            }
        },
        searchURL: function() {
            var link, url, parser, newPathName = '',
                newstr = '';
            var container = document.getElementById('container').getElementsByTagName('a');
            for (var i = 0, len = arguments.length; i < len; i++) {
                url = this.getURL(arguments[i]);
                for (var j = 0, jlen = container.length; j < jlen; j++) {
                    link = container[j];
                    if (link.href.indexOf(url) !== -1) {
                        parser = document.createElement('a');
                        parser.href = link.href;

                        link.setAttribute('target', '_self');
                        newPathName = parser.pathname;


                        if (newPathName.search(/Executive|District|Division|National/) != -1) {
                            newPathName = newPathName.split('/').pop();
                            newstr = newPathName;
                        } else {
                            newstr = newPathName;
                        }

                        link.href = newstr;
                    } else {
                        link.setAttribute('target', '_blank');

                    }

                }
            }
        }
    };
    return publicAPI;
})();

As you can see this method returns a anonymous object, which I am using as a switch statement and a place to store values.

         getURL: function() {
                for (var i = 0; i < arguments.length; i++) {
                    return {
                        'url': 'http://url1.com',
                        'url1': 'http://url2.com',
                        'url2': 'http://url3.com',
                        'url3': 'http://www.url4.com',
                        'url4': 'http://www2.url5.com'
                    }[arguments[i]];
                }
          },

But afterwards I wondered if I could refactor and eventually get the module to allow one to add urls...I'll be glad to add anymore information! So hopefully it's clear now I nested the object in the method in a object like I did!

Upvotes: 1

Views: 66

Answers (3)

KevBot
KevBot

Reputation: 18888

Arguments length is 1 but there is no value at arguments[1]. i is set to 1 by executing the for loop (i++). You only have a value at arguments[0]. When you pass only 1 argument, argument[1] will be undefined, and therefore you cannot find what you are looking for in the object.

Why not just pass in the key you are looking for (like you are already doing), and reference the key from the object in the function?

var outerObj = {

  nestedObj: {
    nestedObjMethod: function(key) {
      var URLS = {
        'url1': 'http://foo.com',
        'url2': 'http://bar.com',
        'url3': 'http://yay.com'
      };
      return URLS[key];
    }
  }
};

console.log(outerObj.nestedObj.nestedObjMethod('url1'));

Upvotes: 2

jfriend00
jfriend00

Reputation: 707158

Because after you run your for loop, the value of i is one more than the number of arguments you have so arguments[i] is always beyond the last argument and thus will be undefined.

Your whole for loop is doing nothing so it isn't really making much sense here what you're trying to accomplish with that code.

If you just want to index into the URLs structure with the argument that was passed, then you can just do this:

var outerObj = {

    nestedObj: {
        nestedObjMethod: function(index) {
            var URLS = {
                'url1': 'http://foo.com',
                'url2': 'http://bar.com',
                'url3': 'http://yay.com',
            };
            return URLS[index];
        }
    }
};


outerObj.nestedObj.nestedObjMethod('url1');   // 'http://foo.com'

If you were trying to accomplish something else with your for loop, then please describe what you were trying to accomplish with it.

Upvotes: 1

Dylon
Dylon

Reputation: 1750

You've incremented i past the last index of the array, try this:

var outerObj = {

     nestedObj : {
           nestedObjMethod : function() {
                for (var i = 0; i < arguments.length; i++) {
                    var URLS = {
                        'url1': 'http://foo.com',
                        'url2': 'http://bar.com',
                        'url3': 'http://yay.com',                  
                    };
                }
                return URLS[arguments[i - 1]];
            }
      }
 };

Upvotes: 2

Related Questions