2

Application Description:

I am making a simple Ecommerce website(single page product listing) using AngularJS and Rails. It only handles Cash On Delivery Orders. The user adds products and checksout. All this process is done in Angular. The cart is stored in localstorage.When he checksout a modal pops up asking him to choose choose between two shipping methods. Depending on the shipping method he chooses the price which is displayed on the bootstrap modal has to be updated.

Problem Description:

The page flickers(the curly braces appear) when I try to do this. When I reload the whole thing it works properly.

After some research I found that I have to use $compile but I am not sure of how to use it. i read several tutorials but I am not able to figure it out.

Here is my angular code. The two functions I used in bootstrap modal are shippingCharges(), totalPrice(). They are at the end of the angular code.

<script>
  var products = angular.module('products', []);


  products.controller('ListController', ['$scope', function($scope) {
    $scope.categories = JSON.parse('<%= j raw(@categories_hash.to_json) %>');
    $scope.activeCategory = null;
    $scope.cart = JSON.parse(localStorage.getItem('cart'));

    if (!!$scope.cart) {
      angular.forEach($scope.cart, function(item_quantity, item_id) {
        $scope.categories.forEach(function(category, index1) {
          category.products.forEach(function(product, index2) {
            if (item_id == product.id) {
              product.ordered_quantity = item_quantity;
            }
          });
        });
      });
    };

    $scope.formData = {
      shipping: "scheduled"
    };


    $scope.addProductToCart = function(product_id) {
      // event.preventDefault();
      var cart = $scope.cart;
      if (!cart) {
        cart = {}
      }

      if (!cart[product_id]) {
        cart[product_id] = 0;
      }

      cart[product_id] += 1;

      localStorage.setItem('cart', JSON.stringify(cart));
      $scope.cart = cart;
    };

    $scope.increaseQuantity = function(product) {
      product.ordered_quantity += 1;
      $scope.addProductToCart(product.id);
    };

    $scope.decreaseQuantity = function(product) {
      product.ordered_quantity = product.ordered_quantity - 1;

      var cart = $scope.cart;
      if (!cart) {
        cart = {}
      }

      cart[product.id] -= 1;

      localStorage.setItem('cart', JSON.stringify(cart));
      $scope.cart = cart;
    };

    $scope.removeProductFromCart = function(product_id) {
      var cart = $scope.cart;

      cart[product_id] = 0;

      localStorage.setItem('cart', JSON.stringify(cart));
      $scope.cart = cart;
    }

    $scope.totalPrice = function() {
      total = 0;

      $scope.categories.forEach(function(category, index) {
        category.products.forEach(function(product, index1) {
          total += product.price*product.ordered_quantity; 
        });
      });

      return total;
    };

    $scope.toggleCategory = function(category) {
      if ($scope.activeCategory == category.category_id) {
        $scope.activeCategory = null;
      } else {
        $scope.activeCategory = category.category_id;
      }
    };

    $scope.shouldShowCategory = function(category) {
      return($scope.activeCategory == category.category_id);
    };




    $scope.shippingCharges = function() {
      var cart = $scope.cart;
      var shippingcost;
      if ($scope.formData.shipping == "scheduled"){
        shippingcost = 35;

      }else if ($scope.formData.shipping == "unscheduled"){
        shippingcost = 75;
      }
      cart["shipping"]=shippingcost;
      localStorage.setItem('cart', JSON.stringify(cart));
      return shippingcost;

    }

  }]);
</script>

Boostrap Modal Code

<div class="modal fade" id="checkoutModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" ng-controller="ListController" ng-cloak >
      <div class="modal-dialog modal-lg">
        <div class="modal-content">
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <h4 class="modal-title" id="myModalLabel">Information for delivery</h4>
          </div>
          <div class="modal-body checkout-details">
            <form id="checkoutForm" class="form-horizontal">
              
              <div id="checkoutLoading" class="progress progress-striped active hidden">
                <div class="progress-bar progress-bar-success" style="width: 100%"></div>
              </div>
              <fieldset>
                <legend>Choose a delivery method</legend>
                  <p>We are making a schedule delivery to <strong><%= delivery_timing[0] %></strong> on <strong><%= delivery_timing[1] %></strong>. If you are not located in the mentioned places please choose an unscheduled delivery</p>

               <div class="radio">
                  <label><input type="radio" name="shipping" value="scheduled" ng-model="formData.shipping" ng-change="setShipping('scheduled')">Scheduled Delivery(Rs. 35)</label>
                </div>
                <div class="radio">
                  <label><input type="radio" name="shipping" value="unscheduled" ng-model="formData.shipping" ng-change="setShipping('unscheduled')">Unscheduled Delivery(Rs.75)</label>
                </div>
               <p class="ng-cloak">Total: {{shippingCharges() + totalPrice()}}</p>

              </fieldset>
              <fieldset>
                <legend>Please provide delivery details:</legend>
                <div class="errorMessage alert alert-dismissible alert-danger hidden">
                <strong>Oh snap!</strong> Please provide phone number and address.
              </div>
                <div id="checkoutEmailFormGroup" class="form-group">
                  <label for="checkoutPhone">Email</label>
                  <input type="email" class="form-control" id="checkoutEmail" placeholder="me@example.com" >
                </div>

                <div id="checkoutPhoneFormGroup" class="form-group">
                  <label for="checkoutPhone">Phone</label>
                  <input type="phone" class="form-control" id="checkoutPhone" placeholder="+91-9999-999-999" >
                </div>

                <div id="checkoutAddressFormGroup" class="form-group">
                  <label for="checkoutAddress">Address</label>
                  <textarea class="form-control" id="checkoutAddress" placeholder="Plot No
  Street Name
  City" rows="5"></textarea>
                </div>
              </fieldset>
            </form>
          </div>
          <div class="modal-footer">
            <p class="ng-cloak" >Total cost: {{shippingCharges() + totalPrice()}}</p>
            <button type="button" class="btn btn-default" data-dismiss="modal">Go Back</button>
            <button id="checkout_trigger" type="button" class="btn btn-brown">Confirm</button>
          </div>
        </div>
      </div>
    </div>

Can you please let me know how to compile the code in the Bootstrap modal?

  • try ng-cloak on the ` – apneadiving Jun 03 '15 at 07:00
  • @apneadiving I already tried that. It did not work. I read that Angular does not bind(?) the html in the bootstrap modal. We have to do it with $compile. I am not able to do that :( – Ravikanth Andhavarapu Jun 03 '15 at 07:58
  • I fear you dont understand angular enough. Too hard to help if you dont provide a plnkr or a jsbin. – apneadiving Jun 03 '15 at 08:00
  • @apneadiving You are right. I am new to angular. Here is the link to the app hosted on heroku http://goodseeds.herokuapp.com/. The backend is written in rails. If you add a couple of products to the shopping bag and check out a modal pops up with the moustaches. If you reload and go back it works fine. Here is the same code in plunker: http://plnkr.co/edit/2msue65j5OoncJKm2zhU?p=preview Plunker cannot run it because of lack of inputs from backend. – Ravikanth Andhavarapu Jun 04 '15 at 13:00

0 Answers0