2

I have read several posts on the use of this instead of $scope, and vice versa, but being fairly new to javascript in general, I feel like I'm still missing something.

Below is a code example where I'm doing a POST request. But by the time I get inside the method, my formData object is empty. But if I change it from this to $scope, it works, and I'm having a hard time understanding why that is.

code:

var app = angular.module('TM', []);

app.controller('tableController', function($scope, $http){

    //Empty object that gets filled with data and sent as a POST request.
    this.formData = {};

    // Define process for submitting form
    //TODO: FIND OUT THE DIFFERENCE BETWEEN $SCOPE AND THIS
    this.processForm = function() {
        console.log('Inside processForm method');

        $('#addEntry').modal('hide');
        console.log($scope.formData); //If I use this here - the object is empty
        $http({
            method : 'POST',
            url :'../protocols',
            data : JSON.stringify($scope.formData), 
            headers : {
                'dataType' : "json",
                'contentType' : "application/json"
            }
        })
        .success(function(data) {
            console.log('Success: ' + data);

            //Empties the object after the POST request is done...
            $scope.formData = {}
        })
        .error(function(data){
            console.log('Error ' + data);
        });
    };
});
Nilzone-
  • 2,766
  • 6
  • 35
  • 71

2 Answers2

1

You need to realize that Javascript has multiple scopes and that the this keyword refers to the scope you are operating in.

Then, like mentioned by @Henri S, you should also realize the scope of your controller, which is a JavaScript contructor function, is not the same as the $scope you are using inside. The $scope used by Angular is an object associated with a controller, which is really a viewmodel to begin with. Your HTML, under the control of a certain controller can 'access' this object. If you create chains of controllers, the $scope will prototypically inherit.

If we apply this to your code:

var app = angular.module('TM', []);

app.controller('tableController', function($scope, $http){

   var self = this; //We capture a reference/value of the scope of your controller

    this.formData = {};
    this.currentDataObject : {restURL: "../protocols"} 

    // Define process for submitting form
    this.processForm = function() { //Here begins a new javascript scope
        console.log('Inside processForm method');

        $('#addEntry').modal('hide');
        console.log(self.formData); // this will refer to the this.formdata

        $http({
            method : 'POST',
            url : self.currentDataObject.restURL,
            data : JSON.stringify(self.formData), 
            headers : {
                'dataType' : "json",
                'contentType' : "application/json"
            }
        })
        .success(function(data) {
            console.log('Success: ' + data);

            //Empties the object after the POST request is done...
            self.formData = {}
        })
        .error(function(data){
            console.log('Error ' + data);
        });
    };
});
skubski
  • 1,586
  • 2
  • 19
  • 25
  • thanks - one more question though; say I create something like this below `formData` : `this.currentDataObject = {restURL: "../protocols"}` If I pass in that instead of writing ../protocols directly. Would does it work when I call it like this: url : this.currentDataObject.restURL?(instead of call it like `$scope.currentDataObject.restURL`) – Nilzone- Jul 09 '15 at 07:55
  • Inside the processForm function the `this` will refer to the scope of `this.processForm = function() {...};` since a function has its own scope. I updated the answer with what I believe you are trying to do. – skubski Jul 09 '15 at 08:07
  • But what I don't understand is why it works when I call `this.currentDataObject.restURL` but not, `this.formData` – Nilzone- Jul 09 '15 at 08:24
  • In the processForm you are in the (execution) scope of your controller and within the anonymous success function you are in the scope of that particular function's scope. This means that the reference to this is different. http://www.smashingmagazine.com/2009/08/01/what-you-need-to-know-about-javascript-scope/ – skubski Jul 09 '15 at 08:58
0

$scope != this.

'this' is context sensitive, related to his 'direct parent'.

$scope isn't needed, if you use the 'controller as' syntax.

But, if you still want to use $scope, use $scope.formData in your controller.

schellingerht
  • 5,726
  • 2
  • 28
  • 56