1

I am having trouble in proper calculation of numerical values in an array inside a loop.

Scenario

  • The tbody generates a list of dynamic values.
  • The button inside td has a function called preBookThis() with params.
  • When the User clicks the button, it will trigger the function then push the data into an array variable.
  • Upon pushing, there will be a for loop that will iterate and compute the values. ($scope.nights is the two dates - ie. 2018-05-05 and 2018-05-07, so it will have a value of 2)

The problem

  • Lets imagine that there were three rows in the tbody and have the following values.

    $scope.nights = 2; row1 = 100; row2 = 200; row3 = 300;

  • When the user clicks the button in row 1 the computation works and performs as expected

    amount_row1 = 200;

but...

  • When the user clicks the button in row 2, the computed values of the first row will be doubled.

    amount_row1 = 400; amount_row2 = 400;

and also...

  • When the user clicks the button in row 3, the computed values of the first row and second row will be doubled again.

    amount_row1 = 800; amount_row2 = 800; amount_row3 = 600;

The final output should be:

 amount_row1 = 200;
 amount_row2 = 400;
 amount_row3 = 600;

HTML

<tbody ng-repeat="room in roomsDisplay">
    <tr>
        <td>
            <div class="col-md-6"><img ng-src="images/rooms/{{room.room_image}}"></div>         
        </td>
        <td>
            <div style="margin-top: 20px;"><input type="button" 
                ng-click="preBookthis({room})" class="btn btn-primary" 
                value="Book this Room"></div>
        </td>
    </tr>
</tbody>

JS

$scope.preBookthis = function(data){
    $scope.totalAmount = 0;
    $scope.bookData.push({ 
        'room_name': data.room.room_name, 
        'price': data.room.price,
        'amount': $scope.amount,
        'id' : data.room.rooms_type_id
    });

    _.forEach($scope.bookData, function(value, key){
        value.amount = value.amount * $scope.nights;
    });
}
Emjey23
  • 339
  • 1
  • 4
  • 16
  • I can't help, since I don't know enough about the subject. But I'd like to commend you on a very detailed and high quality answer. I'm sure that'll increase the chances of getting answered. – ItamarG3 May 05 '18 at 15:35
  • I really appreciate your commendation. I hope someone can answer because I am really frustrated in this, can't solve it. – Emjey23 May 05 '18 at 15:38
  • What is the last line in the method for? – ItamarG3 May 05 '18 at 15:42
  • Also, you seem to be multiplying by `$scope.nights` twice. – ItamarG3 May 05 '18 at 15:48
  • I updated my codes in the last part, removed the unnecessary codes that may confuse others. thanks. – Emjey23 May 05 '18 at 15:50

2 Answers2

2

Do the calculations only once when you add the new object and don't loop over all the others that have had it calculated already

Something like:

$scope.preBookthis = function(data){
    $scope.totalAmount = 0;
    $scope.bookData.push({ 
        'room_name': data.room.room_name, 
        'price': data.room.price,
        'amount': $scope.amount * $scope.nights,// calculate only for this item
        'id' : data.room.rooms_type_id
    });  
}
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • nice. Didn't think about that. Certainly better than my idea :D – ItamarG3 May 05 '18 at 15:56
  • I didn't see that one. Really good job. Now, my only problem is the `total_amount` of the all `pushed` data. Thank you. – Emjey23 May 05 '18 at 16:01
  • Can use the loop to get total or just add new amount to existing total – charlietfl May 05 '18 at 16:03
  • Nice, got it working both. Anyway, I have other problems but it is not related to question I posted. It is the opposite of this one though, I will try to solve it myself first. Thank you. – Emjey23 May 05 '18 at 16:07
  • Opposite meaning how to remove one? If so this might help https://stackoverflow.com/questions/15453979/how-do-i-delete-an-item-or-object-from-an-array-using-ng-click/15454424#15454424 – charlietfl May 05 '18 at 16:08
  • Yeah. Anyway, I already got it working. I just modifed my exisiting code on that one and followed the tip you gave. Thanks, – Emjey23 May 05 '18 at 16:11
  • The link you gave, I think it is also where I got the answer on how to remove the specific row in the table. Really appreciate your help. Kudos. – Emjey23 May 05 '18 at 16:14
1

The problem rises from $scope.bookData being changed entirely whenever the function is called.

When the function is called, $scope.bookData might contain objects for other rows. those objects have an amount value. In your loop, you multiply that value by $scope.nights (which is 2).

So you are multiplying all the rows' values by 2.

You are repeatedly changing the values for amount.

try this:

_.forEach($scope.bookData, function(value, key){
    value.amount = (key+1) * $scope.nights*100;
});

EDIT:

Actually, the other answer features a better solution.

ItamarG3
  • 4,092
  • 6
  • 31
  • 44