I have a resource whose data depends on another resource. Transaction
is tied to a SplitTransaction
which has a list of transactions.
From a transaction, I need to know the total of transactions of the SplitTransaction
.
This is my resource:
.factory('Transaction', ['$resource', '$http', '$rootScope', 'SplitTransaction', '$q', function($resource, $http, $rootScope, SplitTransaction, $q){
var Transaction = $resource('/api/v1/transaction/:id', {}, {
query: {
method: 'GET',
isArray: true,
transformResponse: tastypieDataTransformer($http).concat(function (data, headersGetter) {
for (var idx in data) {
var transaction = data[idx];
if (transaction.installment_of) {
var split = transaction.installment_of.split('/');
var installmentId = split[split.length-1];
SplitTransaction.get({id: installmentId}).$promise.then(function (installment) {
transaction.installment_total = installment.transactions.length;
});
}
}
return data;
})
}
});
This is the html:
<tr class="transaction-row" ng-repeat="transaction in group.transactions">
<td ng-bind="transaction.installment_total"></td>
</tr>
It shows nothing on the rendered html.
I tried to use promises:
transformResponse: tastypieDataTransformer($http).concat(function (data, headersGetter) {
for (var idx in data) {
var transaction = data[idx];
if (transaction.installment_of) {
var split = transaction.installment_of.split('/');
var installmentId = split[split.length-1];
var deferred = $q.defer();
SplitTransaction.get({id: installmentId}).$promise.then(function (installment) {
var installment_total = installment.transactions.length;
deferred.resolve(installment_total);
});
transaction.installment_total = deferred.promise;
}
}
return data;
})
Now the binding seems to work, but it only shows [object Object]
on the html.
What am I doing wrong?
Edit:
If I set the transaction.installment_total
outside the SplitTransaction.get
callback, it shows on the HTML, so the bindings are ok.. Like this:
if (transaction.installment_of) {
var split = transaction.installment_of.split('/');
var installmentId = split[split.length-1];
transaction.installment_total = 0; // shows "0" on the html
SplitTransaction.get({id: installmentId}, function (installment) {
...
});
}
For some reason what happens inside the callback does not reflect on the bindings...
Temporary solution:
I removed the code from the transformResponse
to where I load the Transaction
's:
Transaction.query(filter).$promise.then(function (result) {
$.each(result, function (idx, transaction) {
if (transaction.installment_of) {
var split = transaction.installment_of.split('/');
var installmentId = split[split.length-1];
transaction.installment_total = 0;
SplitTransaction.get({id: installmentId}, function (installment) {
transaction.installment_total = installment.transactions.length;
});
}
});
$scope.allTransactions = result;
$scope.transactionGroups = groupTransactions($scope.groupBy);
window.transactions = $scope.transactionGroups;
}).finally(function () {$scope.loading = false;});
Can't say why this works. Maybe the objects get copyed after the transformResponse
, making my reference to transaction
on the callback scope useless...
It is not quite obvious, what is getting bound to transaction.installment_total in your html. Usually it may be property of $rootScope or $scope of bound controller and I do not see any controller here.
Also, not obvious, what is
group.transactions
. If it's empty, then nothing will be rendered.But if you managed somehow to bind transaction.installment_total to your html, then the problem is here:
You are binding Promsie object to your html and you need to bind result of this promise:
That is if you want to use promises. But there is another way.
ngResource's method return promise, which you can assign to your view and when data will be available, this promise will be replaced with this data.
This is from documentation:
In another words...
...should also work.