$rootScope.$broadcast is failing when fallback language is set - javascript

Implementing localization in angular app.
In app.js, written below code to support fallback language , if required .json files not present in the specific {{de-DE}}\ folder. (Taken german for example)
function configure($routeProvider, $locationProvider, $translateProvider, $httpProvider, $compileProvider) {
$routeProvider
.when('/instructions', {
templateUrl: "app/instructions/Instructions.html",
resolve: {
translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) {
$translatePartialLoader.addPart('instructions');
$translatePartialLoader.addPart('common');
//$translatePartialLoader.addPart('instructions').then(function (data) {
//console.log(data);
//});
//$translatePartialLoader.addPart('common').then(function (data) {
// console.log(data);
//});
$translateProvider.fallbackLanguage("en-US");
return $translate.refresh();
}]
}
})
.otherwise(
{
redirectTo: redirectTo
});
$httpProvider.useApplyAsync(true);
//$locationProvider.html5Mode(true);
$translateProvider.preferredLanguage($("#CultureCode").val());
$translateProvider.fallbackLanguage('en-US');
}
After changing my browser setting to german (google chrome). Files were not found, so it had to fallback. With the above code, my fallback language was english. So app downloaded .json files from {{en-US}}\folder.
But the actual problem is.
Once all the code excecutes , in one place i have written.
$rootScope.$broadcast("SHIFT_CHANGED");
And subscribing for the event like below.
$scope.$on("SHIFT_CHANGED", function() {
loadInstructions();
});
Here load instructions in my main method. Which is not getting executed because. Shift_changed events is not getting fired.
For testing purpose as soon as i paste those .json files in german folder. App starts working. But am trying to implement fallback.
I tried few code which is commented for refrence above. addpart trying to resolve for promise.
But none of them worked.
Am i missing some thing. And no error in console.
clueless to figure out.Any ideas to troubleshoot further / Is really some code is missing.
Please help.
Thanks in Advance

Related

ocLazyLoad and angular.bootstrap

I want to add a ocLazyLoad in my mean-stack website. Here is the code:
.state('kpi', {
url:'/kpi',
templateUrl: '/htmls/kpi.html',
resolve: {
loadMyCtrl: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load('/javascripts/kpi-controller.js').then(function () {
console.log("done");
}, function (e) {
console.log("error")
})
}]
}}
Loading the kpi page returns
bootstrapped
kpi-controller inside
done
Error: [ng:areq] http://errors.angularjs.org/1.5.8/ng/areq?p0=KpiCtrl&p1=not%20aNaNunction%2C%20got%20undefined
where the error is about Error: ng:areq Bad Argument Argument 'KpiCtrl' is not a.
KpiCtrl is defined in kpi-controller.js, and printing kpi-controller inside in the console shows the file has been indeed loaded. But why KpiCtrl is still not recognized?
One thing special about my code is, in the beginning of the program, I have
jQuery(document).ready(function () {
angular.bootstrap(document, ['myweb'])
console.log("bootstrapped");
})
app = angular.module('myweb', ['ui.router', 'oc.lazyLoad']);
I did not understand angular.bootstrap well, but it seems that the new loaded KpiCtrl should be bootstrapped to be recognized. I tried to add angular.bootstrap(document, ['myweb']) inside ocLazyLoad, but it showed App already bootstrapped with this element 'document'.
Does anyone know how to solve this?

angular.js Routing doesn't work on the server

I'm using ngRoute in my site, it work well on my computer (local) but on the server routing doesn't work. On my computer all my files are html, on the server i rename them as php. How can i fix it?
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider, $compileProvider) {
$routeProvider
.when("/", {
templateUrl : "pages/main.php",
controller: 'oneCtrl'
})
.when("/about", {
templateUrl : "pages/about.php"
})
.when("/news", {
templateUrl : "pages/news.php"
})
});
Based on the error messages you're getting (as you said in the comments), the Angular library is not being loaded. Double-check the URL. Also in the browser dev tools, check the Network tab and see what error it shows. Probably a 404 not found.
After checking your website and the line where you said the error was occurring (line 156 of route.js), change your code to this:
$('.counter-one span').eq(0).html(value1 + ' ');
$('.counter-two span').eq(0).html(value2 + ' ');
You did a search/replace for "html" to "php" but that also replaced the jQuery html() command. Just fix these two lines and you should be good.

How to check if minification went wrong?

I have a resolve in my code which works perfectly fine locally and all tests pass as well. However, it seems that the minified code causes some problems here.
When I stage the code and then run it locally it causes the same issues as the minified code. The resolve block does not do its job anymore.
Is there a way to compare the minified code with the actual code to find differences?
.state('index', {
url: '/',
resolve: {
trans: ['resolveService', function(resolveService) {
resolveService.languageResolve('main', {});
}]
},
controller: 'IndexCtrl'
})
.state('main', {
url: '/{language:[a-z]{2}}',
templateUrl: 'app/main/main.html',
controller: 'MainCtrl',
controllerAs: 'mainCtrl',
resolve: {
trans: ['resolveService', '$stateParams', function(resolveService, $stateParams) {
return resolveService.translateResolve($stateParams);
}],
redirect: ['resolveService', function(resolveService) {
return resolveService.resolveRedirect();
}]
}
})
.state('main.results', {
url: '/results/{route:nonURIEncoded}',
templateUrl: 'app/results/results.wrapper.html',
controller: 'ResultsCtrl',
resolve: {
urlParsed: ['urlParser','$stateParams','$state',function(urlParser,$stateParams,$state){
return urlParser.parse($stateParams.route).then(function(){ return true },function(err){
$state.go('main',{
language: $stateParams.language
});
});
}]
},
controllerAs: 'rc'
})
If you are experiencing a different behavior comparing the original and minified code, I'm pretty sure that something went wrong at the minification process and the result is incomplete or wrongly parsed. You should check your browser console and your minifier log for errors.
Also, as already pointed in comments (1, 2), you can pretty print the minified code to manually check where is the difference.
In Chrome:
Pretty Print JavaScript
The DevTools support prettifying of minified JavaScript to a more
readable form. To pretty print:
Go to the Sources panel and selected your desired script from the scripts list.
Next, press the "Pretty print" button (marked with curly braces) from the bottom of the DevTools window.
Your code should now be prettified!
Before
After

AngularJS Error: Unknown provider: aProvider <- a

OK I'm officially bald now, after having been streching my hair out with this infamous problem: The minfied AngularJS app just doesn't work, with this error thown out:
Error: [$injector:unpr] Unknown provider: aProvider <- a
http://errors.angularjs.org/1.2.6/$injector/unpr?p0=aProvider%20%3C-%20a
at http://localhost/my-app/dist/scripts/1bde0e2e.vendor.js:4:11492
at http://localhost/my-app/dist/scripts/1bde0e2e.vendor.js:4:26946
at Object.c [as get] (http://localhost/my-app/dist/scripts/1bde0e2e.vendor.js:4:26250)
at http://localhost/my-app/dist/scripts/1bde0e2e.vendor.js:4:27041
at c (http://localhost/my-app/dist/scripts/1bde0e2e.vendor.js:4:26250)
at Object.d [as invoke] (http://localhost/my-app/dist/scripts/1bde0e2e.vendor.js:4:26496)
at http://localhost/my-app/dist/scripts/1bde0e2e.vendor.js:9:910
at Object.f [as forEach] (http://localhost/my-app/dist/scripts/1bde0e2e.vendor.js:4:11927)
at http://localhost/my-app/dist/scripts/1bde0e2e.vendor.js:9:856
at j (http://localhost/my-app/dist/scripts/1bde0e2e.vendor.js:5:27235)
Lots of other people had this problem as well, but looks like it could be fixed by declaring dependencies as an array instead of bare function parameters, like this:
angular.module('my-app').controller('LoginCtrl', [ '$scope', 'HttpService', function($scope, HttpService) { ... }]);
instead of this:
angular.module('my-app').controller('LoginCtrl', function($scope, HttpService) { ... });
But it doesn't work in my case. I checked all of my scripts (coffee and generated javascripts as well), they all use the proper array-style declaration.
The problem doesn't come from extra packages apparently. I tried moving all extra package references out of <!-- bower:js --> block (so that they are not minified by grunt), yet the problem still remains. Which means, it's my code to blame... But then again, I've tried the (seems to be) only fix available, to no avail.
Any hint, even on how to properly debug this?
Thanks in advance!
Finally I've found the problem. And yes, it's a DI bug which I missed.
To all who may be suffering from the same headache: array-format declaration must be done in $routeProvider's resolve options as well. In my case (CoffeeScript ahead):
app.config (['$routeProvider', ($routeProvider) ->
$routeProvider
.when '/',
templateUrl: 'views/main.html'
controller: 'MainCtrl'
resolve:
groups: ['GroupService', (GroupService) -> # I MISSED THIS
return GroupService.getAll()
]
entries: ['EntryService', (EntryService) -> # AND THIS
return EntryService.getAll()
]
# ...
])
Hope this helps!
This behaviour could come if you use implicit injection, instead of explicit declaring your dependencies. In my experience I faced this kind of problem with particular kind of Angular.js services that return instantiable class (for example to create abstract controller Classes or some other particular cases).
For example: AbstractBaseControllerClass
During minification I had the same problem. I solved using internal declaration of dependency injection.
Hope this helps
For the ones that doesn't like CoffeeScript.
I just took some of my code and put it in.
$stateProvider
.state('screen', {
url: '/user/',
templateUrl: 'user.html',
controller: 'UserController',
controllerAs: 'user',
location: "User",
resolve: ['$q', 'UserService', '$state', '$timeout', authenticateUser
]
})
function authenticateUser($q, UserService, $state, $timeout) {
UserService.getLoginStatus().then(function () {
if (UserService.user) {
console.log("is user");
return $q.when();
} else {
console.log("not user");
$timeout(function () {
// This code runs after the authentication promise has been rejected.
// Go to the log-in page
$state.go('login')
});
return $q.reject()
}
});
}

RequireJS plugin: load timeouts experienced when using plugin

Using RequireJS I'm building an app which make extensive use of widgets. For each widget I have at least 3 separate files:
request.js containing code for setting up request/response handlers to request a widget in another part of my application
controller.js containing handling between model and view
view.js containing handling between user and controller
Module definition in request.js:
define(['common/view/widget/entity/term/list/table/controller'],
function(WidgetController) { ... });
Module definition in controller.js:
define(['common/view/widget/entity/term/list/table/view'],
function(WidgetView) { ... });
Module definition of view.js is:
define(['module','require'],function(module,require) {
'use strict';
var WidgetView = <constructor definition>;
return WidgetView;
});
I have lots of these little situations as above in the case of widgets I have developed. What I dislike is using the full path every time when a module is requiring another module and both are located in the same folder. I'd like to simply specify as follows (assuming we have a RequireJS plugin which solves this for us):
define(['currentfolder!controller'],
function(WidgetController) { ... });
For this, I have written a small plugin, as I couldn't find it on the web:
define({
load: function (name, parentRequire, onload, config) {
var path = parentRequire.toUrl('.').substring(config.baseUrl.length) + '/' + name;
parentRequire([path], function (value) {
onload(value);
});
}
});
As you might notice, in its basic form it looks like the example of the RequireJS plugins documentation.
Now in some cases, the above works fine (e.g. from the request.js to the controller.js), but in other cases a load timeout occurs (from controller.js to view.js). When I look at the paths which are generated, all are proper RequireJS paths. Looking at the load timeouts, the following is logged:
Timestamp: 13-09-13 17:27:10
Error: Error: Load timeout for modules: currentfolder!view_unnormalized2,currentfolder!view
http://requirejs.org/docs/errors.html#timeout
Source File: http://localhost/app/vendor/requirejs/require.js?msv15z
Line: 159
The above log was from a test I did with only loading the view.js from controller.js using currentfolder!view in the list of modules in the define statement. Since I only requested currentfolder!view once, I'm confused as to why I both see currentfolder!view_unnormalized2 and currentfolder!view in the message.
Any idea as to why this might be happening?
My answer may not answer your primary questions, but it will help you achieve what you're trying to do with your plugin.
In fact, Require.js support relative paths for requiring modules when using CommonJS style. Like so:
define(function( require, exports, module ) {
var relativeModule = require("./subfolder/module");
module.exports = function() {
console.log( relativeModule );
};
});

Categories