angularjs, coding style, use of global variable - angularjs

I see a lot of Angular codes more like this.
The following one is from their tutorial.
angular.module('phonecat', ['phonecatFilters', 'phonecatServices']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl}).
when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
otherwise({redirectTo: '/phones'});
}]);
However, I am more familiar with like this;
var app = angular.module('phonecat', ['phonecatFilters', 'phonecatServices']);
app.config(function($routeProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl}).
when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
otherwise({redirectTo: '/phones'});
}]);
I even want to define that function($routeProvider) { ...} as a variable, but I am not confident about that will work.
Is there a reason behind this to avoid global variable, in this case app.
Or it's just one of best practices in AngularJs community?

angular.module(..) returns a module, and you can;
assign to a variable app(which is a global variable).
or continue chaining it
You saw a lot of chained examples because it is in a single file.
You will also see a lot of examples using global variable 'app' or whatever, because codes needs to be organized to many files.
I recommend the first one if you make an single file example.
I recommend the second one if you make an actual app, which requires name spacing.

Namespacing is good. Best practive is using angular.value instead of global variables
app.value('myVariable', 'myValue')
.controller('myController', function($scope, myVariable) {
...
});

Related

angularjs ngroute and htaccess rewrite

I am wondering how to work angularjs ngRoute and htaccess rewrite together.
I have ngRoute working so I get URLs like these:
http://domain.com/#/something/somestring
But I would very much like this result:
http://domain.com/something/somestring
In other words, I'd like to get rid of /# in my URLs.
I've done this before with .htaccess and mod_rewrite.c and PHP, but I have no clue how to achieve the same result with AngularJS.
Any pointers, tutorial-links, articles, etc. that explains how this can be done, or simply an example would be greatly appreciated.
A few requirements:
I should still be able to do my routing the same way I've done so far:
blogApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/page/:pagePermaLink', {
templateUrl: './assets/templates/page.html',
controller: 'pageCtrl'
}).
when('/article', {
templateUrl: './assets/templates/article.html',
controller: 'articleCtrl'
}).
otherwise({
redirectTo: '/home',
templateUrl: './assets/templates/page.html',
controller: 'mainCtrl'
});
}]);
The URL query string, like :pagePermaLink should still be accessible from the scope:
blogCtrl.controller('pageCtrl', ['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
var foo = $routeParams.pagePermaLink;
// ...
}]);
If you've already done your rewrites, you should just be able to set $locationProvider.html5Mode(true). See https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode
Also, similar stack overflow questions might be of assistance:
Angular Direct Url without hash
$location / switching between html5 and hashbang mode / link rewriting

Route Parameters in AngularJS

I'm working on an Angular.js application. It has 7 "pages" that make up a report about backlinks. The main url looks like http://www.site.com/report/# so the first route below '/' points to that URL.
My problem is I want to have the report ID in the url. So something like this. http://www.site.com/report/#/:reportId or http://www.site.com/report/#/99DF82A023FCE3515BE9A18F00908939F5A29D14.
I need to access that ID and store it somehow for each page. So on http://www.site.com/report/#/live I still need access to reportID.
Im sure this is a simple thing but Im an Angular noob. Can someone point me towards a tutorial for this? Here's what I have so far.
'use strict';
// Declare app level module which depends on filters, and services
var ultModule = angular.module('ultimate-report', ['ngRoute', 'ngCookies', 'ngTable', 'ultimate.filters','ultimate.services','ultimate.directives','myApp.controllers', 'ultimate.config']);
ultModule.config(['$routeProvider', function($routeProvider, $routeParams) {
$routeProvider
.when('/', {templateUrl: '../partials/report/about.html', controller: 'CtrlReport'})
.when('/live', {templateUrl: '../partials/report/links-live.html', controller: 'CtrlLinksLive'})
.when('/dead', {templateUrl: '../partials/report/links-dead.html', controller: 'CtrlReport'})
.when('/selected', {templateUrl: '../partials/report/links-selected.html', controller: 'CtrlReport'})
.when('/patterns', {templateUrl: '../partials/report/patterns.html', controller: 'CtrlReport'})
.when('/exports', {templateUrl: '../partials/report/export.html', controller: 'CtrlReport'})
.when('/help', {templateUrl: '../partials/report/help.html', controller: 'CtrlReport'})
.otherwise({redirectTo: '/'});
}]);
So do you really want the other urls (e.g. http://www.site.com/report/#/live) to not have the report id in them? It would be a lot easier/shorter if you had the parameters in each adress (e.g. http://www.site.com/report/#/12334223287/live).
Nonetheless, I would create my own service ('ReportID') that just stores the report ID. And then include both $routeParams and ReportID (your service) as dependencies in your controller.
app.controller('CtrlReport', ['$routeParams', 'ReportID', '$scope'],
function($routeParams, ReportID, $scope){
ReportID.id = $routeParams.reportID;
})
and set up your route as such
.when('/report/:reportID', ...)
Angular ui-router is a great extension to Angular.js that makes it easy to handle route parameters, nested views etc.
As others have pointed out, keeping the ID in the url for all pages is a good idea - without that people cannot bookmark the page and go straight back to viewing the same item in the same view.

Replacing $routeProvider with the latest and greatest from Angularjs

I am just getting started with an angular project. We have a number of simple views and controllers, and have been using the mechanism provided by $routeProvider to map controllers to views. Upon updating to angular v1.2.0 the $routeProvider mechanism appears to be gone and replaced with something better. However, I have not been able to find a coherent code example showing how to make the switch.
What I have looks like this:
theApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/foo', {
templateUrl: 'views/foo.html',
controller: 'FooCtrl'
})...
What has that changed to?
Thanks
It is still $routeProvider, but they moved it out into a module. You need to add it to the list of dependencies for your app by injecting 'ngRoute'.
You can get the routing module with the others for http://code.angularjs.org/1.2.0-rc.2/
here.

angularjs routing, multiple paths

I have the following set up:
var userSystemApp = angular.module("userSystem",['userServices','groupServices']).
config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider.
when('/user', {templateUrl: 'user/partials/userlist.html', controller: 'userListController'}).
when('/user/:userName', {templateUrl: 'user/partials/userdetail.html', controller: 'userDetailController'}).
when('/group',{templateUrl: 'group/partials/grouplist.html', controller: 'groupListController'}).
when('/group/:groupName', {templateUrl: 'group/partials/groupDetail.html', controller: 'groupDetailController'}).
otherwise({redirectTo: '/user'});
}]);
When I go to localhost/#/user the groupListController is activated.
When I go to localhost/#/group the groupListController is activated but it uses the userlist.html partial template.
Why isn't it using the proper controller? Am I fundamentally using routing and templates improperly?
(side note, I have mod_rewrite taking rewriting the blank path to index.html)
Probably there is an error where the controllers are defined.
It seems you have something like:
userSystemApp.controller('userListController', theFunction);
But theFunction instead of being the correct one, which returns the userListController, is by mistake the one which defines the groupListController.

TypeScript example of AngularJS $routeProvider module

I am currently working up a simple couchapp that uses AngularJS and have decided to use TypeScript
I am basing it off of the AngularJS angular-phonecat tutorial. I have most of the application converted to idiomatic TypeScript. I have based this off of the pwalat / Piotr.Productlist bits1, however they only cover Controllers and Models.
I am struggling to figure out how to create the correct TypeScript equivalent for the angular router $routeProvider
//app/js/app.js[2]
angular.module('phonecat', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl}).
when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
otherwise({redirectTo: '/phones'});
}]);
I know it needs to be a module {} of some sort?
The angular-vs team has some stuff that is really worth looking at:
https://github.com/kriasoft/angular-vs/blob/master/App/Scripts/App.ts
...in this case, they do a sort of a cast on the initial string in the any array passed to config that avoid the trouble that Typescript seems to have figuring out which version of config to use (.config(<any>'$routeProvider'...).
Example:
angular
.module('phonecat', [])
.config([
<any>'$routeProvider',
($routeProvider: angular.RouteProvider) {
$routeProvider
.when('/phones', { templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl })
.when('/phones/:phoneId', { templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl })
.otherwise({ redirectTo: '/phones' });
}
]);
...I should mention, that I installed the AngularJS TypeScript declations source from here:
http://nuget.org/packages/Schmulik.AngularTS
..and then reference them at the top of my routing file:
/// <reference path="../AngularTS/angular.d.ts" />
/// <reference path="../AngularTS/ng/route.d.ts" />
You can also use ng.route.IRouteProvide
I found the answer here: http://morrisdev.com/2016/01/angular-controllers-with-typescript/
interface IRouteParams extends ng.route.IRouteParamsService {
userId: number;
}
I haven't looked up AngularJS to find out all the details, but hopefully this will help you with the process of declaring an existing library, which is more useful than just giving you an AngularJS definition.
I have created these definitions based on your usage. The important bits are...
The Angular definition describes the functions you can expect to call on an instance of an Angular class.
The RouteProvider definition describes the functions you can expect to call on an instance of a RouteProvider class
I then declare angular and $routeProvider and tell the compiler they are instances of the classes defined in the previous steps.
Disclaimer: because I don't know what the arguments in your example represent I have used names like param1 but these should be updated to reflect what is actually expected, for example filePath: string - or whatever it actually is.
Here is the example:
// I don't know what the param names should be, so they
// need to be changed to sensible names
declare class Angular {
module (param1: string, param2: any[]) : Angular;
config(param1: any[]) : Angular;
}
declare class RouteProvider {
when(param1: string, param2: any) : RouteProvider;
otherwise(param1: any) : RouteProvider;
}
declare var angular: Angular;
declare var $routeProvider: RouteProvider;
// These are just because I don't know where you define them...
declare var PhoneDetailCtrl: any;
declare var PhoneListCtrl: any;
function myFunction ($routeProvider: RouteProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl}).
when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
otherwise({redirectTo: '/phones' });
}
angular
.module('phonecat', [])
.config(['$routeProvider', myFunction]);

Resources