1

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;
    }
}
3
  • 3
    Where is openModal() defined exactly? What do you think this refers to? Also: this doesn't sound like the angular way to approach this task. Commented Feb 23, 2015 at 7:40
  • Are you going to use the Angular Bootstrap modal window? Where is this.openModal() defined? Commented Feb 23, 2015 at 7:48
  • If you could confirm whether you are using the Bootstrap UI, or Foundation Directives, I can give you further assistance with the Modal. Commented Feb 23, 2015 at 8:14

2 Answers 2

1

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']];
}));
Sign up to request clarification or add additional context in comments.

1 Comment

What actually is happening here is that :- I am working on a popup window while deleting the contact, on success I want the popup to close which I am doing using the openModal function which resets every popup window.
1

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.

1 Comment

hey I have a problem calling sub function inside function code look like this function foo(){ this.sam = function(){ alert('helllo') } } in my controller I try calling it using this.foz = foo.sam; but it doesnt work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.