Search code examples
javascriptangularjslaravel-5loadapplication-settings

AngularJS load data (settings) from server


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);
});

Solution

  • 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;});
    }