0

I have the following question: Why is it impossible for me to access my array in a forEach loop with Angular. I have made this factory with an array and a function, within the function I have this forEach loop. Outside of the forEach loop I can acces my array with the this keyword. In the forEach loop it gives me a undefined value.

.factory("sendOrder", function () {


    return {
        paired: [],

        send: function () {
            var names = document.getElementsByTagName('input');
            var ordered = document.getElementsByClassName('ordered');
            var i = 0;
            console.log(this.paired);//I can access it from here


           angular.forEach(names, function (amount, key) {
            console.log(this.paired);//Unable to access

               i++; 
            return;
                })
        }
    }

})
Michelangelo
  • 5,312
  • 5
  • 28
  • 46
  • [You Don't Know JS: this and Object Prototypes](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/README.md#you-dont-know-js-this--object-prototypes) is so good at teaching you why `this` isn't what you think it is. – Neil Smith Jan 27 '15 at 22:37
  • Thanks for the tip. I will take a look at it. – Michelangelo Jan 27 '15 at 22:45

2 Answers2

3

Maybe this will help. Angular lets you set the context (this) in forEach. It's one of the arguments. You don't have to set any other variables:

angular.forEach(obj, iterator, [context]);

You've passed in obj and iterator. Just pass in something for context and that will be this in the function.

chris
  • 1,525
  • 15
  • 29
  • I see...Interesting. Did not know I was able to do that. Thanks – Michelangelo Jan 27 '15 at 22:22
  • You can do the same thing in plain old JavaScript array `forEach` too. – chris Jan 27 '15 at 22:23
  • 1
    Yes I know but I want to learn it the Angular way and sometimes Angular is really close to plain javascript. – Michelangelo Jan 27 '15 at 22:25
  • It's in the documentation, so I don't think you have to worry about it not being the Angular way. Self is a JavaScript thing in general, looks like: http://stackoverflow.com/questions/962033/what-underlies-this-javascript-idiom-var-self-this – chris Jan 27 '15 at 22:47
1

Because the context of the function changes - this is not what it originally was. The usual fix is to set the original context to a variably (usually called self):

.factory("sendOrder", function () {


    return {
        paired: [],

        send: function () {
                var self = this;
                var names = document.getElementsByTagName('input');
                var ordered = document.getElementsByClassName('ordered');
                var i = 0;
                console.log(this.paired);//I can access it from here


               angular.forEach(names, function (amount, key) {
                console.log(self.paired);//should be fine now

                   i++; 
                return;
                    })
            }
        }
    })
Michelangelo
  • 5,312
  • 5
  • 28
  • 46
Shomz
  • 36,161
  • 3
  • 52
  • 81
  • Is there a way I can still use my array or should I just work around it? – Michelangelo Jan 27 '15 at 22:20
  • Absolutely, sorry, posted my answer before it was done. Just assign this to a variable. – Shomz Jan 27 '15 at 22:21
  • Thanks for the fix. Just like regular oop in javascript. – Michelangelo Jan 27 '15 at 22:23
  • By the way, the solution you posted did not work untill I moved `var self = this` within the function. Updated your solution. Still you got me on the right track! I think `this` in your solution did reference the factory object not the returned object. – Michelangelo Jan 27 '15 at 22:48