I'm following a thinkster tutorial on angular and rails. The tutorials says to make the app like this...
angular.module('flapperNews', [])
with the controllers and factories like this...
.config([...
.controller([...
.factory([...
and so on. However it only works when I do this...
var flapperNews = angular.module('flapperNews', [])
with the controllers and factories like this...
flapperNews.config([...
flapperNews.controller([...
flapperNews.factory([...
Is there a short answer for this? Is the tut wrong or am I doing something wrong.
Here is the tut link
https://thinkster.io/angular-rails#introduction
I haven't started the rails part yet, just wanted to know why it breaks.
Here are the two codepens...
This one works as described above.
http://codepen.io/MrNagoo/pen/regKgM
This one fails and gives errors, although it's how i'm being directed to write the code...
http://codepen.io/MrNagoo/pen/regKEM
I would suggest looking at John Papa's style guide: https://github.com/johnpapa/angular-styleguide/tree/master/a1
You create your module as you said:
angular.module('flapperNews', [])
And you add a controller/factory/config/whatever like:
angular
.module('flapperNews')
.config(config)
function config() { ... }
Your problem is that you are using ; before doing the next .config this terminate the statement. You need to chain the components.
angular.module("app",[])
.config()
.controller()
.service();
here is the codepen with the working code
But you should definettly follow John Papa's style guide
Related
I can not get rid of a small issue affecting my app functionality to enable to call a phone number using skype, what I have so far is this:
HTML:
<a ng-href="skype:{{user.phone}}?call" class="btn btn-sm btn-success" type="button">{{user.phone}}</a>
ANGULAR
(function() {
angular.module('core').config(coreConfig);
coreConfig.$inject = ['$compileProvider'];
function coreConfig($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|skype):/);
}
})();
The result is always the same, when I hover the element to start a call the browser show this: unsafe:skype:012345678?call and do not allow me to call the number...
I added the config part browsing other questions related to similar issues but it doesn't solve my issue.
EDIT:
I'm using meanjs.org
EDIT 2:
Please do not copy/paste my question code as your answer... I know that it work on a normal Angular application. The problem is that I can not let it work using meanjs.org app. Thanks.
EDIT 3:
I just found that: if I use the skype link in the main root / or in a child root like: /list it work fine without adding the unsafe prefix. In a dynamic root like: /list/1234 it doesn't work anymore. I don't know if it could help.
The "bug" was caused by an old version of ngFileUpload that overwrite my configuration as reported here.
Upgrading the version of ngFileUpload solved my issue.
Thanks for your help.
You need to explicitly add URL protocols to Angular's whitelist using a regular expression. Only http, https, ftp and mailto are enabled by default. Angular will prefix a non-whitelisted URL with unsafe: when using a protocol such as chrome-extension:.
A good place to whitelist the chrome-extension: protocol would be in your module's config block:
var app = angular.module( 'myApp', [] )
.config( [
'$compileProvider',
function( $compileProvider )
{
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/);
// Angular before v1.2 uses $compileProvider.urlSanitizationWhitelist(...)
}
]);
The same procedure also applies when you need to use protocols such as file: and tel:.
Please see the AngularJS $compileProvider API documentation for more info.
I've made it work in following plunker
http://plnkr.co/edit/rIPFz9WhFjlRJ1ogCArP?p=preview
angular.module('plunker', [])
.config(function($compileProvider){
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|skype|mailto|tel|file):/)
})
.controller('MainCtrl', function($scope) {
$scope.href = 'skype:123456?call';
});
I am trying to learn the popular method of using controllerAs as opposed to binding everything to the $scope. Briefly documented here : http://www.johnpapa.net/do-you-like-your-angular-controllers-with-or-without-sugar/
I am going to provide a much simplified example of my code in order to understand how to properly code in this manner.
angular
.module('gc',['gc.login']);
angular
.module('gc.login',[]);
(function () {
'use strict';
angular
.module('gc.login')
.controller('gcLoginController', gcLoginController);
gcLoginController.$inject = [];
/* #ngInject */
function gcLoginController() {
var vm = this;
vm.blah = "blah";
activate();
////////////////
function activate() {
console.log("Hello World!");
}
}
})();
The code above was created using snippits from the author of the article, but when I try to bind to the variable "blah" in the html, it does not work. It doesn't output anything at all.
<body id="ng-app" ng-app="gc">
<div class="wrapper" ng-controller="gcLoginController as vm">
"{{vm.blah}}"
</div>
</body>
This simply outputs ""
Can anyone see what error was made in using this method?
Ah shoot it was a stupid mistake. Thank you to those who double checked my work in plunker. I was using a node.js server for this project along with the template engine "Swig". Apparently that was a mistake to combine Angular and Swig, because they both use {{ }} to bind variables, which is why my code (which as charlietfl pointed out is actually working) didn't seem to work. I will update the title of this post to help others who may have a similarly difficult to trace issue with Angular / Swig.
Update - can get around this problem : https://gist.github.com/angelochen960/4188293
I know it is not a good practice to use Angular services outside of angular but nevertheless it's very interesting for me, for example I have
.constant('APIprefix','/api')
how can I retrieve APIprefix value outside of angular scope? For instance from other js file which is not in angular scope.
You can access any service like this:
angular.element(document.documentElement).injector().get('APIprefix');
Note that you should pass to angular.element DOM node where you put ng-app. In the example above document.documentElement is HTML tag.
Demo: http://plnkr.co/edit/nf8zhDsl1PAnE5zDYYaG?p=preview
pixelbits example did not worked for me. I needed to do a small change to do it.
Writting constants
var app = angular.module('module',[]);
app.constant('APIprefix', '/api');
Reading from non angular scope
var prefix = angular.injector(['ng', 'module']).get('APIprefix');
Thanks pixelbits for showing me the way :)
So, I've been talking with co-workers about the "right way" to create an AngularJS controller. I know there are several ways of creating one, but I'm interested in getting my team writing them the same way AND the "right" way. By "right way" I'm talking about easy to read, testable, and performant. I'm sure there are competing theories on the best way to create a controller, but I'm most interested in test-ability at the end of the day since that is what AngularJS is built to do well.
Without further ado, here's the contenders:
Let's assume that our app is declared as so: var app = angular.module('app',[]);
1.
app.controller('myCtrl', function(){
...
});
2.
function myCtrl = {
...
}
app.controller('Ctrl', myCtrl);
3.
(function(app) {
app.controller('myCtrl', function() {
...
}
})(app);
Please let me know if I've missed one.
This does not take into consideration the changes needed for minification so please do not add that to this conversation.
Thanks! (I hope this doesn't start a flame war ><)
My team exclusively uses 1. I've considered 3 as well, and we just have a standing rule (and jshint constraint) about global level code. I would never use 2.
I always do it this way:
angular.module('myModule').controller('MyController', ['$scope', function($scope) {
<stuff>
}]);
Yes, it's a little more verbose, but it creates nothing in global scope, it is very clear what module the controller belongs to, and if I need to separate my controller into another file I just copy and past it without worrying about where 'app' is defined or about whether I missed a '.' in a chained declaration.
And I know I was supposed to ignore it, but of course this version is minification safe.
In general I believe you should find a clear standard and stick to it. That way if something doesn't look "right" you can tell right away.
The Angular team recently posted a best practices guide so that might be a good place to start: http://blog.angularjs.org/2014/02/an-angularjs-style-guide-and-best.html. Also this presentation discusses some best practices on creating controllers: https://docs.google.com/presentation/d/1OgABsN24ZWN6Ugng-O8SjF7t0e3liQ9UN7hKdrCr0K8/present?pli=1&ueb=true&slide=id.p
If you were using number 2 you wouldn't really need app.controller('Ctrl', myCtrl);. You can reference a controller from ng-controller even if it isn't defined with module.controller(...)
You might want to also consider making your controller as much like "classes" as javascript will allow and using the 'controller as' syntax.
var myApp = angular.module("myApp", []);
myApp.MyCtrl = function($log) {
this.$log = $log;
}
myApp.MyCtrl.prototype.sayHello = function() {
this.$log('hello');
}
There are cases where it may be useful to have your controllers globally accessible. Like if you want to create an instance of your controller with $injector.instantiate() you need to have access to its constructor (although you could use the $controller service to accomplish the same goal using a string).
var myCtrl = $injector.instantiate(myApp.MyCtrl); //Works
var myCtrl2 = $injector.instantiate('MyCtrl'); //Doesn't Work
But if you don't have a specific use case for making your controllers global you should probably encapsulate them with module.controller(...);.
This answer also advocates using module.controller() https://stackoverflow.com/a/13363482/373655
I'm wondering what's wrong with this snippet
var app = angular.module('myApp', []);
app.constant('_START_REQUEST_', '_START_REQUEST_');
app.constant('_END_REQUEST_', '_END_REQUEST_');
app.config(function($httpProvider, _START_REQUEST_, _END_REQUEST_) {
});
it give me
Unknown provider: START_REQUEST from myApp
Bye
It turns out that it is the way you have named your constants that is causing the problem.
If you change _START_REQUEST_ & _END_REQUEST_ to START_REQUEST & END_REQUEST it works.
It must be something to do with the _ at the start of the name.
This may be a bug or there may be a reason for it, but as it stands I don't know why angular doesn't accept the names like that.
Demo with no errors in console http://jsbin.com/UZaquNu/1/edit