Reputation: 1324
I am working on a small application in angularjs :-
I am working on deleting a contact. Everything works fine but the this.openModal() throws an error as undefined even though it is defined in the same JS.
Have some confusions on how to use this and $scope together. Can anyone help ?
$scope.deleteContact = function ()
{
var delNo = $scope.contactNumber;
var delName = $scope.contactName;
var person = {};
person['phone'] = delNo;
...
...
$timeout(function(){
delete $scope.contacts[person['phone']];
});
$scope.activeChats={};
$scope.showContactName = false;
this.openModal();
console.log("Delete success");
}
EDIT:
this.openModal is a function I have defined as follows
this.openModal = function (input) {
this.modalOpen = !this.modalOpen;
// RESET
this.showNewMessage = false;
this.showEditGroup = false;
this.showAddContact = false;
this.showPersonSettings = false;
this.showUserProfile = false;
if (input == "newmessage"){
this.showNewMessage = true;
} else if (input == "showEditGroup"){
this.showEditGroup = true;
} else if (input == "newcontact"){
this.showAddContact = true;
} else if (input == "userprofile"){
this.showUserProfile = true;
} else if (input == "usersettings"){
this.showPersonSettings = true;
}
}
Upvotes: 1
Views: 189
Reputation: 104999
It's not completely clear what you're doing but I suppose you're having some context issues executing async functions. Try assigning $scope
to a local variable closing it over in your function block and use the variable in asnyc functions' blocks.
$scope.deleteContact = function ()
{
var person = {
phone: $scope.contactNumber
};
...
// save scope reference to local variable
var scope = $scope;
$timeout(function(){
// use saved scope
delete scope.contacts[person['phone']];
});
$scope.activeChats={};
$scope.showContactName = false;
this.openModal();
console.log("Delete success");
}
There's also another way that somewhat does something similar in but inside angular's code. And that's angular.bind
. Use it in your $timeout
. The similarity is that you provide the function's context in the time of execution, so this
is what you provide. In the following case I'm providing $scope
to be the execution context of the async function this referring to it using this
:
$timeout(angular.bind($scope, function(){
// context (this) is actually $scope
delete this.contacts[person['phone']];
}));
Upvotes: 1
Reputation: 14417
You use either $scope
or this
in two scenarios. The first scenario where you use the binding:
ng-controller="MyCtrl"
Or in the route:
when('/color', { controller : 'MyCtrl' });
Here, angular js expects you include the $scope
service in your controllers and attach bindable properties to that:
angular.module('myModule')
.controller('MyCtrl', ['$scope', myCtrl]);
function myCtrl($scope) {
$scope.title = "Hello";
}
In the second scenario, you define a controllerAs
and this is where angular will expect to see the bindable properties on the controller object, controller as a class. I prefer this method because it looks cleaner.
ng-controller="MyCtrl as vm"
Or in the route:
when('/color', { controller : 'MyCtrl', controllerAs: 'vm' });
The controller:
angular.module('myModule')
.controller('MyCtrl', [myCtrl]);
function myCtrl() {
this.title = "Hello";
// or to make sure that you don't get JS contexts mixed up
var vm = this;
vm.title = "Hello";
vm.openModal = function () {
this;// this refers to the current function scope
vm.title = "Modal Opened"; // this refers to the controller scope
// scope as in the JS function context.
}
}
In the second scenario, the binded page will look like this:
<h3>{{vm.title}}</h3>
Where you use the 'controllerAs' string as the object you use to access the properties.
So to answer the question: Have some confusions on how to use this and $scope together
You generally would use one or the other. In the second scenario you would only inject the $scope
if you needed to $watch
a property, or use some other special scope function.
Upvotes: 1