Search code examples
javascriptangularjsangularjs-watch

AngularJS $watch multiple items


What I'm trying to achieve:
Watch 'Height','Chest','Waist','Hips' & 'Thigh' scopes, on change update $storage array.

Current Problem:
Although the below works, I'm having to repeat each section 5 times and feel this can be slimmed down and cleaned up!

I'm not 100% sure if this is the best way todo this and some reassurance and advice would be helpful!

Thank you.

  defaultStats();
  function defaultStats() {
    if ($scope.$storage.userData.bodyType === undefined) {
      $scope.$storage.userData.bodyType = (
        {'height': 525,'chest': 32,'waist': 30,'hips': 34,'thighs': 20,'bodyType': bodyType}
      );
    }
    $scope.height = $scope.$storage.userData.bodyType.height;
    $scope.chest = $scope.$storage.userData.bodyType.chest;
    $scope.waist = $scope.$storage.userData.bodyType.waist;
    $scope.hips = $scope.$storage.userData.bodyType.hips;
    $scope.thighs = $scope.$storage.userData.bodyType.thighs;
  }
  var bodyType = 'triangle';
  $scope.$watch('height', function() {
    $scope.$storage.userData.bodyType = (
      {'height': $scope.height,'chest': $scope.chest,'waist': $scope.waist,'hips': $scope.hips,'thighs': $scope.thighs,'bodyType': bodyType}
    );
  });
  $scope.$watch('chest', function() {
    $scope.$storage.userData.bodyType = (
      {'height': $scope.height,'chest': $scope.chest,'waist': $scope.waist,'hips': $scope.hips,'thighs': $scope.thighs,'bodyType': bodyType}
    );
  });
  $scope.$watch('waist', function() {
    $scope.$storage.userData.bodyType = (
      {'height': $scope.height,'chest': $scope.chest,'waist': $scope.waist,'hips': $scope.hips,'thighs': $scope.thighs,'bodyType': bodyType}
    );
  });
  $scope.$watch('hips', function() {
    $scope.$storage.userData.bodyType = (
      {'height': $scope.height,'chest': $scope.chest,'waist': $scope.waist,'hips': $scope.hips,'thighs': $scope.thighs,'bodyType': bodyType}
    );
  });
  $scope.$watch('thighs', function() {
    $scope.$storage.userData.bodyType = (
      {'height': $scope.height,'chest': $scope.chest,'waist': $scope.waist,'hips': $scope.hips,'thighs': $scope.thighs,'bodyType': bodyType}
    );
  });

Update

  // Default Stats (Average UK Woman)
  defaultStats();
  function defaultStats() {
    if ($scope.$storage.userData.bodyType === undefined) {
      $scope.$storage.userData.bodyType = (
        {'height': 525,'chest': 32,'waist': 30,'hips': 34,'thighs': 20,'bodyType': bodyType}
      );
    }
    $scope.height = $scope.$storage.userData.bodyType.height;
    $scope.chest = $scope.$storage.userData.bodyType.chest;
    $scope.waist = $scope.$storage.userData.bodyType.waist;
    $scope.hips = $scope.$storage.userData.bodyType.hips;
    $scope.thighs = $scope.$storage.userData.bodyType.thighs;
  }
  var bodyType = 'triangle';
  $scope.$watchGroup(['height', 'chest', 'waist', 'hips', 'thighs'], function() {
     $scope.$storage.userData.bodyType = ({'height': $scope.height,'chest': $scope.chest,'waist': $scope.waist,'hips': $scope.hips,'thighs': $scope.thighs,'bodyType': bodyType});
  });
  // Reset Stats
  $scope.resetStats = function() {
    // Reset
    $scope.$storage.userData.bodyType = (
      {'height': 525,'chest': 32,'waist': 30,'hips': 34,'thighs': 20, 'bodyType': ''}
    );
    defaultStats();
  };

Solution

  • I would suggest to use $watchGroup

    So your watchers should look like

    $scope.$watchGroup(['height', 'chest', 'waist', 'hips', 'thighs'], function() {
         $scope.$storage.userData.bodyType = ({'height': $scope.height,'chest': $scope.chest,'waist': $scope.waist,'hips': $scope.hips,'thighs': $scope.thighs,'bodyType': bodyType});
    });
    

    link to the documentation: $watchGroup