Backer
Backer

Reputation: 1114

When deleting object from scope, it hides the rest in Angularjs

I have a list of clients inside my $scope.clients which i use a ng-repeat to display.

<tr ng-repeat="client in clients">
   <td class="l-h-3x">{{client.name}}</td>
   <td class="l-h-3x p-t-md text-right">
       <button type="button" ng-click="deleteUser($index)>Delete</button>
   </td>
</tr>

Now, it works perfectly if i delete the last client in the list, it deletes it from my database and removes it from $scope.clients. The problem comes when i delete any client that is not the last one. It deletes the correct client from my database, and removes it from my $scope.clients, but then it hiddes all of the remaining clients that is below.

Fx.

$scope.clients [
{id: 1, name: 'Adam'},
{id: 2, name: 'Nadja'},
{id: 3, name: 'Marc'},
{id: 4, name: 'Casper'}]

I delete the client where id = 3 it works like a charm, but when i delete the client where id = 2, it deletes it from my database and removes it from the scope, but also hiddes the client where id = 3 and id = 4.

Below is my function I use at the moment to delete a client

$http.delete(api.getUrl('user', person_to_delete.id), {
        user: $scope.user
    })
.success(function(data, status, headers, config) {
        $scope.clients.splice(idx, 1);
    })
.error(function(data, status, headers, config) {
    });

After reviewing my question (with the help of your inputs) i discovered some dumb mistakes (sorry about that) and i have now updated my post, but I still have the same issue. It still hiddes client 3 & 4, after deleting client 2

Upvotes: 0

Views: 101

Answers (3)

Artem Petrosian
Artem Petrosian

Reputation: 2954

Don't really understand the purpose of using for here. After first splice your indexes in array are shifted and thats why all items after index has been deleted.

You can use splice directly since you known the proper element index.

Also, you can use the power of promises that returned by $http service, see example below:

$http.delete(api.getUrl('user', person_to_delete.id), {
    user: $scope.user
})
.success(function(data, status, headers, config) {
    // this callback will be called asynchronously
    // when the response is available 
    $scope.clients.splice(idx, 1);
})
.error(function(data, status, headers, config) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
});

Upvotes: 1

Tiago Martins
Tiago Martins

Reputation: 727

Not going into specifics about your code, check out this fiddle I've built from it. Looks like it does what you expected it to do.

<html ng-app="clientsApp">
<head>
    <script src="https://code.angularjs.org/1.3.14/angular.min.js"></script>
    <script>
    var app = angular.module("clientsApp", []);
    app.controller("clientsCtrl", function($scope) {
        $scope.clients = [
        {id: 1, name: 'Adam'},
        {id: 2, name: 'Nadja'},
        {id: 3, name: 'Marc'},
        {id: 4, name: 'Casper'}];

        $scope.deleteUser = function(idx) {
        var person_to_delete = $scope.clients[idx];

            for (var i = $scope.clients.length; i--;) {
                var user = $scope.clients[i];
                if ($scope.clients.indexOf(user) == idx) {
                    $scope.clients.splice(i, 1);
                }
            }
        };
    });
    </script>
</head>
<body ng-controller="clientsCtrl">
    <table>
        <tr ng-repeat="client in clients">
            <td class="l-h-3x">{{client.name}}</td>
            <td class="l-h-3x p-t-md text-right">
                <button type="button" ng-click="deleteUser(clients.indexOf(client))">Delete</button>
            </td>
        </tr>
    </table>
</body>
</html>

Upvotes: 1

Scott Vickers
Scott Vickers

Reputation: 611

I think the problem is probably in the for loop.

for (var i = $scope.clients.length; i--;) {
    var user = $scope.clients[i];
    if (clients.indexOf(user) == idx) {
        $scope.clients.splice(i, 1);
    }
}

You're looping from the end of the $scope.clients list and then moving backwards comparing each $scope.client to each client in some other clients list trying to find one that matches.

If you find one that matches then you're asking if the client in the 'clients' list happens to be in the same index position as the client in the $scope.clients list when it was clicked, and finally if that was true then splice it from the list.

Why is any of that necessary?

You already have the index position of the item that was clicked (from the function argument), why not just use that directly in the splice call?

$scope.clients.splice(idx, 1);

Upvotes: 0

Related Questions