2017-03-21 1 views
-1

J'ai une application AngularJS 1.6.3 et je rencontre un problème avec $q.all() ne résolvant pas correctement. Il semble que la fonction resolve dans ma configuration (sessionService.initializeApp()) ne soit même pas appelée du tout.

Les instructions console.log() ne sont pas en cours d'exécution et les demandes réseau ne sont pas effectuées. Cependant, si je change sessionService.initializeApp() pour être simplement une variable au lieu d'un appel de fonction avec un retour (par exemple var initializeApp = return $q.all(...)), et appelez simplement sessionService.initializeApp dans le resolve, les demandes de réseau sont faites, mais les instructions console.log() ne s'exécutent pas, et le contrôleur fait ne pas instancier. J'ai l'impression de renvoyer correctement les promesses, mais il est évident que quelque chose ne va pas puisque la résolution n'est pas vraiment résolue. Des idées ici?

app.config.js

//more code above... 
.when('/dashboard', { 
    slug: 'dashboard', 
    templateUrl: 'app/dashboard/dashboard.html', 
    controller: 'DashboardController', 
    options: { 
     title: 'Dashboard' 
    }, 
    resolve: { 
     appReady: function(sessionService) { 
      console.log('resolving...'); 
      return sessionService.initializeApp(); 
     } 
    } 
}) 
//more code below... 

session.service.js

//more code above... 
var state = { 
    appReady: false, 
    loading: false, 
    data: {} 
}; 

var service = { 
    initializeApp: initializeApp, 
    getData: getData, 
    setData: setData 
}; 

function initializeApp() { 
    return $q.all({ 
     user: ajaxService.get('SupplierService.svc/me', {}), 
     states: ajaxService.get('SupplierService.svc/states', {}), 
     utilityTypes: ajaxService.get('SupplierService.svc/utilities/types', {}), 
     roles: ajaxService.get('SupplierService.svc/contacts/types', {}) 
    }).then(function(response) { 
     setData('user', response.user['data']); 
     setData('states', response.states['data']); 
     setData('utilityTypes', response.utilityTypes['data']); 
     setData('roles', response.roles['data']); 
    }).catch(function(e) { 
     console.log(e); 
    }).finally(function() { 
     state.appReady = true; 
    }); 
} 

function getData(key) { 
    if (key) { 
     return state.data[key]; 
    } else { 
     return state.data; 
    } 
} 

function setData(key, val) { 
    state.data[key] = val; 
} 

return service; 
//more code below... 

dashboard.controller.js

//more code above... 
function DashboardController($q, ajaxService, sessionService) { 
    console.log('dashboard...'); 
}); 
//more code below... 
+1

Ressemble votre fonction initializeApp manque une accolade fermante :) –

+0

@AJFunk - Whoops! Mauvaise copie/coller sur ma fin. En fait, il n'y a pas d'accolade de fermeture manquante dans le code complet ... J'ai édité ma question. –

+1

Qu'est-ce que setData? Il n'est probablement pas appelé parce que vous n'injectez pas appReady dans le contrôleur. – estus

Répondre

0

attraper la promesse du contrôleur au lieu du service. dans le service juste retourner le $q.all

//more code above... 
var service = { 
    initializeApp: initializeApp 
}; 

function initializeApp() { 
    return $q.all({ 
     user: ajaxService.get('SupplierService.svc/me', {}), 
     states: ajaxService.get('SupplierService.svc/states', {}), 
     utilityTypes: ajaxService.get('SupplierService.svc/utilities/types', {}), 
     roles: ajaxService.get('SupplierService.svc/contacts/types', {}) 
    }) 

} 
return service; 

attraper la promesse dans le contrôleur

function DashboardController($q, ajaxService, sessionService,setData) { 
    sessionService..then(function(response) { 
     setData('user', response.user['data']); 
     setData('states', response.states['data']); 
     setData('utilityTypes', response.utilityTypes['data']); 
     setData('roles', response.roles['data']); 
    }).catch(function(e) { 
     console.log(e); 
    }).finally(function() { 
     state.appReady = true; 
    }); 
}); 
+0

Cela fonctionnera, mais je veux seulement lancer initializeApp() une fois lorsque l'application est chargée. Sinon, il fera toutes ces demandes chaque fois que l'utilisateur change de route/page. –

+0

mais chaque fois que vous appelez 'sessionService' du contrôleur, il sera exécuté –

+0

Cela ne fonctionnera pas à cause du fonctionnement des résolveurs. Si un résolveur refuse, l'itinéraire ne sera pas activé. Et injecté 'sessionService' est une valeur résolue d'une promesse, pas une promesse elle-même. – estus

0

Pour l'instant, j'ai renoncé à l'aide resolve et simplement modifié pour vérifier sessionService.initializeApp() si l'application est prête, et si c'est le cas, renvoyez une promesse résolue immédiatement afin que je n'ai pas besoin de récupérer les ressources du serveur.

function initializeApp() { 
    if (isAppReady()) { 
     return $q.when('appReady'); 
    } 

    return $q.all({ 
     user: ajaxService.get('SupplierService.svc/me', {}), 
     states: ajaxService.get('SupplierService.svc/states', {}), 
     utilityTypes: ajaxService.get('SupplierService.svc/utilities/types', {}), 
     roles: ajaxService.get('SupplierService.svc/contacts/types', {}) 
    }).then(function(response) { 
     setData('user', response.user['data']); 
     setData('states', response.states['data']); 
     setData('utilityTypes', response.utilityTypes['data']); 
     setData('roles', response.roles['data']); 
    }).catch(function(e) { 
     console.log(e); 
    }).finally(function() { 
     setAppReady(true); 
    }); 
} 

Et puis dans mes contrôleurs, je fais juste:

sessionService.initializeApp().then(function() { 
    //do stuff 
});