Abhishek
Abhishek

Reputation: 717

Unable to understand why variable is undefined

I am beginner in AngularJS so I'm trying to learn by building POCs. My requirement is simple-

  1. User adds details and clicks on "Add Contact" button. This adds the contact to an array in controller. (This part is working).
  2. This added contact is shown in tabular format, just below the form. (This is also working).
  3. In the table where contacts are displayed, I also want to have a delete button which will delete the corresponding contact. (The problem)

Following is the html code-

<body ng-app="myApp" class='container'>
    <div ng-controller="Controller1 as ctrl">
        <h1>Contacts Manager</h1>
        <hr>
        <div class="panel panel-primary">
            <div class="panel-heading">Contact Editor</div>
            <div class="panel-body">
                <form role="form" >
                    <div class="form-group">
                        <label for="firstName">First Name</label>
                        <input type="text" name="firstName" class="form-control" placeholder="First Name" ng-model="contact.firstName"/>
                    </div>
                    <div class="form-group">
                        <label for="lastName">Last Name</label>
                        <input type="text" name="lastName" class="form-control" placeholder="Last Name" ng-model="contact.lastName"/>
                    </div>
                    <div class="form-group">
                        <label for="phoneNumber">Phone Number</label>
                        <input type="text" name="phoneNumber" class="form-control" placeholder="Phone Number" maxlength="10" ng-model="contact.phoneNumber"/>
                    </div>
                </form>
            </div>
            <div class="panel-footer">
                <input type="checkbox" name="disableAddRec" ng-model="disableAddRec"> <label for="disableAddRec">Disable Adding Contacts</label>
                <span class="pull-right"><button name="addContact" class="btn btn-primary" ng-disabled="disableAddRec" ng-click="ctrl.addToContactList()">Add Contact</button></span>
            </div>
        </div>

        <table class="table table-bordered table-hover" ng-if="ctrl.contactList.length > 0">
               <thead>
                   <tr><th>S. No.</th><th>First Name</th><th>Last Name</th><th>Phone Number</th><th>Action</th></tr>                       
               </thead>
               <tbody>
                   <tr ng-repeat="cntct in ctrl.contactList">
                       <td>{{$index+1}}</td><td>{{cntct.firstName}}</td><td>{{cntct.lastName}}</td><td>{{cntct.phoneNumber}}</td>
                       <td><button class="btn btn-danger" ng-click="ctrl.removeContact($index)">Remove</button></td>
                   </tr>
               </tbody>
        </table>
    </div>
</body>

Following is the js code-

var myAppRef = angular.module("myApp", []);
myAppRef.controller("Controller1",['$scope', myController1]);
function myController1($scope) {

    this.contactList = [];

    this.addToContactList = function() {
        this.contactList.push($scope.contact);     
        $scope.contact = {};        
    }

    this.removeContact = function(idx) {
        this.contactList.splice(idx,1); // contactList is undefined here... why?
    }
}

Can anyone please help me identifying, why contactList is undefined in removeContact?

Upvotes: 0

Views: 80

Answers (3)

Ashyboy
Ashyboy

Reputation: 175

Made slight modifications in your code. I made it working without using "Controller As"

<div ng-controller="Controller1">
  <h1>Contacts Manager</h1>
  <hr>
  <div class="panel panel-primary">
    <div class="panel-heading">Contact Editor</div>
    <div class="panel-body">
      <form role="form">
        <div class="form-group">
          <label for="firstName">First Name</label>
          <input type="text" name="firstName" class="form-control" placeholder="First Name" ng-model="contact.firstName" />
        </div>
        <div class="form-group">
          <label for="lastName">Last Name</label>
          <input type="text" name="lastName" class="form-control" placeholder="Last Name" ng-model="contact.lastName" />
        </div>
        <div class="form-group">
          <label for="phoneNumber">Phone Number</label>
          <input type="text" name="phoneNumber" class="form-control" placeholder="Phone Number" maxlength="10" ng-model="contact.phoneNumber" />
        </div>
      </form>
    </div>
    <div class="panel-footer">
      <input type="checkbox" name="disableAddRec" ng-model="disableAddRec">
      <label for="disableAddRec">Disable Adding Contacts</label>
      <span class="pull-right"><button name="addContact" class="btn btn-primary" ng-disabled="disableAddRec" ng-click="addToContactList()">Add Contact</button></span>
    </div>
  </div>

  <table class="table table-bordered table-hover" ng-if="contactList.length > 0">
    <thead>
      <tr>
        <th>S. No.</th>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Phone Number</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="cntct in contactList">
        <td>{{$index+1}}</td>
        <td>{{cntct.firstName}}</td>
        <td>{{cntct.lastName}}</td>
        <td>{{cntct.phoneNumber}}</td>
        <td>
          <button class="btn btn-danger" ng-click="removeContact($index)">Remove</button>
        </td>
      </tr>
    </tbody>
  </table>
</div>

JS code:

var myAppRef = angular.module("myApp", []);
myAppRef.controller("Controller1", ['$scope', myController1]);

function myController1($scope) {

  $scope.contactList = [];

  $scope.addToContactList = function() {
    $scope.contactList.push($scope.contact);
    $scope.contact = {};
  }

  $scope.removeContact = function(idx) {
    $scope.contactList.splice(idx, 1); // contactList is undefined here... why?
  }
}

Please check this fiddle. https://jsfiddle.net/Ashyboy/vv8jt6sh/

Upvotes: 1

P. Jairaj
P. Jairaj

Reputation: 1033

Your exact code is working here!! Try running it here.

var myAppRef = angular.module("myApp", []);
myAppRef.controller("Controller1",['$scope', myController1]);
function myController1($scope) {

    this.contactList = [];

    this.addToContactList = function() {
        this.contactList.push($scope.contact);     
        $scope.contact = {};        
    }

    this.removeContact = function(idx) {
        this.contactList.splice(idx,1); // contactList is undefined here... why?
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" class='container'>
    <div ng-controller="Controller1 as ctrl">
        <h1>Contacts Manager</h1>
        <hr>
        <div class="panel panel-primary">
            <div class="panel-heading">Contact Editor</div>
            <div class="panel-body">
                <form role="form" >
                    <div class="form-group">
                        <label for="firstName">First Name</label>
                        <input type="text" name="firstName" class="form-control" placeholder="First Name" ng-model="contact.firstName"/>
                    </div>
                    <div class="form-group">
                        <label for="lastName">Last Name</label>
                        <input type="text" name="lastName" class="form-control" placeholder="Last Name" ng-model="contact.lastName"/>
                    </div>
                    <div class="form-group">
                        <label for="phoneNumber">Phone Number</label>
                        <input type="text" name="phoneNumber" class="form-control" placeholder="Phone Number" maxlength="10" ng-model="contact.phoneNumber"/>
                    </div>
                </form>
            </div>
            <div class="panel-footer">
                <input type="checkbox" name="disableAddRec" ng-model="disableAddRec"> <label for="disableAddRec">Disable Adding Contacts</label>
                <span class="pull-right"><button name="addContact" class="btn btn-primary" ng-disabled="disableAddRec" ng-click="ctrl.addToContactList()">Add Contact</button></span>
            </div>
        </div>

        <table class="table table-bordered table-hover" ng-if="ctrl.contactList.length > 0">
               <thead>
                   <tr><th>S. No.</th><th>First Name</th><th>Last Name</th><th>Phone Number</th><th>Action</th></tr>                       
               </thead>
               <tbody>
                   <tr ng-repeat="cntct in ctrl.contactList">
                       <td>{{$index+1}}</td><td>{{cntct.firstName}}</td><td>{{cntct.lastName}}</td><td>{{cntct.phoneNumber}}</td>
                       <td><button class="btn btn-danger" ng-click="ctrl.removeContact($index)">Remove</button></td>
                   </tr>
               </tbody>
        </table>
    </div>
</body>

Upvotes: 0

Shomz
Shomz

Reputation: 37701

It's a wrong context - your inner this is not the same as your outer this. Either use $scope or store a reference to the controller context.

For example:

    var self = this;
    self.contactList = [];

    self.addToContactList = function() {
        self.contactList.push($scope.contact);     
        $scope.contact = {};        
    }

    this.removeContact = function(idx) {
        self.contactList.splice(idx,1); // contactList is now defined 
    }

Or:

    $scope.contactList = [];

    $scope.addToContactList = function() {
        $scope.contactList.push($scope.contact);     
        $scope.contact = {};        
    }

    $scope.removeContact = function(idx) {
        $scope.contactList.splice(idx,1); // contactList is now defined as well
    }

Upvotes: 2

Related Questions