I have a page that displays a couple of lists from a REST service built on nodejs and mongodb. On the client I'm using angularjs for directives, data binding, etc.
In this case I'm having trouble figuring out the best way to display related data, in some cases even calculating values, between the two lists.
For example I have a list of properties, each has some tenants (tenantIds actually), and I want to display first the list of properties, then for each property I show its tenants, and some info about each tenant. For this I load the properties and tenants from the REST service in the controller, then I use the following method in the view within an ng-repeat row to display the tenant's lease expiry:
{{$parent.leaseInfo(property).expires}}
The implementation of leaseInfo looks like this:
$scope.leaseInfo = function(property) {
if (property && $scope.tenants) {
for (var i = 0; i < property.tenantIds.length; i++) {
var tenant = $scope.lookupTenant(property.tenantIds[i]);
// TODO: does tenant have active lease? for now just pick the first one
if (tenant.leaseStart && tenant.leaseStart.length > 0) {
var label = 'info';
var expires = '?';
var leasePeriod = (tenant.monthToMonth) ? 'Month-to-month' : tenant.leasePeriod + '-month';
var leaseStart = moment(tenant.leaseStart);
var leaseEnd = leaseStart.add(tenant.leasePeriod, 'M');
var leaseDaysLeft = leaseEnd.diff(moment(), 'days');
// expired is danger, < 31 is warning, otherwise okay
if (leaseDaysLeft <= 0) {
label = 'danger';
expires = 'expired ' + leaseEnd.fromNow();
} else if (leaseDaysLeft <= 31) {
label = 'warning';
expires = 'expires ' + leaseEnd.fromNow();
} else {
label = 'success';
expires = 'expires ' + leaseEnd.fromNow();
}
return { label: label , leasePeriod: leasePeriod, expires: expires };
}
};
}
return { label: 'danger', leasePeriod: 'Vacant', expires: 'no lease' };
};
I think this is a somewhat egregious example of how I'm misusing angluar bindings and controllers. I even call this multiple times on the same tenant row to display the different components of the object that is returned. However I chose my worst example to get my point across about what I'm struggling with.
One option would be to assemble the entire JSON structure in node, and have the tenant and calculated values already expanded and calculated in the REST service response. However to me this feels like I'd be breaking some REST service principles in returning a deeply nested structure that is a mixture of multiple entities.
I guess I could also do this on the client in the angular controller and assemble this object structure once the collections are loaded. This feels a little better to me as I would not have the strange $parent binding and inefficient lookup and calculation per-binding.
I appreciate any advice on how to bind and display related data such as this, and from within child scopes such as the ng-repeat row.