0

I'm writing a counter to count an object, and it looks like this:

function myFunc(param) {
  this.param = param;

  param.foo = function() {
    var object = window.JSON.parse(data);
    for (i in object) {
      counter++;
    }
  }

}

var foo = new myFunc('data.json');
var counter = 0;
document.write(counter); // displays 0

How can I achieve to get the counter value outside the function? I tried almost everything, from window to return to separate functions.

Any clue?

Update

I prefer a better design like this

function myFunc(param) {
  this.param = param;

  param.foo = function() {
    var object = window.JSON.parse(data);
    var counter = 0;
    for (i in object) {
      counter++;
    }
    return counter;
  }

}

var foo = new myFunc('data.json');
document.write(counter); // displays undefined

Update 2

Sorry, thought it would be easier to have a sample code. But here's the real one: https://gist.github.com/BobWassermann/e709ec303477a015b609

5
  • That's a bad design. Instances shouldn't modify global(or outer) variables. If you just want to create one instance of that constructor then there is no need to define a constructor, Use a singleton.
    – Ram
    Commented Jun 27, 2015 at 19:55
  • 1
    What is a "data" in "window.JSON.parse(data)" ?
    – Art713
    Commented Jun 27, 2015 at 19:58
  • @Vohuman Updated the code, this gives me undefined Commented Jun 27, 2015 at 19:58
  • data = this.param? Commented Jun 27, 2015 at 19:59
  • @Art713 It's a JSON file the counter is looping through. I think it's out of content for the particular problem, but can post the real code if necessary Commented Jun 27, 2015 at 19:59

3 Answers 3

2

I think you have a couple issues here.

First, you're setting your counter to 0 just before you write. It will always be 0 no matter what you do, even with hoisting.

Second, you never call the foo function, so your counter is never incremented.

Third, param.foo isn't public. I think you want it to be this.foo = function(){ ... }.

Here's a simplified version of the code you posted with my tweaks:

var counter = 0;
var foo;

function myFunc() {
  this.foo = function() {
    counter = 1000;
  }
}

foo = new myFunc();
foo.foo();
document.write(counter);

JSFiddle: http://jsfiddle.net/dgrundel/2ojw2332/2/ Note that JSFiddle doesn't allow document.write, so replaced that part.

1
  • Weird thing going on. Writing or console logging still shows 0. But when I type counter in the chrome dev tools command line it displays 173, the correct number. Commented Jun 27, 2015 at 20:11
2

function myFunc(param) {
    this.param = param;
    this.foo = function () {
        var object = window.JSON.parse(this.param),
            counter = 0,
            i;
        for (i in object) {
            counter++;
        }
        return counter;
    };
}
var foo = new myFunc('{"a":99}');
out(foo.foo());

function out(s) {
    document.getElementById('out').innerHTML = '<pre>' + s + '</pre>';
}
<div id="out"></div>

3
  • This doesn't work, it's what I'm trying to do now. I updated my question with the original function, the one I'm really using. Commented Jun 27, 2015 at 20:08
  • Thank you. I'm doing this now out(data.xobj.onload()); function out(s) { document.getElementById('out').innerHTML = '<pre>' + s + '</pre>'; }, but gives me Uncaught TypeError: Cannot read property 'onload' of undefined. Am I doing something wrong? Or should I wrap xobj.onload in another function? Commented Jun 27, 2015 at 20:22
  • the data you retrieve is asynchron. the problem with that is, you process the data and the data is not received. Commented Jun 27, 2015 at 20:40
1

As @Nina Scholz pointed out earlier, I'm retrieving the data asynchron. Javascript started painting the dom before all the values where loaded.

This fixed my problem:

if (document.readyState) {
  setTimeout(function() {
    var objLen = Object.keys(obj).length;
    console.log(objLen);
  }, 100);
}

I'm waiting for the document to be ready, then add an additional timeout as buffer.

Not the answer you're looking for? Browse other questions tagged or ask your own question.