I am working on my first AngularJS application in order to learn the framework.
I am currently hiting a wall finding the idiomatic way to handle nested resources.
I have areas containing buildings containing flats. One flat is only inside one building, which is turn in only inside one area.
In my database model I do not need to store the area Id together with the flat object, its parent (building Id) is enough.
Below is a minimal example I wrote to illustrate the concept. I based it on what I saw on the video from the Google I/O: http://www.youtube.com/watch?v=HCR7i5F5L8c
My question is: how can I instantiate a specific Flat resource? I have all the information needed in the URL but it doesn't strictly correspond to my model (area Id is missing).
var app = angular.module('neighborhoodApp', [
'ngResource',
'ngRoute'
]);
angular.module('neighborhoodApp')
.factory('Area', function ($resource) {
return $resource('/areas/:id', {
'id': '@_id'
});
});
angular.module('neighborhoodApp')
.factory('Building', function ($resource) {
return $resource('/areas/:aid/buildings/:id', {
'id': '@_id',
'aid': '@area_id'
});
});
angular.module('neighborhoodApp')
.factory('Flat', function ($resource) {
return $resource('/areas/:aid/buildings/:id/flats/:id', {
'id': '@_id',
'bid': '@building_id'
// 'aid': '@area_id' => my model doesn't have an area id, having a building id attached to a flat is enough to find the area
});
});
angular.module('neighborhoodApp')
.controller('AreaListCtrl', function (Area) {
this.areas = Area.query();
});
angular.module('neighborhoodApp')
.controller('AreaShowCtrl', function ($routeParams, Area) {
this.area = Area.get({
id: $routeParams.aid
});
});
angular.module('neighborhoodApp')
.controller('BuildingListCtrl', function (Building) {
this.buildings = Building.query();
});
angular.module('neighborhoodApp')
.controller('BuildingShowCtrl', function ($routeParams, Building) {
this.building = Building.get({
aid: $routeParams.aid,
id: $routeParams.rid
});
});
angular.module('neighborhoodApp')
.controller('FlatShowCtrl', function (Flat) {
this.flats = Flat.query();
});
// What is the idiomatic way to pass the area id (from $routeParams.aid)
// so that the server can be queried successfully
angular.module('neighborhoodApp')
.controller('FlatListCtrl', function ($routeParams, Flat) {
this.flat = Flat.get({
bid: $routeParams.bid,
id: $routeParams.rid
});
});
app.config(function ($routeProvider) {
$routeProvider
.when('/areas', {
templateUrl: 'views/area/list.html',
controller: 'AreaListCtrl',
controllerAs: 'list'
})
.when('/areas/:aid', {
templateUrl: 'views/area/show.html',
controller: 'AreaShowCtrl',
controllerAs: 'show'
})
.when('/areas/:aid/buildings', {
templateUrl: 'views/building/list.html',
controller: 'BuildingListCtrl',
controllerAs: 'list'
})
.when('/areas/:aid/buildings/:bid', {
templateUrl: 'views/building/show.html',
controller: 'BuildingShowCtrl',
controllerAs: 'show'
})
.when('/areas/:aid/buildings/:bid/flats', {
templateUrl: 'views/flat/list.html',
controller: 'FlatShowCtrl',
controllerAs: 'list'
})
.when('/areas/:aid/buildings/:bid/flats/:fid', {
templateUrl: 'views/flat/show.html',
controller: 'FlatListCtrl',
controllerAs: 'show'
})
.otherwise({
redirectTo: '/areas'
});
});