javascriptdurandaldurandal-2.0

Durandal: how to cache calls?


In my durandal app I need to know if the user is logged in different places. So currently i'm doing a call to get the user state in every views that needs it.

Is possible to do something like this:

//login.js

define(function(require) {
 var http = require('durandal/http')
 var isLogged;

 function getLogin() {
 if (isLogged != undefined) return isLogged
 return http.get('/api/login').then(function(data) {
  isLogged = data.logged
  return isLogged
  })
 }

 return {
  getLogin: getLogin
}

//view.js
define(function(require) {
 var login = require('login')
 function vm() {
  var self = this;
  self.isLogged;
  self.activate = function() {
   self.isLogged = login.getLogin()
  }
 }
 return vm
})

The above doesn't work because in the view activate method I need to return a promise. How can I achieve that?


Solution

  • You can use guardRouter function!

    This will be triggered in all navigation.

    // Shell main or other file that runs before any view!
    // Define the router guard function!
    
     require('plugin/router', 'Q', function(router, q){
    
         var cache = {};
    
         router.guardRoute = function(instance, instruction) {
             var key = instruction.fragment.toLowerCase();
    
             return cache[key] !== undefined ?
                 cache[key]:
                 q($.get(url,data)).then(_setCache, _fail);
    
    
             function _fail(/*jqhxr*/) {
                /* do something */
             }
    
             function _setCache(result) {
                 cache[key] = result;
                 return cache[key];
             }
         }
    
     });
    

    If you return true, the navigation will proceed! in case of string returned, durandal will navigate into it!

    The cache works as you define (check for javascript memoization)

    About durandal Auth chech this gitHub for inspiration.