-1

Please read the controller code. I am not able to print the price of each pizza. I have figured out that even after I initialize the price and name of mainDish object it does not show on the webpage when the code is run the first time. /* I am writing these extra words because stackoverflow doesn't let me post this because it thinks the code requires more detail...*/

    <!DOCTYPE html>
<html ng-app="app">

<head>
    <title>Tony's Pizza</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"
        crossorigin="anonymous">
</head>

<body ng-controller="menuController">
    <div class="container">
        <h1>Tony's Pizza</h1>
        <h2>{{model.title}}</h2>
        <div>
        <label><input type="radio" name="category" ng-click="changeMainDish('Cheese Pizza')"/> Cheese Pizza</label>
    </div>
    <div>
        <label><input type="radio" name="category" ng-click="changeMainDish('Pepperoni Pizza')"/> Pepperoni Pizza</label>
    </div>
    <div>
        <label><input type="radio" name="category" ng-click="changeMainDish('Margherita  Pizza')"/> Margherita Pizza</label>
    </div>
    <div>
        <label><input type="radio" name="category" ng-click="changeMainDish('BBQ Chicken Pizza')"/> BBQ Chicken Pizza</label>
    </div>
    <div>
        <label><input type="radio" name="category" ng-click="changeMainDish('Combo Pizza')"/> Combo Pizza</label>
    </div>
    <div>
        <h3>Selected Item</h3>
        <pre>{{model.mainDish.name}}</pre>
    </div>
    <div>
    <h3>Special Instuctions</h3>
    <textarea class="form-control" ng-model="model.specialInstructions"></textarea>
</div>
<div>
    <h3>Order Summary</h3>

<pre> {{ model.mainDish.name }} {{ model.mainDish.price }} - {{ model.specialInstructions }} </pre></div>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script src="./app/app.js"></script>
<script src="./app/menuController.js"></script>
</body>

</html>

script>

var app = angular.module('app', []);
app.controller('menuController', [
    '$scope',
    function($scope){
        $scope.model={title:'Our Menu',
                    mainDish:[{name:''},{price:''}]};
        $scope.$watch('model.mainDish.name',function(newValue,oldValue){
        if(newValue==='BBQ Chicken Pizza'){
            alert('You have selected BBQ Chicken Pizza');
            model.mainDish.price= 10;
}
        if(newValue==='Cheese Pizza'){

            model.mainDish.price= 15;
}
        if(newValue==='Pepperoni Pizza'){

            model.mainDish.price= 20;
}
        if(newValue==='Margherita Pizza'){

            model.mainDish.price= 30;
}
        if(newValue==='Combo Pizza'){

            model.mainDish.price= 40;
}
    });
        $scope.changeMainDish = function (item) {
        $scope.model.mainDish.name = item;
        }
    }
]);</script>
georgeawg
  • 48,608
  • 13
  • 72
  • 95
Math_Zombie
  • 135
  • 5
  • That;s not the way you do radio buttons in AngularJS. Radio buttons need `ng-model` directives. For more information, see [AngularJS ` – georgeawg May 23 '18 at 21:59
  • This approach violates the [DRY programming principle](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) because main dish selections need to be entered both in the HTML template and the JS controller. This makes adding new dishes tedious and error prone. – georgeawg May 23 '18 at 22:42

2 Answers2

0

The problem occurs because you of the way you declared mainDish. In your code, mainDish is an array but you access it like it's an object. You cannot use $watch for nested objects they way you want to. The best solution is to follow the answer given on this question, and use ng-change and ng-model.

NocNit
  • 280
  • 1
  • 7
  • it doesn't work , moreover as I said if I write as : mainDish:{name:'test',price:'test'}; it should initialize the states and show the initial values on page – Math_Zombie May 23 '18 at 20:15
  • According to this question and answer https://stackoverflow.com/questions/24876944/angularjs-watch-an-object-property-in-an-object-array, you cannot use $watch on nested objects like mainDish inside model. It suggests you use an ng-change and ng-model – NocNit May 23 '18 at 21:09
  • Updated answer. – NocNit May 23 '18 at 21:13
0

Your are updating model rather than $scope.model in your $watch.

<!DOCTYPE html>
<html ng-app="app">

<head>
  <title>Tony's Pizza</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>

<body ng-controller="menuController">
  <div class="container">
    <h1>Tony's Pizza</h1>
    <h2>{{model.title}}</h2>
    <div>
      <label><input type="radio" name="category" ng-click="changeMainDish('Cheese Pizza')"/> Cheese Pizza</label>
    </div>
    <div>
      <label><input type="radio" name="category" ng-click="changeMainDish('Pepperoni Pizza')"/> Pepperoni Pizza</label>
    </div>
    <div>
      <label><input type="radio" name="category" ng-click="changeMainDish('Margherita  Pizza')"/> Margherita Pizza</label>
    </div>
    <div>
      <label><input type="radio" name="category" ng-click="changeMainDish('BBQ Chicken Pizza')"/> BBQ Chicken Pizza</label>
    </div>
    <div>
      <label><input type="radio" name="category" ng-click="changeMainDish('Combo Pizza')"/> Combo Pizza</label>
    </div>
    <div>
      <h3>Selected Item</h3>
      <pre>{{model.mainDish.name}}</pre>
    </div>
    <div>
      <h3>Special Instuctions</h3>
      <textarea class="form-control" ng-model="model.specialInstructions"></textarea>
    </div>
    <div>
      <h3>Order Summary</h3>

      <pre> {{ model.mainDish.name }} {{ model.mainDish.price }} - {{ model.specialInstructions }} </pre>
    </div>
  </div>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
  <script src="./app/app.js"></script>
  <script src="./app/menuController.js"></script>
</body>

</html>
<script>
  var app = angular.module('app', []);
  app.controller('menuController', [
    '$scope',
    function($scope) {
      $scope.model = {
        title: 'Our Menu',
        mainDish: {
          name: 'test', 
          price: 'test'
        }
      };
      $scope.$watch('model.mainDish.name', function(newValue, oldValue) {
        if (newValue === 'BBQ Chicken Pizza') {
          alert('You have selected BBQ Chicken Pizza');
          $scope.model.mainDish.price = 10;
        }
        if (newValue === 'Cheese Pizza') {

          $scope.model.mainDish.price = 15;
        }
        if (newValue === 'Pepperoni Pizza') {

          $scope.model.mainDish.price = 20;
        }
        if (newValue === 'Margherita Pizza') {

          $scope.model.mainDish.price = 30;
        }
        if (newValue === 'Combo Pizza') {

          $scope.model.mainDish.price = 40;
        }
      });
      $scope.changeMainDish = function(item) {
        $scope.model.mainDish.name = item;
      }
    }
  ]);
</script>
jbrown
  • 3,025
  • 1
  • 15
  • 22
  • Thanks...but it should have atleast showed the initial price and name if I initialized it . – Math_Zombie May 23 '18 at 20:21
  • The problem is that you had mainDish as an array of objects rather than just an object. I've amended my answer to show this. – jbrown May 23 '18 at 20:28
  • but I corrected the mainDish , still it did not show the initial values before I correct the watch code – Math_Zombie May 23 '18 at 20:48
  • Which values are you referring to? I see the test values under selected item and order summary. – jbrown May 23 '18 at 22:57