I've made a simple food-ordering application with Laravel 5. Now I'm trying seperate the front-end and back-end by using AngularJS. Angular grabs it's data from the back-end, which is a REST API based on Laravel (Lumen).
There are a few settings stored in the database which consist of a key-value pair. Think of settings like 'minimum-order-amount' and 'delivery-costs'. Normally I would simply call setting(key)
within my Laravel application:
/**
* Get the value for the given setting from the database.
*
* @param mixed $key
* @return mixed
*/
function setting($key)
{
static $settings;
if(is_null($settings)) {
$settings = Cache::rememberForever('settings', function() {
return array_pluck(App\Setting::all()->toArray(), 'value', 'key');
});
}
return (is_array($key)) ? array_only($settings, $key) : $settings[$key];
}
Notice the static functions which allows me to call the setting()
function multiple times per request, but only query the database once. How can I achieve this within my Angular application?
I could accomplish the same with something like this:
/**
* Retrieve the value of the given setting.
*/
function setting(key) {
$.get(apiUrl('api/setting'), function(data) use (key) {
return data.key;
});
}
...but this would lead to multiple requests (for the same set of data) from the database, multiple times per page load. Which is pretty inefficient.
Edit (final working example)
app.factory('Setting', ['$q', '$http', function($q, $http) {
var url = 'api/setting';
var promise = null;
function load() {
if ( ! promise) {
promise = $q.defer();
$http.get(apiUrl(url))
.success(function(data) {
promise.resolve(data);
})
.error(function(data) {
promise.reject(data);
});
}
return promise.promise;
}
return {
load: load
}
}]);
// Usage
Setting.load().then(function(result) {
console.log(result);
});
Use a service and if necessary use a cache system.
angular.factory('SettingsService', SettingsService);
function SettingsService($q, $http) {
var userUrl = ApiConfigurationService.userUrl;
var url = 'api/setting';
var promise = null;
function loadSettings() {
if (!promise) {
promise = $q.defer();
$http.get('url', function(res) {
settings = res.data;
promise.resolve(res.data);
}, function(res) {promise.reject(res)});
}
return promise.promise;
}
return {
loadSettings: loadSettings
}
}
Then in your controller/directive
angular.controller('MyController', MyController);
function MyController(SettingsService) {
var me = this;
SettingsService.loadSettings(function(res) {
me.settings = res;});
}