P
P
Pavel2016-01-20 00:31:01
JavaScript
Pavel, 2016-01-20 00:31:01

What is the best way to check user rights in js?

DISCLAIMER. We have a one-page js app, unfortunately written without angular and backbone. The project was not started by us, but there was no time to write from scratch.

Essence of the question:
In js, a function is called with an ajax request for user rights. There comes an array with 0 and 1, and what they are responsible for. Depending on this, you need to change the UI.

Since the main interface initializer function (the lodash template engine used) starts right after document.ready, what's the best way to organize the test conditions? After all, we cannot know what will happen first document.ready or ajax-request for access data.

Now there is a solution:

var access = {}
function getAccess() {
   $.get('url', function(data) {
      access = data;
      start();
   }
}
getAccess(); // вызываем проверку до document.ready();
function start() {
   $(function(){
      if (access.read) {
            // генерится шаблон
      } else {
            // генерится шаблон "В доступе отказано"
      }
   }
}


How to make this code beautiful and successful? Why is such a decision bad and bad?

UPD.
After thinking a little, I decided to use the following structure
function permissionsRecieved() {
   if (access.read || access.readAll) {
      // генерим шаблончик
   }    
}
access = {
    getPermissions : function() {
        // get-запрос, по .done - вызываем access.ready
        $.get('бла-бла', function(data) { 
              Object.assign(access, data) // подгрузили всякие read/write и добавили к access
              access.ready()
        }, 'json')
    },
  ready : function() {
                // вот здесь пришедшая в голову идея отказаться от $.ready и всего такого
    document.onreadystatechange = function () {
      if (document.readyState == 'complete') {
        return permissionsRecieved();
      }
    }
  }
}


UPD 3
Having tested, I realized that it is impossible to do this by "complete", due to the possible presence of large css and pictures on the page. And "interactive" is not always called on document.onreadychange inside ready, since the ajax request was interactive later.
ready : function() {
    console.info('Access ready. Current app ('+access.moduleName+') may be initiated');
    if ((document.readyState == 'interactive') || (document.readyState == 'complete')) {
      startApp();  // бывш. permissionRecieved() - начинаем генерить шаблончики, сперва проверив права
    } 
    document.onreadystatechange = function () {
      console.info(document.readyState); // смотрим, когда выходит 'complete', а может быть, и отловим 'interactive', когда ajax выполнится ДО загрузки и обработки дом-дерева
    }
  }

Answer the question

In order to leave comments, you need to log in

2 answer(s)
K
Konstantin Gromov, 2016-01-20
@Carduelis

$(document).ready(func) internally uses $.Deferred, that is, even if the DOM has already loaded, when this construct or its shortened version is called, the passed function will still be executed. Based on this, the code in your first version works reliably and without delays, you just need to make it concise:

var permissionsAndDOM = $.Deferred();

$.get("url", function(access) {
  $(function() {
    permissionsAndDOM.resolve(access);
  });
});

permissionsAndDOM.done(function(access) {
  if (access.read) {

  } else {

  }
});

If you don't understand what's going on here, read about Promise (ES6), $.Deferred (jQuery analogue of Promise) and it doesn't hurt to know the Pub-Sub pattern (in JavaScript it's usually implemented through the on, off, trigger functions). These are all the basic tools for comfortable work with asynchrony.

S
sim3x, 2016-01-20
@sim3x

Conceptually - you make a wrapper over the standard $.ajax, where you check the rights inside.
You cache the request for rights for 5-10 minutes

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question