OOP in AngularJS within minutes - #1 Defining a class

Posted by Krzysztof Zbiciński on 2015-08-01.

When it comes to object oriented programming, JavaScript is a little bit weird in comparison with other (preferably C-like) languages. The same holds true while working with AngularJS.

The topic has been already covered in the Internet multiple times. If you’re looking for a comprehensive article, just google it up. This blog post is intended to be used more like a handnote or a cheatsheet, so I’ll try to keep it extremally concise.


The following example represents a Task class which contains two properties: a textual content and a (theoretically) read-only array of hashtags. The latter property is automatically regenerated by extracting hashtags from the task’s content via a regex expression.

Long story short, defining a class in AngularJS looks as follows:

task.factory.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
myApp.factory('Task', function () {
// defining a constructor
function Task(content) {
// initialization of the object happens here
this.setContent(content);
}
// defining public members
Task.prototype = {
setContent: function (value) {
this._content = value;
//looking for hashtags
var regexp = /\B\#\w\w+\b/g;
this._tags = this._content.match(regexp);
},
getContent: function () {
return this._content;
},
getTags: function () {
return this._tags;
}
};
// defining a static method
Task.restore = function (data) {
return new Task(data._content);
};
return Task;
});

There is no way to define a purely private property (or at least I don’t know one). In my opinion, the best that can be done is to follow a specific naming convention. Names of properties that are not intended to be directly modified should start with an underscore character (_content) and be accompanied by appropriate getters and setters.

To become usable in a controller, the class has to be injected as any other module and we’re done:

main.controller.js
1
2
3
4
myApp.controller('MainController', ['$scope', 'Task', function ($scope, Task) {
$scope.task = new Task('Lorem lipsum #hashtag');
$scope.anotherOne = Task.restore({ _content: 'Another one'});
}]);


Comments: