MediCoder Aide

Blogues » MediCoder » Refactoring javascript ligne par ligne
Par mytto20892 points 

Refactoring javascript ligne par ligne

Voici un anodin fragment javascript qui ne parait pas affreux à prime abord. Et pourtant, on peut y voir un code à moderniser. Explications.

function submitImeds(oForm){
  submitFormAjax(oForm, 'systemMsg', { onComplete : function() { reloadUserImeds(oForm.user_id.value, oForm.tag.value, oForm.type.value) } });
}
 
function reloadUserImeds(user_id, tag, type){
  var url = new Url;
  url.setModuleAction("dPImeds", "httpreq_vw_id_imeds");
  url.addParam("user_id", user_id);
  url.addParam("tag"    , tag);
  url.addParam("type"   , type);
  url.requestUpdate('user-imeds');
}

Regrouper dans un objet utilitaire

On voit bien que les deux fonctions — presque — jusque dans leur noms, forment un tout homogène et indissociable autour de UserImeds, autant le formaliser par un objet qui fournira entre autre un namespace. On remarquera qu'il s'agit d'un couple onSubmit/reload ultra classique...

function submitImeds(...){
  ...
}
 
function reloadUserImeds(...){
  ...
}

Devient alors :

UserImeds = {
  onSubmit: function(...) {  
    ...
  },
 
  reload: function(...) {
    ...
  }
}

Passage de paramètres simplifié

On voir apparaitre un passage de paramètres étonnant: tous sont issus directement du formulaire.

reloadUserImeds(oForm.object_id.value, oForm.tag.value, oForm.type.value)

Pourquoi ne pas tout simplement passer le formulaire ? Sans compter que si le fomulaire change de contenu, on voudra très probablement adapter son usage dans la fonction reload().

UserImeds.reload(form)

onSubmit et son callback

Voici une bien lourde facon d'utiliser l'ancien submitFormAjax(), certes cette fonction aurait du être supprimée depuis longtemps pour forcer la migration vers son remplaçant submitFormAjax().

function submitImeds(oForm){
  submitFormAjax(oForm, 'systemMsg', { onComplete : function() { reloadUserImeds(oForm.object_id.value, oForm.tag.value, oForm.type.value) } });
}

On notera :

  • la simplification syntaxique de oForm qui devient form car on ne souhaite pas faire semblant de typer du javascript pour au final n'apporter qu'une très maigre information
  • la disparition du paramètre 'systemMsg' car on souhaite que tous les formulaires soumis en ajax le soient vers la messagerie système.
  • la simplification du fait que truc est un raccourci — ouf! — pour l'indigeste et quasi systématique { onComplete: truc() } dans les fonctions ajax, raccourci déjà abordé précédemment
  • la simplification par curry qui instancie une fonction de sorte que truc.curry(bidule) soit un élégant équivalent de function() { truc(bidule) }

onSubmit: function(form) {  
  return onSubmitFormAjax(form, UserImeds.reload.curry(form));
}

Meilleur usage de URL

Enfin on pourra simplier légèrement la forge de la requête par -+URL+.

function reloadUserImeds(user_id, tag, type){
  var url = new Url;
  url.setModuleAction("dPImeds", "httpreq_vw_id_imeds");
  url.addParam("user_id", user_id);
  url.addParam("tag"    , tag);
  url.addParam("type"   , type);
  url.requestUpdate('user-imeds');
}

Notamment grace à :

  • addElement qui termine de justifier l'intérêt du passage en paramètre du formulaire seul
  • la construction qui inclue le quasi systématique setModuleAction depuis fort longtemps

reload: function(form) {
  var url = new Url('Imeds', 'httpreq_vw_id_imeds');
  url.addElement(form.user_id);
  url.addElement(form.tag    );
  url.addElement(form.type   );
  url.requestUpdate('user-imeds');
}

Au total

Nettement plus propre :

Imeds = {
  onSubmit: function(form) {  
    onSubmitFormAjax(form, UserImeds.reload.curry(form));
  },
 
  reload: function(form) {
    var url = new Url('Imeds', 'httpreq_vw_id_imeds');
    url.addElement(form.user_id);
    url.addElement(form.tag    );
    url.addElement(form.type   );
    url.requestUpdate('user-imeds');
  }
}

Sponsors privilégiés

Mediboard project