<!doctype html>
<html ng-app="ui.bootstrap.demo">

<head>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
  <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
  <script src="example.js"></script>
</head>

<body>

  <div ng-controller="myCtrl">
    <h3>Some test data data</h3>
    <div>Get 'key1'======> {{myMap.get('key1')}}</div>
    <div>Arr ==========> {{myArr}}</div>
    <div>filtered ======> {{myMap | fromMap}}</div>
    <div>myArrFromMap=> {{myArrFromMap}}</div>
    <div>myLoopedMap==> {{myLoopedMap}}</div>
    <div>myLoopedMap2=> {{myLoopedMap2}}</div>

    <h3>ng repeat in myLoopedMap</h3>
    <div ng-repeat="item in myLoopedMap">
      Item:`{{item}}`
    </div>
 
    
    <h3>ng repeat in myArrFromMap</h3>
    <div ng-repeat="(index, value) in myArrFromMap">
      value[0]:`{{value[0]}}`, value[1]:`{{value[1]}}`, index: `{{index}}`
    </div>
    
  </div>
</body>

</html>
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo')
.filter('fromMap', ()=> mapObject=>[...mapObject])
.controller('myCtrl', function($scope, $log) {
  $scope.myMap = new Map([
    ['key1', 'value1'],
    ['key2', 'value2'],
    ['key3', 'value3'],
    ['key4', 'value4'],
  ]);
  const unsuscribeWatcher1 = $scope.$watch(() => $scope.myMap.size, (newVal, oldVal) => {
    if (newVal !== oldVal) {
      //Splicing and pushing keeps the reference to the Array instead of reassigning.
      $scope.myLoopedMap.splice(0);
      $scope.myLoopedMap.push(...[...$scope.mySet].filter(k => $scope.myMap.has(k)).map(k => $scope.myMap.get(k)))
      $scope.myArrFromMap.splice(0);
      $scope.myArrFromMap.push(...[...$scope.myMap])
    }
  })
  const unsuscribeWatcher2 = $scope.$watch(() => $scope.mySet.size, (newVal, oldVal) => {
    if (newVal !== oldVal) {
      $scope.myLoopedMap.splice(0);
      $scope.myLoopedMap.push([...$scope.mySet].filter(k => $scope.myMap.has(k)).map(k => $scope.myMap.get(k)));
    }
  })
  $scope.mySet = new Set(['key1', 'key3']);
  $scope.mySet.add('not in the Map')
  $scope.mySet.add('key7')
  $scope.myKeys = ['key1', 'key3'];
  $scope.myArr = [
    ['key1', 'value1'],
    ['key2', 'value2'],
    ['key3', 'value3'],
    ['key4', 'value4'],
  ];
  $scope.myArrFromMap = [...$scope.myMap]
  $scope.myLoopedMap = [...$scope.mySet].filter(k => $scope.myMap.has(k)).map(k => $scope.myMap.get(k))
  $scope.myLoopedMap2 = [...$scope.myKeys].reduce((acc, k) => {
    return $scope.myMap.has(k) ? acc.concat($scope.myMap.get(k)) : acc;
  }, [])

  // added to the map later
  setTimeout(() => {
    $scope.$apply(() => {
      // this will be updated as we are watching the Map
      $scope.myMap.set('key7', 'value7')
    })
    setTimeout(() => {
      unsuscribeWatcher1(); // this breaks the watching of the Map
      $scope.$apply(() => {
        // this will not be updated as the watcher is not working anymore
        $scope.myMap.set('key8', 'value8')
      })
    }, 3000)
  }, 3000)


});