$ richiesta http prima che l’app AngularJS inizializzi?

Per determinare se la sessione di un utente è autenticata, ho bisogno di fare una richiesta $ http al server prima che venga caricato il primo percorso. Prima che ogni percorso venga caricato, un servizio di autenticazione controlla lo stato dell’utente e il livello di accesso richiesto dalla rotta e, se l’utente non è autenticato per quella rotta, reindirizza a una pagina di accesso. Tuttavia, quando l’app viene caricata per la prima volta, non ha alcuna conoscenza dell’utente, quindi anche se hanno una sessione autenticata, verrà sempre reindirizzato alla pagina di accesso. Quindi, per risolvere questo problema, sto cercando di fare una richiesta al server per lo stato degli utenti come parte dell’inizializzazione dell’app. Il problema è che ovviamente le chiamate $ http sono asincrone, quindi come dovrei interrompere l’esecuzione dell’applicazione fino al completamento della richiesta?

Sono molto nuovo per lo sviluppo di Angular e front-end in generale, quindi il mio problema potrebbe essere un fraintendimento di javascript piuttosto che di Angular.

Puoi farlo usando la resolve nel tuo routingProvider.

Questo ti permette di aspettare che alcune promesse vengano risolte prima che il controller venga avviato.

Citazione dai documenti:

resolve – {Object. =} – Una mappa opzionale di dipendenze che dovrebbe essere iniettata nel controller. Se una qualsiasi di queste dipendenze è promise, il router attenderà che tutte siano risolte o che uno venga rifiutato prima dell’istanza del controller. Se tutte le promesse vengono risolte correttamente, i valori delle promesse risolte vengono iniettati e viene generato l’evento $ routeChangeSuccess.

Semplice esempio

  app.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/', {templateUrl: 'home.html', controller: 'MyCtrl',resolve: { myVar: function($q,$http){ var deffered = $q.defer(); // make your http request here and resolve its promise $http.get('http://example.com/foobar') .then(function(result){ deffered.resolve(result); }) return deffered.promise; } }}). otherwise({redirectTo: '/'}); }]); 

myVar verrà quindi iniettato sul controller, contenente i dati di promise.

Evitare parametri DI aggiuntivi

Potresti anche evitare il parametro DI aggiuntivo restituendo un servizio che avresti dovuto iniettare comunque:

 app.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/', {templateUrl: 'home.html', controller: 'MyCtrl',resolve: { myService: function($q,$http,myService){ var deffered = $q.defer(); /* make your http request here * then, resolve the deffered's promise with your service. */ deffered.resolve(myService), return deffered.promise; } }}). otherwise({redirectTo: '/'}); }]); 

Ovviamente, dovresti memorizzare il risultato della tua richiesta ovunque in un servizio condiviso quando fai cose del genere.


Dai un’occhiata a Angular Docs / routeProvider

Ho imparato la maggior parte di quella roba da quel ragazzo su egghead.io

Incapsula tutte le tue risorse con un sessionCreator e restituisci una promise. Dopo la resolve quindi, al controller in modo da poterlo mantenere libero da un codice promise specifico.

 app.factory('sessionCreator', ['$http', '$q', 'urlApi', function ($http, $q, urlApi) { var deferred = $q.defer(); $http.get(urlApi + '/startPoint').success(function(data) { // Do what you have to do for initialization. deferred.resolve(); }); return deferred.promise; } ]); app.factory('Product', ['$resource', 'urlApi', 'sessionCreator', function($resource, urlApi, sessionCreator) { // encapsulate all yours services with `sessionCreator` return sessionCreator.then(function() { return $resource(urlApi + '/products', {}, { query: {method:'GET', params:{}, isArray: true} }); }); } ]); app.config(['$routeProvider', function ($routeProvider) { var access = routingConfig.accessLevels; $routeProvider .when('/product', { templateUrl: 'views/products.html', controller: 'ProductCtrl', // resolve then in router configuration so you don't have to call `then()` inside your controllers resolve: { Product: ['Product', function(Product) { return Product; }] } }) .otherwise({ redirectTo: '/' }); }]);