StackOverflow_22898927: injecting-scope-into-an-angular-service-function

Illustration of answer to http://stackoverflow.com/questions/22898927/injecting-scope-into-an-angular-service-function.

by ExpertSystem

HTML

<script src="http://code.angularjs.org/1.7.8/angular.min.js"></script>
<div ng-controller="myCtrl">
  <div ng-repeat="student in students">
    <b>{{ student.id }}</b>
    <span>{{ student.name }}</span>
    <input type="text" ng-model="student.grade" />
    <button ng-click="saveStudent(student)">Save</button>
  </div>
  <div class="status">
    {{ students.length ? statusMessage : 'Loading...' }}
  </div>
</div>

CSS

body {
  border: 1px solid black;
}

.status {
  border-top: 1px solid black;
}

JavaScript

angular.
  module('myApp', []).

  controller('myCtrl', function ($scope, $timeout, StudentService) {
    $scope.statusMessage = '';

    $scope.students = StudentService.students;
    $scope.saveStudent = function (student) {
      StudentService.save(student).then(function () {
        $scope.statusMessage = 'Student saved successfully!';
        $timeout(function () { $scope.statusMessage = ''; }, 2000);
      });
    };
  }).

  factory('StudentService', function ($http, $q) {
    var path = 'data/people/students.json';
    var students = [];
    
    var save = function (student) {
      if (student.id === null) {
        students.push(student);
      } else {
        for (var i = 0; i < students.length; i++) {
          if (students[i].id === student.id) {
            students[i] = student;
            break;
          }
        }
      }
      
      // Emulate an async response from the server.
      return $q.resolve(student);
    };
    
    // In the real app, this should be a GET,
    // but jsFiddle needs a POST to mock AJAX requests:
    $http.post('/echo/json/', mockPayload).then(function (response) {
      response.data.forEach(function (student) {
        students.push(student);
      });
    });
    
    return {
      students: students,
      save: save
    };     
  });

// Mock data for faking AJAX requests.
var studentsArr = [
  {id: '01', name: 'Student 1', grade: 'A'},
  {id: '02', name: 'Student 2', grade: 'B'},
  {id: '03', name: 'Student 3', grade: 'C'}
];
var mockDelay = 2;  // seconds
var mockData = JSON.stringify(studentsArr);
var mockPayload = 'json=' + encodeURIComponent(mockData) + '&' +
                  'delay=' + mockDelay;