I have been developing this structure or pattern (I don't really know how to call it). It's my first time doing something like this, and I'm a bit worried about the future, if it becomes unmanageable.
I'm looking for some advice on what could improve or remove to prevent that the one that has to work with this does not end trying to kill me.
This pattern is made to prevent repeated code and centralize all requests of a functionality.
It consists of two parts, the first one is the 'Controller' and the other one its the 'Client'.
The first part is the 'controller' where there are all the available ajax requests and the functions used in the scope. Going into more detail, the Controller receives a request object that contains the parameters to identify which request will be executed and the callbacks for that request.
And the client is where you can define the events, requests, callblacks, and the template specific functions, like a normal JS file.
This is the 'Controller':
var FOF = FOF || {};//Namespace definition
FOF.Users = {//Init User inside the namespace
init: function(userRequest){//Main Function
var request = userRequest.request || ''; //Request name as string
var callbacks = userRequest.callbacks || {}; //Callbacks functions to run as ajax callbacks
var userId = userRequest.userId || 0; //User Id param
var event = userRequest.domainEvent || false; //Custom Event to be fired after the ajax request
var dependency = userRequest.dependency || false; //Dependency injection
var allowCache = userRequest.allowCache || false; //To allow load and store data from cache
console.log(userRequest);
if(allowCache){ //Cache variables
var requestCache = JSON.parse(localStorage.getItem(request));
var currentDate = ((new Date).getTime());
var cacheTimeHours = 1; //Cache Time in Hours
var timeToUpdate = hoursToSeconds(cacheTimeHours);
}
switch(request) { //Request Switch
case 'getUser':{//Get an user from a ajax request
if(allowCache && requestCache != null && ((currentDate - requestCache.cacheLastUpdateDate)/1000) < timeToUpdate ){
console.log('From Cache');
callbacks.run(requestCache)
}else{
console.log('From ApiCall')
FOF.Users.getUserData(callbacks,dependency,allowCache);
}
break;
}
default:{//Request Parameter empty or invalid
console.log('Param Request Empty or not valid');
}
}
},
getUserData : function(callbacks,dependency,cache){ User data function
dependency.ajax({
url: "Mocks/users.json",
data: {},
dataType: "json",
method: 'get',
success: function (data) {
if (!isObjectEmpty(callbacks)) { //Callbacks exec
callbacks.run(data);
}
if(event){//Event dispatch
document.dispatchEvent(new CustomEvent(event, {detail: {data}}));
}
if(cache){//Cache storage
storeInCache(data,'getUser'); //Es importante que se amacene el nombre de la cache con el mismo nombre de la request
}
},
error : function (data) {
if (!isObjectEmpty(callbacks)) {//Errors callbacks
callbacks.errors(data);
}
if(event){//Event dispatch
document.dispatchEvent(new CustomEvent(event, {detail: {data}}));
}
},
cache: false,
});
}
}
/**
* @description: Check if an object is empty by the ammount of keys
*/
function isObjectEmpty(obj) {
return Object.keys(obj).length === 0;
}
/**
* @description: transform hours to seconds
* @param : {Number} hours
*/
function hoursToSeconds(hours) {
var seconds = (hours * 60 * 60);
return seconds;
}
function storeInCache(data, cacheName){ //Store in cache function
data.cacheLastUpdateDate = ((new Date).getTime());
localStorage.setItem(cacheName, JSON.stringify(data));
}
And this is the client :
$(document).ready(function(){
//Callbacks definitions
var getUserCallbacks = {
run: function(data){//Success Callbacks
console.log(data);
},
errors: function(data) {//Error Callbacks
console.log(data);
},
serverError : function(data){//Server Error Callback
console.log('Error From Server, Ask to backend team');
},
}
var userRequest = { //request Object
dependency : jQuery, //jQuery as dependency to allow to make an ajax inside the namespace
request: 'getUser', //Request Name
userId : 1, //Param
callbacks :getUserCallbacks, //succes an error callbacks
allowCache: true, //Cache boolean
domainEvent: 'getUser' //Custom event Name
}
FOF.Users.init(userRequest); //Exec request
});