Mo.
Mo.

Reputation: 27465

How can I delete $scope object from service

Is it possible to delete $scope.contacts object from the service() function ?

var module = angular.module('app', []);
module.service('ContactService', function() {
  //contacts array to hold list of all contacts
  this.delete = function(item) {
    console.log(item);
    var confirmDelete = confirm("Do you really need to delete " + item.name + " ?");
    if (confirmDelete) {
      var curIndex = $scope.contacts.indexOf(item);
      $scope.contacts.splice(curIndex, 1);
    }
  }
});
module.controller('ContactController', function($scope, ContactService) {
  $scope.contacts = [{
    id: 0,
    'name': 'Viral',
    'email': '[email protected]',
    'phone': '123-2343-44'
  }];
  $scope.delete = function(id) {
    ContactService.delete(id);
    if ($scope.newcontact.id == id) $scope.newcontact = {};
  }
})
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ContactController" class="container">
  <table class="table table-striped table-bordered">
    <thead>
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Phone</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="contact in contacts">
        <td>{{ contact.name }}</td>
        <td>{{ contact.email }}</td>
        <td>{{ contact.phone }}</td>
        <td> <a href="javascript:void(0)" ng-click="edit(contact.id)">edit</a> | <a href="javascript:void(0)" ng-click="delete(contact)">delete</a>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Upvotes: 0

Views: 1037

Answers (4)

AWolf
AWolf

Reputation: 8980

I think adding $scope to a service is not the Angular way.

It's better to let the service manage your data (as mentioned in Golo's answer). Then you can also do $http request to keep your model/data in synch. with your backend.

Have a look at the demo below or in this fiddle.

angular.module('app', [])
    .factory('contactService', function () {
        
    //contacts array to hold list of all contacts
    var service = {
        contacts: [{
            id: 0,
                'name': 'Viral',
                'email': '[email protected]',
                'phone': '123-2343-44'
        }, {
            id: 1,
                'name': 'John',
                'email': '[email protected]',
                'phone': '123-2343-44'
        }, {
            id: 2,
                'name': 'Jane',
                'email': '[email protected]',
                'phone': '123-2343-44'
        }],
        
        delete: function (item) {
            console.log(item);
            var itemIndex;
            var confirmDelete = confirm("Do you really need to delete " + item.name + " ?");
            if (confirmDelete) {
                angular.forEach(this.contacts, function(contact, index) {
                    if(item.id === contact.id) {
                        itemIndex = index;
                    }
                });

                this.contacts.splice(itemIndex, 1);
            }
        }
    };
    return service;
})
    .controller('contactController', function ($scope, contactService) {
    $scope.contacts = contactService.contacts;

    $scope.delete = function (contact) {
        contactService.delete(contact);
        //if ($scope.newcontact.id == id) $scope.newcontact = {};
    }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="contactController">
    <ul>
        <li ng-repeat="contact in contacts">{{contact.name}}
            <button ng-click="delete(contact)">remove</button>
        </li>
    </ul>
</div>

Upvotes: 0

Ori Drori
Ori Drori

Reputation: 191976

You don't have to send the $scope. Just send the contacts array:

var module = angular.module('app', []);
module.service('ContactService', function () {
//contacts array to hold list of all contacts
this.delete  = function (contacts, item) {
	var confirmDelete = confirm("Do you really need to delete " + item.name + " ?");
	if (!confirmDelete) {
		return;
	}

	var curIndex = contacts.indexOf(item);
	contacts.splice(curIndex, 1);
};
});
module.controller('ContactController', function ($scope, ContactService) {
$scope.contacts = [{
		id : 0,
		'name' : 'Viral',
		'email' : '[email protected]',
		'phone' : '123-2343-44'
	}
];
$scope.delete  = function (item) {
	var id = item.id;
	ContactService.delete ($scope.contacts, item);
	if ($scope.newcontact.id == id)
		$scope.newcontact = {};
}
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ContactController" class="container">
  <table class="table table-striped table-bordered">
    <thead>
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Phone</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="contact in contacts">
        <td>{{ contact.name }}</td>
        <td>{{ contact.email }}</td>
        <td>{{ contact.phone }}</td>
        <td> <a href="javascript:void(0)" ng-click="edit(contact.id)">edit</a> | <a href="javascript:void(0)" ng-click="delete(contact)">delete</a>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Upvotes: 0

Golo Roden
Golo Roden

Reputation: 150624

Short answer: No, you can't.

Long answer: No, you can't, because a scopes are tied to controllers that in turn are tied to views, and services are view-independent (hence their name ;-)).

So, to cut a long story short: It's not possible to access a scope from within a service, because the service is responsible for multiple views (and scopes). You will never know which scope to use, because for a service there is no "ambient" or "current" scope.

If you actually want to to access the scope directly, hand it over to the service (as suggested in the answer by Andy Newman). But I'd not recommend this, because then the service acts on something it should not know about.

A better approach would be to think about messaging, so that the service lets all interested parties (i.e., controllers) know to do something on their scope.

Probably the best option is not to hold the data in the controller, but to put the data into the service, so that it's the service's responsibility to deal with the data and delete them when appropriate. Controllers then only need to tell the service what to do.

Upvotes: 0

Andy Newman
Andy Newman

Reputation: 281

This would not make sense, as a service is a singleton (one exists per app), whereas you can have multiple controllers. If the service could get hold of a scope, how does it know it got the right one!

You could make this work by passing the $scope into the delete function, like

this.delete = function($scope, item)

and

ContactService.delete($scope, id)

Upvotes: 1

Related Questions