0

Below is the link of my code:

https://www.w3schools.com/code/tryit.asp?filename=FDTQ99YQS60B

How do I get users to only be able to buy 2 players the position "Defender"? Put another way, how do I get users to only be able to buy 2 Objects of each position?

Deji James
  • 367
  • 6
  • 20
  • Possible duplicate of [Get JavaScript object from array of objects by value or property](http://stackoverflow.com/questions/13964155/get-javascript-object-from-array-of-objects-by-value-or-property) – Nikolaj Dam Larsen Mar 20 '17 at 15:55

2 Answers2

1

I used Array.prototype.reduce to solve your issue. Hope this helps.

var selected = $scope.history.reduce(function(a,b){
    a[b.position] = (a[b.position] || 0) + 1;
    return a;
}, {}) || {};

//{defender:1, forward: 2, midfielder:1}

This block calculate the added counts for each player positions. if no players added, then selected would default to {}. Also, I'm passing player object instead of $index to buy method.

So, the below condition checks the number of players added for each player position.

if(!selected[player.position] || selected[player.position]<2){
    $scope.history.push(player);
}else{
    alert('You can add only two players per position');
}

here player.position is from the player object passed to buy method.

So, let say,

selected = {defender:1, forward: 2, midfielder:1};

and player passsed to buy method as,

player = {name : "Chinedu 'Anuxx' Anukwem", Team : "FBGFC", price: 8000000, position:'forward',image: src='http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'};

console.log(selected[player.position]) // 2

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, PlayerService) {
    $scope.playersSelected = "0/6";
    $scope.total = 50000000;
    //keep trak of what was bought already
    $scope.history = PlayerService.getSelectedPlayers();
    $scope.denteries = [];
    $scope.players = [{
        name: "Yasin 'YB' Amusan",
        Team: "Industry",
        price: 8000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Hassan 'Hasi' Akinyera",
        Team: "Industry",
        price: 5000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Femi 'Fabio' Awoniyi",
        Team: "Industry",
        price: 9000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Deji 'Dej' Awoniyi",
        Team: "Industry",
        price: 7000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Koye 'K10' Kekere-Ekun",
        Team: "Industry",
        price: 9000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Teni 'Teezee' Zacchaeus",
        Team: "Industry",
        price: 6000000,
        position: 'hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Bolaji 'Boj' Odojukan",
        Team: "Industry",
        price: 7000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Ernest",
        Team: "Industry",
        price: 6000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Fikayo 'Kyo' Etti",
        Team: "Industry",
        price: 8000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Efe Tunde-Imoyo",
        Team: "Industry",
        price: 5000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Temi 'Forbes' Afolabi",
        Team: "VGC",
        price: 14000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Dami Etomi",
        Team: "VGC",
        price: 7000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Tomi 'Belg' Belgore",
        Team: "VGC",
        price: 8000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Tobi 'Staxx' Kasali",
        Team: "VGC",
        price: 9000000,
        position: 'Hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Bobo",
        Team: "VGC",
        price: 9000000,
        position: 'Hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Ola Adeyemi",
        Team: "VGC",
        price: 5000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Pekun 'Pyzzle' Odutola",
        Team: "VGC",
        price: 9000000,
        position: 'Hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Oreva 'Revz' Amata",
        Team: "VGC",
        price: 11000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Tenny 'TK' Karim",
        Team: "YMFC",
        price: 5000000,
        position: 'Forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Andy Inegbese",
        Team: "YMFC",
        price: 5000000,
        position: 'Midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Donald 'DO' Ofik",
        Team: "YMFC",
        price: 7000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Zachy Mbadiwe",
        Team: "YMFC",
        price: 10000000,
        position: 'Forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Emeke 'Mexxo'",
        Team: "YMFC",
        price: 6000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Ife 'I-Baxx Bakare",
        Team: "YMFC",
        price: 6000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Gabriel 'Gabby' Inegbese",
        Team: "YMFC",
        price: 8000000,
        position: 'Hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Jimi Oyelola",
        Team: "YMFC",
        price: 5000000,
        position: 'Forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Chad 'Chadea' Oyefolu",
        Team: "ChadFC",
        price: 5000000,
        position: 'Forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Ekoh 'Starboy' Sagoe",
        Team: "ChadFC",
        price: 15000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Tomiwa 'JBET' Jaiyeola",
        Team: "ChadFC",
        price: 13000000,
        position: 'Forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Lemar Chris",
        Team: "ChadFC",
        price: 9000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Olumide 'Olic' Williams",
        Team: "ChadFC",
        price: 7000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Leke 'LVD' Dokomu",
        Team: "ChadFC",
        price: 7000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Dola Awosika",
        Team: "ChadFC",
        price: 5000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Nehemiah 'Memphis'",
        Team: "ChadFC",
        price: 7000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Kola 'Skippo' Ayanwale",
        Team: "ChadFC",
        price: 10000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Milekan 'Mileks'",
        Team: "ChadFC",
        price: 7000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Lanre 'Lavigz' Vigo",
        Team: "ChadFC",
        price: 8000000,
        position: 'hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Alfred 'Flyz' Obande",
        Team: "FBGFC",
        price: 6000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Chuka 'Zingy' Azinge",
        Team: "FBGFC",
        price: 6000000,
        position: 'hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Osobase 'Oso' OmoKhodion",
        Team: "FBGFC",
        price: 10000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Arnold Okuguni",
        Team: "FBGFC",
        price: 7000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Ikenna Mbadiwe",
        Team: "FBGFC",
        price: 6000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Moukhtar",
        Team: "FBGFC",
        price: 8000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Chinedu 'Anuxx' Anukwem",
        Team: "FBGFC",
        price: 8000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Tosan 'Mac' Wiltshere",
        Team: "FBGFC",
        price: 6000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Martin Agbaso",
        Team: "FBGFC",
        price: 5000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      }
    ];

    $scope.buy = function(player) {
      //remove if already added
      if(PlayerService.removePlayerFromSelection(player)){
        return;
      }

      //max 6 allowed
      if ($scope.history.length >= 6) {
        alert('max 6 allowed');
        return;
      }

      var selected = $scope.history.reduce(function(a, b) {
        a[b.position] = (a[b.position] || 0) + 1;
        return a;
      }, {}) || {};

      if (!selected[player.position] || selected[player.position] < 2) {
        PlayerService.addPlayerToSelection(player);
      } else {
        alert('You can add only two players per position');
      }
    };

    $scope.getTotal = function() {
      return $scope.history.reduce(function(tot, p) {
        tot = tot - p.price;
        return tot;
      }, $scope.total);
    };
  })
  .factory('PlayerService', function() {
    var service = {};
    var _data = {
      selectedPlayers: []
    };

    service.getSelectedPlayers = function() {
      return _data.selectedPlayers;
    };

    service.setSelectedPlayers = function(players) {
      //to maintain the array reference we are doing this, othewise we can directly assign players to selectedPlayers
      _data.selectedPlayers.splice(0, _data.selectedPlayers.length);
      players.forEach(function(player) {
        _data.selectedPlayers.push(player);
      });
    };

    service.addPlayerToSelection = function(player) {
      return _data.selectedPlayers.push(player);
    };

    service.removePlayerFromSelection = function(player) {
      var index = _data.selectedPlayers.indexOf(player);
      if (index >= 0) {
        _data.selectedPlayers.splice(index, 1);
        return true;
      }
      return false;
    };

    return service;
  })
  .controller('TestCtrl', function($scope, PlayerService){
    $scope.selectedPlayers = PlayerService.getSelectedPlayers();
  });
div[ng-controller]{
  float:left;
  box-sizing:border-box;
  width:50%;
}
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <link href="app.css" rel="stylesheet" type="text/css" />
  <title>TNF FANTASY</title>
</head>


<div class="app" ng-app="myApp">
<div ng-controller="myCtrl">

  <div class="total"><i>  <h4> Money Remaining: <br>{{getTotal() |currency}}</h4></i>
    <h4>{{history.length}}/6</h4>

  </div>

  <ul>
    <li class="players" ng-repeat="player in players">


      {{player.name}} <br> {{player.Team}} <br> {{player.price| currency}} <br> {{player.position| uppercase }}
      <br>
      <button ng-click="buy(player)">{{history.indexOf(player)>=0?'remove':'buy'}}</button>
    </li>
  </ul>
  </div>
  <div ng-controller="TestCtrl">
    <h1>Selected player accessed in another controller:</h1>
    
    <pre>{{selectedPlayers | json}}</pre>
  </div>
</div>
ajai Jothi
  • 2,284
  • 1
  • 8
  • 16
  • YES!!!! Thanks and God bless. This was perfect. Do you mind explaining this a bit? I spent the past 2 and a half days trying to work this out. @ajaiJothi – Deji James Mar 20 '17 at 16:30
  • Updated. Hope this helps :) – ajai Jothi Mar 20 '17 at 16:54
  • It really does. It has broken it down perfectly. Last question: is it possible for the limit on player selection to apply to all positions bar the "hybrid" position? It works fine the way you've explained this is purely educational – Deji James Mar 20 '17 at 17:02
  • Yes, you can have limits for each positions. eg: `var defaultCnt = 2; var limits = {hybrid:2, forward:3, defender:2};` and in condition check u can refer this limit with `if(!selected[player.position] || selected[player.position]<(limits[player.position]||defaultCnt))` instead of hardcoded count. – ajai Jothi Mar 20 '17 at 20:47
  • hey quick question. is there a way to access the selected players in another page? I tried routing to access the $scope.history array in the second page but nothing came up. I also tried a service but i'm not sure that works either. – Deji James Mar 22 '17 at 11:01
  • Yes. You have to use a `service` for sharing objects between pages. One more way is there, you can save the selected object in `$rootScope` and access it in other pages. but I wont recommend this - it is like polluting global scope. – ajai Jothi Mar 22 '17 at 13:37
  • haha at this point i won't mind polluting. But i'll give services a try again. Do i need to create a service for each of my arrays? The json file i currently have made has both the 'players' array with the objects and the 'history' array that is empty into which selected players are pushed. This did not seem to work. – Deji James Mar 22 '17 at 13:47
  • Updated the code with service implementation. Take a look :) – ajai Jothi Mar 22 '17 at 14:22
  • ah right Thanks a lot. Lemme have a look – Deji James Mar 22 '17 at 15:03
  • so i ran the code but tried to modify it by moving the TestCtrl to anther page on my folder called #status and it did not work. But it revealed another flaw in my code: that the user's choices arent saved before moving to the next page. Thank You So much though – Deji James Mar 22 '17 at 17:42
0

What you can do is before adding the player to $scope.history array you check if that position already has to 2 players selected.

Kxng Kombian
  • 467
  • 4
  • 13