I have initialized my app following these two guides:
My setup looks something like this:
app.js
function init() {
console.log('running global init()');
window.initgapi();
}
var app = angular.module('app', []);
// Main Controller
app.controller('MainCtrl', ['$scope', '$window', 'cloudendpoints', function($scope, $window, cloudendpoints) {
// this is called once eventapi is loaded
var postInit = function() {
$scope.backend_ready = true;
$scope.fetchContent();
};
$window.initgapi = function() {
cloudendpoints.init(postInit);
};
$scope.fetchContent = function() {
gapi.client.cloudendpoints
.getContent()
.execute(function(resp) {
// do something with response
});
};
}]);
The cloudendpoints service is in its own file, cloudendpoints.js
:
// for loading endpoints service
app.factory('cloudendpoints', [function cloudendpoints() {
var init = function(postInit) {
var restUrl = '//' + window.location.host + '/_ah/api';
gapi.client.load('cloudendpoints', 'v1', postInit, restUrl);
};
return { init: init };
}]);
Lastly, our scripts are loaded in this order:
<script src="angular.min.js"></script>
<script src="app.js"></script>
<script src="controllers/mainCtrl.js"></script>
<script src="services/cloudendpoints.js"></script>
<script src="https://apis.google.com/js/client.js?onload=init"></script>
The Challenge
This works well so far, because we are only using a single controller (MainCtrl
). This is what happens in our code:
- The gapi client loads, then calls
init()
, which callswindow.loadCloudEndpoints()
cloudendpoints.init(postInit)
loads the cloudendpoints endpoint service, which then calls thepostInit()
callback. We can then make calls to the endpoints API from within thepostInit()
.
The challenge arises when we want to create another controller to handle another view of our app. Let's say we create a ContentPageCtrl
controller — do we then need to once again init our endpoint service? How can we make the endpoint service available to all controllers without having to repeat ourselves?
My Hacky Solution
In order to get around this, I $watch
the the backend_ready
so that I may only start making gapi calls after the endpoints api has loaded:
app.controller('ContentPageCtrl', ['$scope', function($scope) {
/**
* Make sure that the backend is ready before
* running any gapi.client.cloudendpoints calls
**/
$scope.$watch('backend_ready', function() {
if ($scope.backend_ready === true) {
gapi.client.cloudendpoints
.loadContent()
.execute(function(resp) {
// put content in DOM
});
}
});
}]);
This means I would need to $watch
the backend_ready
variable in every controller in which I need to make endpoint calls. My approach feels pretty dirty, and has problems scaling.
What is the better approach to this?