1

I am building up an mobile application using Ionic Framework and Cordova Sqlite. I am displaying the data from the sqlite database in an ionic list. Each of the ionic list item has a button to delete the corresponding item from the database. On the click of the button, the data gets deleted from the database, but it continues to appear in the ionic list, until I go back to some other view and come back to it. I need to refresh the view immediately and remove that item from the list also. Also, all my SQL codes are in controller, so I also need to reload the controller, it seems.

app.js

.state('app.cart', {
    url: '/cart',
    views: {
      'menuContent': {
        cache: false,
        templateUrl: 'templates/cart.html',
        controller: 'NFController'
      }
    }
  })

controller.js

.controller('NFController', ['$scope', '$cordovaSQLite','$cordovaToast','$state','$stateParams', function($scope, $cordovaSQLite, $cordovaToast, $state,$stateParams) {


        $scope.listItems= [];
        $cordovaSQLite.execute(db, 'SELECT * FROM cart ORDER BY id DESC')
            .then(
                function(res) {

                    $scope.cartTotal=0;
                    $scope.crtPP=0;
                    if (res.rows.length > 0) {
                      for (var i=0; i<res.rows.length; i++) {
                         **$scope.crtPP=res.rows.item(i).productPrice*res.rows.item(i).productQuantity;
                    $scope.cartTotal=$scope.cartTotal+$scope.crtPP;
                    $scope.CProductName=res.rows.item(i).productName; 
                        $scope.listItems.push(res.rows.item(i));**
                      }
                    }
                    else{
                          $scope.status = "No Products in the Cart";
                    }
                },
                function(error) {
                    $scope.statusMessage = "Error on loading: " + error.message;
                }
            );


    $scope.remove = function(id) {

          $cordovaSQLite.execute(db, 'DELETE from cart WHERE id=?', [id])
            .then(function(res) {

                    //$state.go($state.current, {}, {reload: true});
                    var current = $state.current;
                    var params = angular.copy($stateParams);
                    $state.transitionTo(current, params, { reload: true, inherit: true, notify: true });  
                    $cordovaToast.show('Removed from Cart','short','bottom');

            }, function(error) {
                  console.log(error.message);
            })


    }
}])

remove() is called on the button click.

Updated Code :

.controller('NFController', ['$scope', '$cordovaSQLite','$cordovaToast', function($scope, $cordovaSQLite, $cordovaToast) {


        $scope.listItems= [];
        $cordovaSQLite.execute(db, 'SELECT * FROM cart ORDER BY id DESC')
            .then(
                function(res) {

                    $scope.cartTotal=0;
                    $scope.crtPP=0;
                    if (res.rows.length > 0) {
                      for (var i=0; i<res.rows.length; i++) {
                        $scope.listItems.push(res.rows.item(i));
                      }

                      cartTotal(); //cartTotal() called initially when the controller loads
                      console.log("Cart Total : " + $scope.cartTotal);
                    }
                    else{

                          console.log("####console######## NO results found #######"+"Table record #: ");
                    }
                },
                function(error) {

                }
            );

    $scope.remove = function(id) {

          $cordovaSQLite.execute(db, 'DELETE from cart WHERE id=?', [id])
            .then(function(res) {

                    var index=$scope.listItems.indexOf(id)
                    $scope.listItems.splice(index,1);
                    cartTotal(); //CartTotal() called second time
                    $cordovaToast.show('Removed from Cart','short','bottom');

            }, function(error) {
                  console.log(error.message);
            })
            console.log(id);

    }

   function cartTotal()
    {
        angular.forEach($scope.listItems, function(item, key) {
            $scope.crtPP = item.productPrice * item.productQuantity;
            $scope.cartTotal += $scope.crtPP; 
            console.log($scope.cartTotal);
        });
    }
}])
vkm
  • 548
  • 7
  • 23

1 Answers1

3

When you execute the delete in your

$scope.remove = function(id) { 
  ...
}

you don't need to the reload of the view. You can easily remove all this:

var current = $state.current;
var params = angular.copy($stateParams);
$state.transitionTo(current, params, { reload: true, inherit: true, notify: true });  

you array of items $scope.listItems= []; should be bound to the view so you simply have to remove the item from the array or reload it and your view will update automatically.

   $scope.remove = function(id) {
          $cordovaSQLite.execute(db, 'DELETE from cart WHERE id=?', [id])
            .then(function(res) {
                    $scope.listItems = <find the id in the list and remove it>;
                    $cordovaToast.show('Removed from Cart','short','bottom');

            }, function(error) {
                  console.log(error.message);
            })
    }

instead of passing the id only to your $scope.remove method you can pass the whole item and use it to find the element in the array so it can be removed:

$scope.remove = function(item) {
      $cordovaSQLite.execute(db, 'DELETE from cart WHERE id=?', [item.id])
    .then(function(res) {
        var index = $scope.listItems.indexOf(item);
        $scope.listItems.splice(index, 1); 
        $cordovaToast.show('Removed from Cart','short','bottom');

    }, function(error) {
          console.log(error.message);
    })
}

and your HTML:

<a class="btn" ng-click="remove(item)">Delete</a>

UPDATE:

Regarding the question in your comments, I would calculate the total using the array $scope.listItems.

I guess you have defined a property in your scope:

$scope.cartTotal = 0;

I would add a function:

function calculateCartTotal()
{
    angular.forEach($scope.listItems, function(item, key) {
        $scope.cartTotal += item.amount;
    });
}

PS: item.amount or whatever your value is.

and recalculate after the splice:

$scope.remove = function(item) {
      $cordovaSQLite.execute(db, 'DELETE from cart WHERE id=?', [item.id])
    .then(function(res) {
        var index = $scope.listItems.indexOf(item);
        $scope.listItems.splice(index, 1); 

        calculateCartTotal();

        $cordovaToast.show('Removed from Cart','short','bottom');

    }, function(error) {
          console.log(error.message);
    })
}

If you cannot do that cause you don't have a value item.amount (or similar) you can always re-execute the query in that function and feed $scope.cartTotal.

UPDATE:

function cartTotal()
{
    $scope.cartTotal = 0;

    angular.forEach($scope.listItems, function(item, key) {
       $scope.crtPP = item.productPrice * item.productQuantity;
       $scope.cartTotal += $scope.crtPP; 
       console.log($scope.cartTotal);
    });
}
LeftyX
  • 35,328
  • 21
  • 132
  • 193
  • Hey @LeftyX.Thank You for helping out, buddy. I am accepting the answer. Just one more issue, if you would like to help. I have just updated the controller under **. I need to display $scope.cartTotal in my view, which is being calculated directly through db. Though, the list item goes away hrough your code, the cartTotal doesn't get updated.How to handle this? – vkm Oct 01 '15 at 09:58
  • Hey, thanks for helping, yet again. But, i am afraid that this might not be the desired solution. I need to display the cart total already when the view is loaded, initially and on deleting a item i need to refresh it. if I would call calculateCartTotal() at both the places, wouldn't it calculate the cart total multiple times. – vkm Oct 01 '15 at 11:20
  • I am afraid I don't understand. If you could put together a demo on [plunker](http://plnkr.co/) or [codepen](http://codepen.io/) it would be helpful. – LeftyX Oct 01 '15 at 11:30
  • please check the updated code and let me know, if i am clear enough now. – vkm Oct 01 '15 at 11:40
  • The value of the cart called through cartTotal() initially, with the Select Statement, gets appended with the value of the cart called through cartTotal() under remove(), when an item is deleted. :-( – vkm Oct 01 '15 at 11:45
  • Thanks buddy! It worked like a charm. Just one info - I guess the code you added to remove item from listItem just deletes the last item in the array, instead of the specific item. You may want to check it, if you wish to. – vkm Oct 01 '15 at 12:17
  • I think it should work like that. You pass the item (element of the list) find the index in the list `var index = $scope.listItems.indexOf(item);` and remove it `$scope.listItems.splice(index, 1);`. You can see how it works [here](http://codepen.io/anon/pen/WQRPgp) – LeftyX Oct 01 '15 at 12:31