I am having an error on this code. I don't know why I am using angularjs 1.7.x version
$(document).ready(function () {
$('#signupBtn-spinner').hide();
var app = angular.module('myApp', []);
$('#signupBtn').click(signup);
function signup() {
app.controller('signupController', ['$scope', '$http', function ($scope, $http) {
alert('hello')
}]);
}
})
I strongly recommend you to avoid to use jquery with Angular/js
If you want to implement signup/login logic, suggest you to use ui-router. Some example.
Also please read this great Josh David Miller's answer “Thinking in AngularJS” if I have a jQuery background
About your problem:
You get this error from ng-app.
Put var app = angular.module('myApp', []); out of $(document).ready
Angularjs is loaded and it does not see any module because it is still not ready.
var app = angular.module('myApp', []);
$(document).ready(function () {
$('#signupBtn-spinner').hide();
$('#signupBtn').click(signup);
function signup() {
app.controller('signupController', ['$scope', '$http', function ($scope, $http) {
alert('hello')
}]);
}
})
Related
I have a controller as shown below.
(function () {
"use strict";
var app = angular.module('Demo')
.controller('MainController', ['$rootScope', '$scope', '$location', 'curUser',MainController]);
function MainController($rootScope, $scope, $location, curUser) {
//some logic here
}());
I tried to include a third party module called ngIdle and the resultant code looks like below.
(function () {
"use strict";
var app = angular.module('Demo', ['ngIdle'])
.controller('MainController', ['$rootScope', '$scope', '$location', 'curUser','Idle', function ($rootScope, $scope, $location, curUser, Idle) {
}]).config(function (IdleProvider, KeepaliveProvider) {
// configure Idle settings
IdleProvider.idle(5); // in seconds
IdleProvider.timeout(5); // in seconds
KeepaliveProvider.interval(2); // in seconds
})
.run(function (Idle) {
// start watching when the app runs. also starts the Keepalive service by default.
Idle.watch();
});
}());
Now I get an error as Error: [$injector:unpr] Unknown provider: curUserProvider <- curUser <- MainController. Here's the curUser factory definition
(function () {
"use strict";
angular.module("services").factory("curUser", curUser)
function curUser() {}
}());
curUser is defined in the services module so it needs to be added as a dependency in your app. This would have been the case even before adding ngIdle.
var app = angular.module('Demo', ["ngIdle", "services"])
The factory function should also return something.
function curUser() {
return { username: 'fooBar'};
}
See working plunker.
So I know that I need to use [] to secure my code before minification. For example:
app.controller('mainController', ['$scope', function($scope) {
$scope.message = 'HOORAY!';
}]);
But how to do that when I am not using app as global variable, I've got
(function () {
'use strict';
angular
.module('app')
.controller('loginCtrl', Controller);
function Controller($scope, authService) {
var vm = $scope;
vm.login = function(login_field, password_field) {
var loginData = {
login: login_field,
password: password_field
};
authService.login(loginData);
};
}
})();
How to prevent it from problems during minification?
The same way:
.controller('loginCtrl', ['$scope', 'authService', Controller]);
I strongly advise you to use ng-annotate, which allows using the simple syntax, and transforms it into minifiable code for you. That will make your code simpler, easier to read, and avoid a whole lot of bugs.
When a controller or a service is a named function like in code above, it looks best when it's annotated with $inject (see John Papa style guide).
angular
.module('app')
.controller('loginCtrl', Controller);
Controller.$inject = ['$scope', 'authService'];
function Controller($scope, authService) {...}
Hoisting allows to place the annotation right above injectable function.
I believe it should be the same way:
(function () {
'use strict';
angular
.module('app')
.controller('loginCtrl', ['$scope', 'authService', function($scope, authService) {
$scope.login = function(login_field, password_field) {
var loginData = {
login: login_field,
password: password_field
};
authService.login(loginData);
};
}]);
})();
One way you may try grunt-ngmin before the minification that will searches and replace the minification with minify-friendly code. Go to this link you will see example https://github.com/btford/grunt-ngmin#example
Not really sure where I'm going wrong here. I'm trying to simply inject a service and use it in controller
app.js
var app = angular.module('myApp', [
'myApp.controllers.myCtrl',
'myApp.services.myService'
]);
js/controllers/myCtrl.js
var app = angular.module('myApp.controllers.myCtrl', []);
app.controller('homeController', function ($scope, MyService) {
...
});
js/services/myService.js
var app = angular.module('myApp.services.myService', []);
app.service("MyService", function ($http, $q) {
...
});
This results in the following error
Here you are trying to access myService service component of myApp.services.myService module in myApp.controllers.myCtrl module, without injecting the module will obviously going to get failed.
If you wanted to access the service in myApp.controllers.myCtrl module then you need to inject myApp.services.myService in the [](dependency array where you can all dependent module).
var app = angular.module('myApp.controllers.myCtrl', ['myApp.services.myService']);
By doing above line you do have all component(services) in myApp.controllers.myCtrl module.
js/controllers/myCtrl.js
var app = angular.module('myApp.controllers.myCtrl', ['myApp.services.myService']);
app.controller('homeController', function ($scope, MyService) {
...
});
Then not need to inject services in app.js again.
var app = angular.module('myApp', ['myApp.controllers.myCtrl']);
Just wondering if there's difference between:
angular.module('app', [])
.controller('myctrl', ['$scope', 'customService',
function($scope, customService) {
// use customService
}
]);
and using $injector
angular.module('app', [])
.controller('myctrl', ['$scope', '$injector',
function($scope, $injector) {
// get customService via injector and use it
$injector.get('customService');
}
]);
Sometimes I need to inject quite a few dependencies and my parameter list ends up to be lengthy. That's why I'm thinking the latter approach may be better for my scenario.
Does the difference affect testing or minification or any other reason?
You are on the right track. Look at John Papa's Style Guide. You will do the injection before the controller function.
/* recommended */
angular
.module('app')
.controller('Dashboard', Dashboard);
Dashboard.$inject = ['$location', '$routeParams', 'common', 'dataservice'];
function Dashboard($location, $routeParams, common, dataservice) {
}
Basically there is not much different, until you first encounter your circular dependency error while loading your module.
Simple Fiddle that demonstrates circular dependency.
Code (from fiddle):
angular.module('app', [])
.service('serviceA', function (serviceB) {
return {};
})
.service('serviceB', function (serviceA) {
return {};
})
.controller('myCtrl', function (serviceA, serviceB) {
});
Using $injector helps prevent that scenario because when you use it inside the Controller/Factory/Service/etc instead of injecting the first way, you are delaying the dependency and therefore solving the problem.
And a simple Fiddle that demonstrates how that problem is solved.
Code (from fiddle):
angular.module('app', [])
.service('serviceA', function (serviceB) {
return {
test: "it works!"
};
})
.service('serviceB', function ($injector) {
return {
test: function() {
var serviceA = $injector.get("serviceA");
return serviceA.test;
}
};
})
.controller('myCtrl', function ($scope, serviceA, serviceB) {
$scope.test = serviceB.test();
});
I'm testing Angular-translate with angular-traslate-partial-loader and it is not populating the page with the default translation on page load.
here is a plunkr of the problem recreated
app.controller('MainCtrl', ['$scope', '$translate', '$translatePartialLoader',
function($scope, $translate, $translatePartialLoader) {
$translatePartialLoader.addPart('test');
$translate.refresh();
$scope.dotranslate = function() {
$translate.refresh();
};
}
]);
http://plnkr.co/edit/Vts9CW4VoJsXoSdllFsq?p=preview
I added a refresh button to show that the $translate.refresh() works after page load.
What am i missing?
I've never used $translate so I'm not sure exactly what the problem is, but you may be changing a value too late in the digest cycle for the refresh to catch it.
You can use $scope.$evalAsync to fix this. See the angular documentation here: https://docs.angularjs.org/api/ng/type/$rootScope.Scope
Here is an example of your app.js with the change:
var app = angular.module('plunker', ['pascalprecht.translate']);
app.config(function run($translateProvider, $translatePartialLoaderProvider) {
$translateProvider.useLoader('$translatePartialLoader', {
urlTemplate: 'translation-{lang}-{part}.json'
});
$translateProvider.preferredLanguage('fr-FR');
});
app.controller('MainCtrl', ['$scope', '$translate', '$translatePartialLoader',
function($scope, $translate, $translatePartialLoader) {
$translatePartialLoader.addPart('test');
//I wrapped your refresh in the eval async function
$scope.$evalAsync(function() {
$translate.refresh();
});
$scope.dotranslate = function() {
$translate.refresh();
};
}
]);