javascriptangularjsjavascript-objectsangularjs-resource

Extending $resource object removes prototype from Factory


Here is the code that I have right now:

// Factory
angular.factory('Student', function() {
    var defaults = {
        StudentId: null
    };

    var Student = function(params) {
        angular.extend(this, angular.copy(defaults), params);
    };

    // Prototype function for Student
    Student.prototype.hasStudentId = function() {
        return this.StudentId != null;
    };
});

// Service
angular.service('StudentService', ['Student', '$resource', function(Student, $resource) {
    var service = {};

    service.student = $resource('student/:studentId'. {} { load: {method: 'GET'} });

    service.loadStudent = function(studentId) {
        var currentStudent = service.student.load(studentId); // HTTP call

        currentStudent.$promise.then(function() {
            // I expect the object currentStudent would have hasStudentId() prototype function, but it's not
            angular.extend(currentStudent, new Student(currentStudent));

            // However, if I use 'new' keyword, studentObj has prototype hasStudentId() function
            var studentObj = new Student(currentStudent);
        });
    };

    return service;
}]);

As you see, after I extend currentStudent object, currentStudent doesn't have the prototype function hasStudentId(). However, if I use new Student(currentStudent), it has the prototype function properly.

Does Angular.extend ignore prototype functions?

Currently, currentStudent object only has the $resource's prototype functions.


Solution

  • As per the documentation angular.extend only copies own enumerable properties. Prototype properties may be enumerable but they do not belong to the object itself and, therefore, do not qualify as own. MDN has an article on this here.