1

Note: Yes there are similar questions but I'm having trouble passing the collection into a function.

$j = jQuery.noConflict();

// objects.json shows: {"objects": ["hello", "hi", "yo"]}

function ObjectCollection() {

}

ObjectCollection.prototype = [];


ObjectCollection.prototype.fetch = function() {
 var parent = this;
 $j.getJSON("objects.json", function(data) {
     $j.each(data.objects, function(i, customObject) {
        var myCustomObject = new CustomObject(customObject);
        parent.push(myCustomObject);
     });

     console.log(parent); // array exists

 });
      console.log(parent); // its gone!

};


function CustomObject(name) {
    this.name = name;
}

function doSomethingWithCollection(objectCollection) {
    this.objectCollection = objectCollection;
    this.objectCollection.fetch();
    console.log(this.objectCollection); // shows object collection with object in console
    console.log(this.objectCollection.length); // equals 0?? should be 3!
    this.objectCollection.forEach(function(object) {
        // it wont iterate
        console.log(object);


    });
}
var collection = new ObjectCollection;
// if i uncomment the next two lines, the code will work
// var object = new CustomObject('myName');
// collection.push(object);
doSomethingWithCollection(collection);

Edit... ok, my problem is this: https://jsfiddle.net/qd42fknL/

Please don't suggest plugins. I want to create my own object collector.

What's going on with my code?

I made a fiddle...

If I initiate the collection with an object outside of the function..it will work, so this is an inheritance problem. Whats going on?

amlmf1
  • 43
  • 8

1 Answers1

0

EDIT

I realized that issue is not with inheritance at all. Issue here is that you are sending an ajax request and before it actually finishes, you are doing console.log. So, that produces wrong results.

There are two solutions to overcome that.

  1. Use synchronous ajax request (but that is not recommend)
  2. Wait for asynchronous ajax request to finish first.

Here is a working solution using asynchronous ajax calls.

$j = jQuery.noConflict();

function ObjectCollection() { }
ObjectCollection.prototype = [];

ObjectCollection.prototype.fetch = function(callback) {
    var parent = this;
    $j.getJSON("objects.json", function(data) {
        $j.each(data.objects, function(i, customObject) {
            var myCustomObject = new CustomObject(customObject);
            parent.push(myCustomObject);
        });

        callback(); // notify request is completed
   });
};

function CustomObject(name) {
    this.name = name;
}

function doSomethingWithCollection(objectCollection) {
    this.objectCollection = objectCollection;
    var that = this;

    this.objectCollection.fetch(function () {

        // do this only after ajax finishes 
        console.log(that.objectCollection);
        console.log(that.objectCollection.length);
        that.objectCollection.forEach(function(object) {
            console.log(object);
        });
    });
}

var collection = new ObjectCollection;
doSomethingWithCollection(collection);

Here is the fiddle https://jsfiddle.net/qd42fknL/2/

Adnan Umer
  • 3,669
  • 2
  • 18
  • 38
  • That will work very well for other classes, but not for `Array`. `Array.apply(this, arguments)` does nothing, and `.length` doesn't work. – Bergi Mar 23 '16 at 15:54
  • @Bergi coll.length works fine. Please have a look over here https://jsfiddle.net/2j0ef55n/ – Adnan Umer Mar 23 '16 at 16:01
  • [not really](https://jsfiddle.net/2j0ef55n/1/). It only has the expected value because you used `push`, but it does not work like you'd expect from an array. – Bergi Mar 23 '16 at 16:03