1

I am attempting to include additional 'model' objects that are useful in my Angular application. Suppose I have two separate javascript files as shown below. I would like to add a "createStudent" function to my teacher prototype, and have it call the student constructor method. How can teacher.js correctly reference student.js? What is the method for injecting that here?

FYI, I know there are many methods for including rich object models in Angular. I don't want to go the route of using Restangular at the moment for example. I want to keep this extremely simple at the moment, and hopefully increase my understanding of angular modules.

Thanks!!

---------- teacher.js -----------

(function() {

    var teacherConstructor = function() {

        var teacher = {
          student: []
        };
      
        return teacher;

    };


    var module = angular.module("MyApp.models");
    module.value("teacber", teacberConstructor);
}());

---------- student.js

(function() {

    var studentConstructor = function(theTeacher) {

        var student = {
          myTeacher: theTeacher
        };
      
        return student;

    };


    var module = angular.module("MyApp.models");
    module.value("student", studentConstructor);
}());

1 Answer 1

2

A possible solution - use factory:

(function() {
    var module = angular.module("MyApp.models");

    module.factory("teacher", ["student", function(Student) {
        var teacherConstructor = function() {
            ...
            var student = new Student(this);
            ...
        };

        return teacherConstructor;
    }]);
})();

Anyway the definition of the teacher "class" must be done inside Angular's definition function, for it to be able to reference the student.

This however introduces an unecessary closure. I would suggest dropping the outer function, in favor of Angular's native way:

angular.module("MyApp.models").factory("Teacher", ["student", function(Student) {
    var Teacher = function() {
        ...
        var student = new Student(this);
        ...
    };

    return Teacher;
}]);

As a sidenote, it is customary for "classes" to start with capital. i.e. Student, Teacher. And the constructor may as well have the name of the class, thus teacherConstructorTeacher in the code above.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! That is illuminating. A followup question: I assume that only one of these .factory() calls can inject the other, otherwise I would have a circular dependency. So I must choose whether Teacher creates new students, or a Student creates it's teacher. Is that right? And a comment: I have been trying to avoid the use of the 'new' keyword as per Crockford's book "Javascript: The Good Parts", because using a constructor function as opposed to new Teacher() offers a lot of advantages, such as the ability to enforce private vs public functions on an object.
Hi! About circularity: Yes, you are right - but that would be a problem in any language. You can still have private members with the new operator - I may be missing some details of course. But the most productive (IMO) is to pick a style that suits you, so sure, no problem with constructor functions. (Some people would even argue to entirely drop the OO logic and go functional all the way with Javascript :)
Angular seems to lend itself to functional programming by providing services, which as far as I can see are straight up singletons. I thought about simply flattening my object graph into a bunch of effectively static functions, but couldn't make myself do it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.