0

I use angular 1.5 on a project since 1 year. It work good until 2 days. ( I use the same file hierarchy since the begining. )

I cannot make a plunker because i have too many files (>100) but i can provide a zip with all the sources files.

What the problem is :

I put configuration variables into $rootScope and inject it into manies services/controller to get the configuration and use them ( for example path to my webserver or elasticsearch )

The problem i have now is the service are runned before variable has been added to $rootScope so i get undefined variables !

The console log:

> "loading router.js" (from router.js (ligne 2)) > "end router" (from router.js (ligne 353)) > ERROR : "$rootScope.elastic_host undefined" (from elasticsearch.js (ligne 4) ) > "loading rootscope" (from rootscope.js (ligne 3)) > "end rootscope" (rootscope.js (ligne 96)) 

So elasticsearch.js is runned before rootscope.js even if the file a loaded before in the script.

I try to change 'script' order or adding "defer" in 'script' but no change.

DETAILS :

My index.html with the scripts loading :

..... <script type='text/javascript' src="resources/vendors/jquery/jquery.min.js"></script> <script type='text/javascript' src="resources/vendors/bootstrap/bootstrap.min.js"></script> <script type='text/javascript' src="resources/vendors/angular/angular.min.js"></script> <script type='text/javascript' src='resources/vendors/angular/ng-onload.js'></script> <script type='text/javascript' src="js/shared/tools.js"></script> <script type='text/javascript' src="js/shared/countries.tools.js"></script> <script type='text/javascript' src="js/router.js"></script> <script type='text/javascript' src="js/rootscope.js"></script> <script type='text/javascript' src="js/directives/directives.js"></script> <script type='text/javascript' src="js/directives/directivesCarrousel.js"></script> <script type='text/javascript' src="js/filters/filters.js"></script> <script type='text/javascript' src="js/services/carrousel.js"></script> <script type='text/javascript' src="js/services/tumblr.js"></script> <script type='text/javascript' src="js/services/elasticsearch.js"></script> <script type='text/javascript' src="js/services/geographie.js"></script> <script type='text/javascript' src="js/services/services.js"></script> <script type='text/javascript' src="js/services/cas.js"></script> <script type='text/javascript' src="js/controllers/homeController.js"></script> 

router.js

'use strict'; console.log("loading router.js"); /* App Module */ // add the modules her, don't forget to load the js file in /index.html with <script source=""> var interfaceApp = angular.module('interfaceApp', [ 'ngRoute','oc.lazyLoad', 'ngOnload', 'ui.bootstrap', /*'ngMaterial',*/ 'ngMessages', 'filters','directives', 'elasticsearch', 'pascalprecht.translate', 'ngCookies', 'ngAnimate', 'ngDialog', 'angular-confirm', 'ui-notification', 'ngPapaParse','uuid4','angular-momentjs' ] ); /** * routage, permet d'associer une url à un controller et vue, possible de mettre des parametres dans les urls */ angular.module('interfaceApp').config(['$routeProvider', function ($routeProvider) { $routeProvider. when('/', { templateUrl: 'partials/home/home.html', controller: 'homeController', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({files: ['js/controllers/homeController.js']}); }] } }). when('/test', { templateUrl: 'partials/test/index.html', controller: 'testController', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({files: ['js/controllers/testController.js']}); }] } }). when('/users', { templateUrl: 'partials/users/index.html', controller: 'usersController', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({files: ['js/controllers/usersController.js']}); }] } }). when('/gestionusers', { templateUrl: 'partials/gestionusers/index.html', controller: 'gestionusersController', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({files: ['js/controllers/gestionusersController.js']}); }] } }). when('/user/:login?', { templateUrl: 'partials/user/index.html', controller: 'userController', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({files: ['js/controllers/userController.js']}); }] } }). when('/add/:domaine', { templateUrl: 'partials/add/add.html', controller: 'addController', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({ serie: true, files: ['resources/json/countries.geo.min.js','resources/json/stratigraphie.js','resources/vendors/leaflet/all.leaflet.min.js', 'resources/vendors/leaflet/all.leaflet.min.css', 'js/directives/directiveMiniMap.js' ,'js/controllers/addController.js'] }); }] } }). when('/edit/:domaine/:id', { templateUrl: 'partials/edit/edit.html', controller: 'editController', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({ serie: true, files: ['resources/json/countries.geo.min.js','resources/json/stratigraphie.js','resources/vendors/leaflet/all.leaflet.min.js', 'resources/vendors/leaflet/all.leaflet.min.css', 'js/directives/directiveMiniMap.js' , 'js/controllers/editController.js'] }); }] } }). when('/specimenpreview/:domaine/:id', { templateUrl: 'partials/specimenpreview/view.html', controller: 'specimenpreviewController', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({ serie: true, files: ['js/controllers/specimenpreviewController.js'] }); }] } }). when('/copy/:domaine/:id', { templateUrl: 'partials/copy/copy.html', controller: 'copyController', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({ serie: true, files: ['resources/json/countries.geo.min.js','resources/json/stratigraphie.js','resources/vendors/leaflet/all.leaflet.min.js', 'resources/vendors/leaflet/all.leaflet.min.css', 'js/directives/directiveMiniMap.js' , 'js/controllers/copyController.js'] }); }] } }). when('/demos', { templateUrl: 'partials/demos/index.html', controller: 'demosCtrl', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({files: ['js/controllers/demosController.js']}); }] } }). when('/apropos', { templateUrl: 'partials/apropos.html' }). when('/plansite', { templateUrl: 'partials/plansite.html' }). when('/feedback', { templateUrl: 'partials/feedback.html', controller: 'feedbackCtrl', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({files: ['js/controllers/feedbackController.js']}); }] } }). when('/editionlot/:domaine/:collectioncode', { templateUrl: 'partials/editionlot/index.html', controller: 'editionlotController', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({files: ['js/controllers/editionlotController.js']}); }] } }). when('/importlot/:domaine/:collectioncode', { templateUrl: 'partials/importlot/index.html', controller: 'importlotController', resolve: { lazy: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({files: ['js/controllers/importlotController.js']}); }] } }). otherwise({ redirectTo: '/' }); }]); /** * provider pour la traduction des textes **/ angular.module('interfaceApp').config(['$translateProvider', function($translateProvider) { // Translation $translateProvider.useStaticFilesLoader({ prefix: 'resources/i18n/traduction_', suffix: '.json' }); $translateProvider.preferredLanguage('fr'); $translateProvider.fallbackLanguage('fr'); $translateProvider.useLocalStorage(); }]); /** * safe scope $Apply * usage : * $rootScope.safeApply( $scope ); * or * $rootScope.safeApply(function() { $scope.XX = YY ; ... }); */ angular.module('interfaceApp').config([ '$provide', function($provide) { return $provide.decorator('$rootScope', [ '$delegate', function($delegate) { $delegate.safeApply = function(fn) { var phase = $delegate.$$phase; if (phase === "$apply" || phase === "$digest") { if (fn && typeof fn === 'function') { fn(); } } else { $delegate.$apply(fn); } }; return $delegate; } ]); } ]); /** * Controller pour la traduction */ angular.module('interfaceApp').controller('TranslateCtrl', ['$rootScope','$scope', '$translate','$cookieStore', function ($rootScope, $scope, $translate,$cookieStore) { if( tools_defined($cookieStore.get('navigatorLanguage'))){ //recharge l'ancien choix de langue de l'utilisateur si il existe $scope.navigatorLanguage = $cookieStore.get('navigatorLanguage') ; }else { // sinon utilise langue du navigateur $scope.navigatorLanguage = navigator.language || navigator.userLanguage; } // cl('$scope.navigatorLanguage: '+$scope.navigatorLanguage); $scope.translatedLanguage = [ 'fr','en'] ; if( tools_defined($scope.navigatorLanguage) && tools_inArray( $scope.navigatorLanguage,$scope.translatedLanguage )){ }else{ // si la langue du navigateur n'est pas présente dans les traductions on prend l'anglais par défaut $scope.navigatorLanguage = 'en'; } $translate.use( $scope.navigatorLanguage ); $rootScope.navigatorLanguage = $scope.navigatorLanguage; $scope.changeLanguage = function (key) { cl("change langue"); $cookieStore.put('navigatorLanguage', key ); $scope.navigatorLanguage = key ; $rootScope.navigatorLanguage = key ; $translate.use(key); }; }]); /** * Controller pour la gestion de l'authentification unqiue * */ angular.module('interfaceApp').controller('AuthentificationCtrl', AuthentificationCtrl); AuthentificationCtrl.$inject = [ 'cas', '$location', '$rootScope', '$scope' ]; function AuthentificationCtrl(cas, $location, $rootScope, $scope) { $scope.tgc = null; $scope.st = null; var vm = this; var frame = document.getElementById("Menu").contentWindow; vm.frame = frame; $scope.init = function auth() { vm.dataLoading = true; $scope.tgc = getTGCCookiesValue(); if ($scope.tgc) { // on récupère le ST cas.GetServiceTicket($scope.tgc).then( function(response) { if (response.status == 200) { $scope.st = response.data; // on termine le processus de connexion validate(); } else { //FlashService.Error(response.message); vm.dataLoading = false; } }); } else { }; function validate() { cas.ValidateService($scope.st).then(function(response) { if (response.status == 200) { var data = response.data; var splitdata = data.split('\n'); var login = splitdata[1]; frame.postMessage({ type : "user", username : login, userProfile : "/user/"+login }, "https://www.recolenat.org/menu/"); } else { //FlashService.Error(response.message); vm.dataLoading = false; } }); } function getTGCCookiesValue() { var fname = getCookie('CASTGC'); return fname; } function getCookie(cname) { var name = cname + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1); if (c.indexOf(name) == 0) return c.substring(name.length, c.length); } return null; } } angular.module('interfaceApp').run(function ($rootScope, $location,cas,$timeout) { /** * executé avant chaque changement de route * modifie la variable globale filAriane utilisée dans chaque controller pour créer le fils d'ariane (pour revenir en arrière) */ //http://stackoverflow.com/questions/15175429/angularjs-getting-previous-route-path $rootScope.$on("$routeChangeStart", function (event, next, current) { $rootScope.filAriane.lasturl = $rootScope.filAriane.currenturl ; $rootScope.filAriane.currenturl = encodeURIComponent($location.$$path); $rootScope.isIndexPage = $location.$$path == "/"; }); $timeout( function(){ cas.getUser("natg94").then( function(res){ $rootScope.currentUser = res ; }); }, 1000); }); console.log("end router.js"); 

The rootscope.js

angular.module('interfaceApp').run(function ($rootScope) { console.log("loading rootscope"); // elasticsearch serveur host $rootScope.elastic_host = 'https://search.recolenat.org/' ; // adresse de l'interface de saisie $rootScope.saisie_host = 'https://saisie.recolenat.org/#/' ; // api, host for java web service $rootScope.api = 'http://localhost:8080/erecolenat/v1/' ; // elasticsearch index global $rootScope.elastic_global = "global"; .... /* safe scope apply to avoid "digest already in" * $rootScope.$safeApply(fctA()); * */ $rootScope.$safeApply = function () { var $scope, fn, arg, force = false, args = arguments; if (args.length === 1) { arg = args[0]; if (typeof arg === 'function') {fn = arg;} else { $scope = arg; } } else if (args.length > 0) { $scope = args[0]; fn = args[1];if (args.length === 3) {force = !!args[2]; } } $scope = $scope || this || $rootScope; if ($scope === window) { $scope = $rootScope; } fn = fn || function () {}; if (force || !($scope.$$phase || $scope.$root.$$phase)) {$scope.$apply ? $scope.$apply(fn) : $scope.apply(fn);} else { fn(); } }; console.log("end rootscope"); }); 

elasticsearch.js

// Create the es service from the esFactory angular.module('interfaceApp').service('elasticQuery', function ($rootScope,esFactory) { if(!tools_defined($rootScope.elastic_host)){ console.error("$rootScope.elastic_host undefined"); } return esFactory({ host: $rootScope.elastic_host}); }); 
6
  • Remove console.error("$rootScope.elastic_host undefined"); from elasticsearch.js Commented Mar 9, 2016 at 10:25
  • the problem still the same. elasticsearch.js is called before adding variable in $rootscope Commented Mar 9, 2016 at 10:27
  • You Got same Error Again?? Commented Mar 9, 2016 at 10:27
  • yes. removing the console.error() will not display the error but the $rootScope.elastic_host still undefined because elasticsearch.js is called before adding variable in $rootscope Commented Mar 9, 2016 at 10:29
  • Otherwise you can use $broadcast Event. Commented Mar 9, 2016 at 10:34

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.