0

I have problem with ng-if and $scope. I have list of people, which every person is added to new list ($scope.hired). I need to make "Delete" button for people which are already added in list. I wanted to do this with ng-if, but I probably doing it wrong. I have done script for adding people to new list but I need to do deleting script - showing delete button and deleting script from $scope.hired. Can you help me?

Angular:

$scope.hired.push({
    'id': '25',
    'name': 'John Doe',
    'value': '100'
});

HTML:

<a href="#" class="button add" ng-click="hire(person.id)">Hire</a>
<a href="#" class="button add hired" ng-if="hired.id==person.id" ng-click="delete(person.id)">Delete</a>
Damian Hetman
  • 372
  • 4
  • 20
  • 1
    http://stackoverflow.com/questions/8217419/how-to-determine-if-javascript-array-contains-an-object-with-an-attribute-that-e I think `ng-if="hired.id==person.id"` doesn't make sense unless this is an `ng-repeat` for objects in `hired` – EpicPandaForce Mar 18 '17 at 14:58
  • where's your delete function? – Dario Mar 18 '17 at 14:58
  • "I need to make "Delete" button for people which are already added in list" is not a question. It's a requirements statement. Show us evidence that you've tried to solve the problem yourself. – georgeawg Mar 18 '17 at 16:20

2 Answers2

0

Why don't you use ng-show and ng-hide.

<a href="#" ng-show="hired.id==person.id" class="button add hired" ng-click="delete(person.id)">
  Delete
</a>
Uzbekjon
  • 11,655
  • 3
  • 37
  • 54
  • Thing is that hired.id==person.id doesn't work. I tried with `ng-show` and still nothing. – Damian Hetman Mar 18 '17 at 14:53
  • Create a fiddle that replicates your problem. `console.log` the value of `hired`. Are you sure it has correct value? How and where are you setting the value of `hired` object? Please share that code as well. – Uzbekjon Mar 18 '17 at 14:56
0

It's good practice to use the controllerAs syntax. Whenever you use the ngIf directive it creates it's own scope and so by referencing the parent controller by it's controllerAs syntax, you can always be sure to access it's data (and know where the data comes from!).

Here we declare an array named applicants and an array named hired and set them to be a properties of the controller.

We can then "hire" an applicant by calling the hire method (also a property of the controller) passing in the applicant to hire. We simply then add it to the array of hired applicants.

When we want to remove the applicant, we call our remove method (also a property of the controller) passing in the applicant to remove. We simply then remove it from the hired array by getting it's index and splicing the hired array.

We also use track by applicant.id in the ngRepeat directive to minimise the creation of DOM elements as per the documentation.

You can know if the applicant is hired or not because it's either in the hired array or it's not.

// app.js
(function() {

  'use strict';

  angular.module('app', []);

})();

// main.controller.js
(function() {

  'use strict';

  angular.module('app').controller('MainController', MainController);

  MainController.$inject = [];

  function MainController() {

    var vm = this;

    // setup your applicants
    vm.applicants = [{
        'id': 1,
        'name': 'John Doe',
        'value': 100
      },
      {
        'id': 2,
        'name': 'Jack Smith',
        'value': 120
      },
      {
        'id': 3,
        'name': 'Sarah Doe',
        'value': 80
      }
    ];

    // setup your empty hired array
    vm.hired = [];

    // expose any functions you need to access from the view here
    vm.hire = hire;
    vm.remove = remove;

   /*
    * @name hire
    * @type function
    *
    * @description
    * Hires an applicant by adding the applicant to the hired array
    *
    * @param {applicant} The applicant to hire
    * @return nothing.
    */
    function hire(applicant) {

      // make sure vm.hired is an array
      vm.hired = angular.isArray(vm.hired) ? vm.hired : [];

      // push the new item into the array
      vm.hired.push(applicant);

    }

    /*
    * @name remove
    * @type function
    *
    * @description
    * Removes an applicant from the hired array
    *
    * @param {applicant} The applicant to remove
    * @return nothing.
    */
    function remove(applicant) {

      // get the applicant's index
      var index = vm.hired.indexOf(applicant);

      // remove the applicant
      vm.hired.splice(index, 1);

    }

  }

})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app">

  <div ng-controller="MainController as MainCtrl">

    <h2>Applicants</h2>

    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>Name</th>
          <th>Value</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="applicant in MainCtrl.applicants track by applicant.id">
          <td>{{applicant.id}}</td>
          <td>{{applicant.name}}</td>
          <td>{{applicant.value}}</td>
          <td>
            <a href ng-if="MainCtrl.hired.indexOf(applicant) === -1" ng-click="MainCtrl.hire(applicant)">Hire</a>
            <a href ng-if="MainCtrl.hired.indexOf(applicant) > -1" ng-click="MainCtrl.remove(applicant)">Remove</a>
          </td>
        </tr>
      </tbody>
    </table>

    <h2>Hired</h2>

    <pre>{{MainCtrl.hired | json}}</pre>

    <div>

For demonstrative purposes, another option is to modify the applicant itself by toggling a boolean on the applicant object (you will not then need a hire or remove method). However, I'm sure you'd want to do something else when an applicant is hired e.g. making a request to the server to update the applicant details.

// app.js
(function() {

  'use strict';

  angular.module('app', []);

})();

// main.controller.js
(function() {

  'use strict';

  angular.module('app').controller('MainController', MainController);

  MainController.$inject = [];

  function MainController() {

    var vm = this;

    // setup your applicants
    vm.applicants = [{
        'id': 1,
        'name': 'John Doe',
        'value': 100
      },
      {
        'id': 2,
        'name': 'Jack Smith',
        'value': 120
      },
      {
        'id': 3,
        'name': 'Sarah Doe',
        'value': 80
      }
    ];

  }

})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app">

  <div ng-controller="MainController as MainCtrl">

    <h2>Applicants</h2>

    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>Name</th>
          <th>Value</th>
          <th>Hired</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="applicant in MainCtrl.applicants track by applicant.id">
          <td>{{applicant.id}}</td>
          <td>{{applicant.name}}</td>
          <td>{{applicant.value}}</td>
          <td>{{applicant.hired ? 'Hired' : 'Not hired'}}</td>
          <td>
            <a href ng-click="applicant.hired = !applicant.hired">Toggle hired</a>
          </td>
        </tr>
      </tbody>
    </table>

    <pre>{{MainCtrl.applicants | json}}</pre>

    <div>
cnorthfield
  • 3,384
  • 15
  • 22