Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Web App Best Practices

I'm having a hard time writing my question succinctly and clearly, so let me describe what I'm working with.

I'm building a web application that:

  • has it's own API hosted on a subdomain (https://api.example.com)
  • has the main application hosted on the tld (https://www.example.com)
  • the tld doesn't have any database access, but instead interacts with the API to work with data
  • the tld authenticates with the api through OAuth and stores the access token and access token secret in a session
    • when the session ends, the access token is no longer used, thus logging the user out

I have a route in the tld (let's call it /ajax for this question) that the javascript calls (GET, PUT, POST, OR DELETE) to make requests to the api. This way, nobody ever has to see the access token, access token secret, consumer key, or consumer secret.

The way I see it, the access token and access token secret are really the only things I need to store in a session since I can grab everything else using the API, but instead of making a call every single time for every piece of data I need, I think some things should persist, like aspects of the user's profile, layout preferences, etc.

What is the best way for me to accomplish this? Local storage? Cookies? Should I scrap this and just store it in sessions?

And if you have some time, what other best practices are there for building sites like this that I may not know of?

like image 350
Steve Avatar asked Feb 16 '12 16:02

Steve


People also ask

When dealing with strings in JavaScript it is considered best practice to?

When dealing with strings in JavaScript, it is considered best practice to... use 'single' quotes.

Is CoffeeScript like JavaScript?

One crucial difference between the two languages is that TypeScript is the superset of JavaScript while CoffeeScript is a language which is an enhanced version of JavaScript. Not just these two languages but there are other languages such as Dart, Kotlin, etc. which can be compiled into JavaScript.


1 Answers

You are on the right track I would say, but store your data in JavaScript primarily. And couple it with Local Storage when suitable.

When I build apps such as the one you are describing I usually take care to set up JavaScript representations of the data I receive via the API.

One such representation could look as follows below. Bear in mind that my example code below makes a couple of assumptions.

  1. It makes the assumption that you have an api object defined which takes care of API calls, and invokes a callback on completion.
  2. that the data returned by the API is JSON that simply can be assigned to a JavaScript variable,
  3. That the JSON returned is a list of objects, each with an "id" field.
  4. That you have some sort of event object, I usually build my own custom events that basically carry function objects as listeners and when fired go through the listeners and invoke the functions with or without a payload depending on the situation.

Data container example:

MYAPP.data.BaseContainer = function (api_url, loadedEvent) {
    var self = {

        // Array to store the data returned via the APIs 
        _data : [],

        // The API URL used to fetch data
        api_url : api_url,

        // Boolean flag to signify whether the _data variable has been populated
        is_loaded : false,

        // The even to fire once _data has been populated
        loadedEvent : loadedEvent,

        /**
         * Returns the state of the is_loaded variable
         */
        loaded : function () {
            return self.is_loaded;
        },

        /**
         * Takes an ID and returns any member of the _data array
         * that has that ID.
         * 
         * @param id : an String or integer representing the ID.
         * @returns {Object}
         */
        byId : function (id) {
            var toReturn = null;
            for (var i = 0, len = self._data.length; i < len; i++) {
                if (self._data[i].id == id) {
                    toReturn = self._data[i];
                    break;
                }
            }

            return toReturn; 
        },

        /**
         * Returns the entire _data array.
         */
        all : function () {
            return self._data;
        },

        /**
         * This simple callback just stores the json response in 
         * its entirety on the _data variable.
         */
        callback : function(data) {
            self._data = data;
            self.is_loaded = true;
            loadedEvent.fire(self._data);
        },

        /**
         * Calls the API, if no callback has been specified as a parameter
         * self.callback is used.
         */
        getFromAPI : function(callback) {
            if (typeof callback === 'undefined') {
                callback = self.callback;
            }

            api.get(self.api_url, callback);
        }
    };

    self.getFromAPI();

    return self;
};

With this blueprint I can now create specific data containers like this:

/**
 * Stores a list of "friends" gotten from the API.
 * This is basically an instance of the BaseContainer object defined above.
 */
MYAPP.data.Friends = (function () {
    var self = MYAPP.data.BaseContainer("API_URL_TO_FECTH_FRIENDS_LIST", FriendsLoadedEvent);

    return {
        byId : self.byId,
        all : self.all,
        loaded : self.loaded
    };
}());

As soon as this code is run, an API call is made, and the FriendsLoadedEvent will be fired when it is done. So, to put it bluntly, I use JavaScript to store my stuff usually. But if you want to throw LocalStorage into the mix that is easy too!

Just add local storage code to the BaseContainer object that first detects whether the client actually supports localstorage, and if so mirror the _data field in local storage. This is handy to keep often used data quickly available between sessions. Use the readily available JSON parsing tools to convert the data from JSON to LocalStorage "text"and back.

Just keep in mind that you cannot rely on LocalStorage as your primary data structure, you have no guarantee that the client supports it, and even when it does the upper bounds for how much data you can actually store is different between the browsers. So use it to store data that:

  • You want access to very often,
  • that you feel should just be there, immediately as soon as the user logs in,
  • and that does not change often enough to warrant refreshing API calls constantly.
like image 145
Jon Nylander Avatar answered Sep 30 '22 19:09

Jon Nylander