ng-classify
ng-classify copied to clipboard
Lost "this" reference in factory method when I tried to "ng-classify" it.
I am sure this is a simple issue, but confusing nonetheless. I have an angular factory that I am trying to "ng-classify". The existing code looks something like this:
app.factory 'Data', [
'$log'
"$q'
($log, $q) ->
getData1: ->
data1 = $q.defer()
. . .
return data1.promise
getData2: ->
data2 = $q.defer()
. . .
return data2.promise
getSomeComboData: ->
comboData = $q.defer()
$q.all(@getData1, @getData2).then (Data1, Data2) ->
. . .
return ComboData.promise
. . .
]
This works. No problem. Sometimes my controllers need Data1, sometimes Data2, sometimes ComboData. I can imagine other scenarios where a factory method might need to call another public method of the same factory.
This is what I did to "ng-classify" it:
class Data extends Factory
constructor: ($log, $q) ->
return: {
getData1: ->
data1 = $q.defer()
. . .
return data1.promise
getData2: ->
data2 = $q.defer()
. . .
return data2.promise
getSomeComboData: ->
comboData = $q.defer()
$q.all(@getData1, @getData2).then (Data1, Data2) ->
. . .
return ComboData.promise
. . .
}
The problem is now @getData1 and @getData2 are undefined. Somehow the "this" reference to the factory singleton has been lost. Am I missing something?
I'm not exactly sure why the two would behave differently; however, I did notice a few typos.
Typos fixed
app.factory 'Data', [
'$log'
'$q'
($log, $q) ->
getData1: ->
data1 = $q.defer()
return data1.promise
getData2: ->
data2 = $q.defer()
return data2.promise
getSomeComboData: ->
comboData = $q.defer()
$q.all(@getData1, @getData2).then (Data1, Data2) ->
return ComboData.promise
compiles to
app.factory('Data', [
'$log', '$q', function($log, $q) {
return {
getData1: function() {
var data1;
data1 = $q.defer();
return data1.promise;
},
getData2: function() {
var data2;
data2 = $q.defer();
return data2.promise;
},
getSomeComboData: function() {
var comboData;
comboData = $q.defer();
$q.all(this.getData1, this.getData2).then(function(Data1, Data2) {});
return ComboData.promise;
}
};
}
]);
and
class Data extends Factory
constructor: ($log, $q) ->
return {
getData1: ->
data1 = $q.defer()
return data1.promise
getData2: ->
data2 = $q.defer()
return data2.promise
getSomeComboData: ->
comboData = $q.defer()
$q.all(@getData1, @getData2).then (Data1, Data2) ->
return ComboData.promise
}
compiles to
var Data;
Data = (function() {
function Data($log, $q) {
return {
getData1: function() {
var data1;
data1 = $q.defer();
return data1.promise;
},
getData2: function() {
var data2;
data2 = $q.defer();
return data2.promise;
},
getSomeComboData: function() {
var comboData;
comboData = $q.defer();
$q.all(this.getData1, this.getData2).then(function(Data1, Data2) {});
return ComboData.promise;
}
};
}
return Data;
})();
angular.module('app').factory('Data', ['$log', '$q', Data]);
They are virtually identical.
Another way would be to use the Revealing Module Pattern
class Data extends Factory
constructor: ($log, $q) ->
getData1 = ->
data1 = $q.defer()
data1.promise
getData2 = ->
data2 = $q.defer()
data2.promise
getSomeComboData = ->
comboData = $q.defer()
$q.all(getData1, getData2).then (Data1, Data2) ->
ComboData.promise
return {getData1, getData2, getSomeComboData}
compiles to
var Data;
Data = (function() {
function Data($log, $q) {
var getData1, getData2, getSomeComboData;
getData1 = function() {
var data1;
data1 = $q.defer();
return data1.promise;
};
getData2 = function() {
var data2;
data2 = $q.defer();
return data2.promise;
};
getSomeComboData = function() {
var comboData;
comboData = $q.defer();
$q.all(getData1, getData2).then(function(Data1, Data2) {});
return ComboData.promise;
};
return {
getData1: getData1,
getData2: getData2,
getSomeComboData: getSomeComboData
};
}
return Data;
})();
angular.module('app').factory('Data', ['$log', '$q', Data]);
This way you need not worry about the this
context, and it becomes evident what the exposed API is by observing the return statement.