6

I am using the 'clouddns' module to import ~800 domain names into a Rackspace account. I keep getting an error saying the following

TypeError: Cannot call method 'forEach' of undefined
at _wrapDomains (/home/duet/www/git/node-rackspace/node_modules/clouddns/lib/clouddns/core.js:146:17)
at /home/duet/www/git/node-rackspace/node_modules/clouddns/lib/clouddns/core.js:209:14
at Request._callback (/home/duet/www/git/node-rackspace/node_modules/clouddns/lib/clouddns/common.js:170:5)
at Request.self.callback (/home/duet/www/git/node-rackspace/node_modules/clouddns/node_modules/request/main.js:120:22)
at Request.EventEmitter.emit (events.js:98:17)
at Request.<anonymous> (/home/duet/www/git/node-rackspace/node_modules/clouddns/node_modules/request/main.js:555:16)
at Request.EventEmitter.emit (events.js:95:17)
at IncomingMessage.<anonymous> (/home/duet/www/git/node-rackspace/node_modules/clouddns/node_modules/request/main.js:517:14)
at IncomingMessage.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:920:16

After looking at the library file in question (core.js) I decided to throw a couple log statements in there to see if I could figure out what was happening. Here is the code:

CloudDNS.prototype.getDomains = function getDomains(options, callback) {
    var args = Array.prototype.slice.call(arguments),
        callback = args[args.length - 1];

    if (typeof callback !== 'function') {
        throw new Error("This method requires a callback");
    }

    var self = this;
    var reqOpts = {
        method: 'GET',
        uri: this.dnsUrl('domains'),
        client: this
    }

    if ((arguments.length > 1) && (typeof arguments[0] === 'object')) {
        reqOpts.params = {
            name: args[0]
        }
    }

    this.rackspace(reqOpts, callback, function(body) {
        var result = JSON.parse(body);
        console.log(result.domains); //good here, it's an array and I can even forEach on it!
        self._wrapDomains(result.domains, callback); //undefined wtf?
        console.log(result.domains); //same as before, works brilliantly
    });
};

CloudDNS.prototype._wrapDomains = function _wrapDomains(domainArray, callback) {
    var self = this;
    var results = [];

    console.log(domainArray); //reports undefined

    domainArray.forEach(function(domain) {
        results.push(new(clouddns.Domain)(self, domain));
    });

    return callback(null, results);
}

I am weirded out by the fact that result.domains is defined before and after the method gets called, but inside that method it is 'undefined'. Can anyone shed some light on why this is happening?

6
  • I tried to reproduce the issue with a minimum example, but it works like expected. Feel free to fool around at jsfiddle.net/cc7KJ Commented Sep 18, 2013 at 16:09
  • 2
    It is possible that somewhere _wrapDomains method is overridden and do not passes data through as expected. To check that, in this.rackspace callback, after you log result.domains could you console.log(self._wrapDomains.toString()); So to see the function source code, and if it is different from actual _wrapDomains below, then it is overridden. Commented Sep 18, 2013 at 16:11
  • What's even weirder is that the callback from the calling method (CloudDns.getDomains()) actually sends back the correct data. Since this is a one-off thing, and it seems to work - I've just wrapped the whole domainArray.forEach() method in a try/catch to keep it from stopping the script. Commented Sep 18, 2013 at 17:50
  • Some ideas here: Where is body coming from? Has it been serialized using JSON.stringify? Have you linted the json using some jsonlint, or something like that? Have you tried a small subset of the original JSON? Using a json with just one element, you will be sure that nothing is failing because of the json. Check if there is some invalid character. Commented Sep 23, 2013 at 20:57
  • @Guillermo that makes no sense regarding that specific issue, as here problem is with passing data between functions but not about what data is it self. Commented Sep 24, 2013 at 14:39

1 Answer 1

1

I just checkout the source code on github. If you look at the second line in your stack trace, it's at /home/duet/www/git/node-rackspace/node_modules/clouddns/lib/clouddns/core.js:209:14

So _wrapDomains is getting called towards the end of the file in the createDomain method (on line 209). If you investigate there, you will find out why it's calling it with null values.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.