1

I have my Angular code at Plunkr

This is not a school test or anything. It's my own trial and experiment with some front-end processing of AngularJS, so please feel free to help me.

The code contains two ng-repeats divs, children to a parent Controller. The two ng-click somehow intertwine and go wary in their behaviors. I tried with different toggle functions toggleLaptopChoice,toggleTVChoice but can't get them to work properly.

Problems:

1- Listing of products: purchasing 2 TVs would list them in Laptop portion.

2- TV products overwrote Laptop products.

1&2 are coupling and decoupling issue. also, how to bind {{laptop.product}}, {{television.product}} to the ng-click label? Should the ng-click be at label or at the input itself?

3- How to bind handling fee, so the Totals will update automatically on changing of the fee? (I sort of thinking about adding a Directive but kinda want the two Ctrls to handle everything instead of requiring an extra service).

4- Have I handled scopes well? Provide me better ways to handle Totals (totalization|sum calculation)

5- Further suggestions to optimize the sample code? more flexibility, clarity and less but useful abstraction.

Perhaps, further develop it with quantity for each product. The purchase check will become a mean to drop product(s) out of the cart.

Thank you very much.

<div ng-form name="orderForm" ng-controller= "shoppingListCtrl as sl">
  <label for="">Configurate (backend) Handling fee: USD$ </label>
  <input type="number" name="fee_input" ng-model="sl.fee" ng-init="sl.fee=7.50"/>
  <span class="error" ng-show="orderForm.fee_input.$error.number">
        Not valid number!</span>
  <!-- need ng-form name="orderForm" in div to trigger validation on ng-show "orderForm.fee_input" -->
  <br>
  <br>
  <div ng-controller= "merchandiseListCtrl as ml" style="border: 2px solid olive; padding:0 0 1em 1em">
    <h3>Laptop List</h3>
    <table>
      <thead>
        <tr>
          <th>Product</th>
          <th>Purchased</th>
          <th>Price</th>
          <th>Tax</th>
        </tr>
      </thead>
      <tr ng-repeat="laptop in ml.laptops">
        <td>{{laptop.product}}</td>
        <td>
          <!--<label for="laptopCheck" ng-click="$event.stopPropagation();"> http://stackoverflow.com/a/26962680/5828821-->
          <label for="laptopCheck" ng-click="ml.toggleHandler(laptop, ml.laptops, ml.laptopTotal, sl.fee);">
            <!--<input id="laptopCheck" type="checkbox" class="ng-pristine ng-valid" ng-click="ml.toggleSelection($event,laptop)" ng-model="laptop.purchased" ng-init="laptop.purchased=false">-->
            <input id="laptopCheck" type="checkbox" ng-model="laptop.purchased">
          </label>
        </td>
        <td>{{laptop.price}}</td>
        <td>{{$parent.sl.tax}}</td>
      </tr>
    </table>

    <!-- display the selection -->
    Laptop count: {{ ml.laptopTotal.count }} units
    <br>
    <div ng-if="ml.laptopTotal.products">
      <ul ng-repeat="product in ml.laptopTotal.products">
        <li>{{$index+1}}) {{product}}</li>
      </ul>
    </div>
    <br>
    Price for selected laptops before tax: {{ml.laptopTotal.value | currency:"USD$ ":2 }}
    <br>
    Taxing info: {{ml.getTax()}} %

    <br>
    <h3>Television List</h3>
    <table>
      <thead>
        <tr>
          <th>Product</th>
          <th>Purchased</th>
          <th>Price</th>
          <th>Tax</th>
        </tr>
      </thead>
      <tr ng-repeat="television in ml.televisions">
        <td>{{television.product}}</td>
        <td>
          <label for="televisionCheck" ng-click="ml.toggleHandler(television, ml.televisions, ml.televisionTotal, sl.fee);">
            <input id="televisionCheck" type="checkbox" ng-model="television.purchased">
          </label>
        </td>
        <td>{{television.price}}</td>
        <td>{{$parent.sl.tax}}</td>
      </tr>
    </table>
    TV count: {{ ml.televisionTotal.count }} units
    <br>
    <div ng-if="ml.televisionTotal.products">
      <ul ng-repeat="product in ml.televisionTotal.products">
        <li>{{$index+1}}) {{product}}</li>
      </ul>
    </div>
    <br>
    Price for selected televisions before tax: {{ml.televisionTotal.value | currency:"USD$ ":2 }}
    <br>
    Taxing info: {{ml.getTax()}} %
    <br>
    <label for="">$scope element: </label>{{access.child}}
    <br>
    _____________________________________________________________________________
    <br>
    <br>
    <label for="">Grand Total: </label>{{ml.televisionTotal.altogether | currency:"USD$ ":2 }}
    <br>
    <br>
    ________________STILL INSIDE the scope of <strong>merchandiseListCtrl</strong>________________
  </div>
    <br>

  ______________NOW <strong>OUTSIDE that scope</strong>, it's shoppingList scope NOW______________
  <br>This is a <i>{{access.child}}</i>
  <br>
  <br>
  <span style='color:gray'>Formula for total: TOTAL = (total of selected laptops + total of selected televisions)*((100+tax)/100) +handling_fee</span>
  <br>
  <strong>Shopping at {{sl.market}}, the total for your cart <span ng-if="sl.count"> ( {{sl.count}} items ) </span> is {{ sl.total | currency:"USD$ ":2}}</strong>
  Your shopping cart to checkout:
  <br>
  <div ng-if="ml.products">
    <ul ng-repeat="product in ml.products">
      <li>{{$index+1}}) {{product}}</li>
    </ul>
    <br>
    The user interactive, selected data can be further proceeded through a form Submit button for back-end processing.
  </div>

</div>
Pristine Kallio
  • 505
  • 5
  • 19
  • Can we all just stop to appreciate the irony of this question? "This is not a school test or anything" -- js file in plnkr is called exam1.js – mhodges Aug 01 '16 at 18:52
  • exam1.js is just how I name it. If you follow along with Derek tutorial, he names thing that way. so I do the same for the sake of simplicity. https://www.youtube.com/watch?v=gu6TfGZXUZs – Pristine Kallio Aug 01 '16 at 18:54
  • I didn't say I believe you, I just found it funny. Haha Anyway, I am trying to work on a solution - give me a few mins – mhodges Aug 01 '16 at 18:56
  • I did all that experiment code and pose many questions I could to explore more capability of the Angular1 and have a concrete understanding of things, have clues to optimize the code the most likely efficient way (as mentioned in my last question). thanks in advance for any help from you and other people. – Pristine Kallio Aug 01 '16 at 19:03
  • I am confused as to your use of Object.assign(...). That is why your TV products end up in your laptop products array.. Make sure you are using assign as you intend. Docs here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign – mhodges Aug 01 '16 at 19:20
  • Too many *"problems"* for only one question.. – developer033 Aug 01 '16 at 19:21
  • I know that's not your only issue, though. The structure of this code and how objects/arrays are referenced is a nightmare to follow. I think some serious refactoring is in order – mhodges Aug 01 '16 at 19:22
  • I was trying to generate 2 objects to store selected TVs and laptops, and out of the scope, I want to display another, the 3rd unordered list, listing all the selected, purchased products (tv+laptop) to proceed checkout. Object.assign is to join those 2 objects. So, I can ng-repeat through the 3rd object (containing all selected products). that's the goal and why I tried with Object.assign. – Pristine Kallio Aug 01 '16 at 20:47
  • I used Object.assign() several times in the past, this time I referenced to the Merging object portion in Mozilla.Org library and wanted to achieve the result in that portion. – Pristine Kallio Aug 01 '16 at 20:55

1 Answers1

0

I resolved my questions 1,2 & 3 (simple $watch does the job). See Plukr for test result.

The selected laptop and TV products are just arrays, so it makes more sense to just push them to a new array instead of attempt objects merging.

4 & 5 pending your advice and help. Also, how to Bind product name to the checkbox? Clicking on Asus would all toggling the checkbox too.

Pristine Kallio
  • 505
  • 5
  • 19