which is best practice using $routeProvider or using $stateProvider in angularjs? - angularjs

I am building small app using angularjs and nodejs and i would like to know what is best use case for $stateprovider and $routeProvider.
Please help

Angular's own ng-Router takes URLs into consideration while routing, UI-Router takes states in addition to URLs.
States are bound to named, nested and parallel views, allowing you to powerfully manage your application's interface.
While in ng-router, you have to be very careful about URLs when providing links via tag, in UI-Router you have to only keep state in mind. You provide links like . Note that even if you use in UI-Router, just like you would do in ng-router, it will still work.
So, even if you decide to change your URL some day, your state will remain same and you need to change URL only at .config.
While ngRouter can be used to make simple apps, UI-Router makes development much easier for complex apps.

$stateprovider is used when you want the app to have different states like if you want jst a small section of a screen to be loaded at times instead of the entire screen, the go for State provider and the $state.go(url). Special cases when you have a Sliding Drawer sort of an implementation, where you have a right menu with buttons which load different sub screens.
$routeProider are commonly used. Mostly when you want the entire screen to be changed and redirected to a new one.
Note
While using the $state.go(url); for redirecting your screen, the real link of your screen won't change. It will just change the state and not the url of the page

Not to confuse the issue, but there is a new option in AngularJS 1.5: ComponentRouter
This router, along with the uiRouter ($stateProvider) give you more flexibility than the legacy ngRouter ($routeProvider). The ComponentRouter and uiRouter both have a future if you migrate to Angular2.
That said, it depends on your needs. You may not need the composable and nested views offered by ComponentRouter and uiRouter -- but instead only need simple routes.

Related

Moving through a Multi Page Application in AngularJS

I'm structuring a Multi Page App in angular. I have a main app with its ngRoute configured so that the resulting url is something like:
http://localhost:8080/project/main#firstTemplate
http://localhost:8080/project/main#secondTemplate
http://localhost:8080/project/main#thirdTemplate
...
Now I must move to another app in the same project so that the Url is something like:
http://localhost:8080/project/secondary#fourthTemplate
I'm able to achieve this by manipulating the string resulting by $location.absUrl() and pass it to $window.location.href but it's horrible.
Is there a better way to do the same thing?
You should do this by the means of your router. There is a default router in angular, though I would suggest you going with https://github.com/angular-ui/ui-router - as I think it is much better than Angular v1.x defaults.
With that router you can define few states (1 state per each URL), define URL for each state, define views to be displayed in that state, actions on entry/leave etc. Then, you can get access to $state object and its go() method to switch between states - as well as easily have it done automatically on elements by specifying .

Advantage of angular UIRouter over ng-include?

I'm wondering whether to use angular UI router or just use simple ng-include, i'm failing to fully understand why would i pick to include entire library over the built-in ng-include which gives me about the same functionality with less code?
Can someone explain whats wrong with
<div ng-if="somestate" ng-include="someview"></div>
Can someone explain whats wrong with
<div ng-if="somestate" ng-include="someview"></div>
It doesn't handle URLs in any way. You want the URL to change when you go to another state, and you want the state to change when the URL changes. You want to be able to bookmark a page in your app, or send its URL by email, and come back to this page rather than the home page when opening the bookmark or the link.
It also doesn't allow resolving data before switching to a state.Both ui-router and ngRoute allow doing that: the state changes only when the data needed to display this state has been successfully loaded.
That's the main job of ui-router and ngRoute. ui-router has many other goodies, like events when changing state, named views, state inheritance (very useful to handle a view consisting of several tabs, for example), etc.

What is the difference between $state.go(app.location) and $location.path("app/location")?

I have recently started using ionic framework, it has angular js in it. To navigate between screens, I was using $location.path and it's working great. However, in an example I've downloaded, I saw $state.go being used to redirect to some page. I would like to know the difference between the two.
The $location service is on the angular.js framework out of the box and allow you to manage location object (similar to that in pure javascript).
The $state service is a part of ui-router module and allows you to manage routes in an advanced mode, throughout a state machine management of views.
If you use ui-router, you should prefer to use $state service to manage states/routes because state abstracts the concept of route and you could change the physical routes without changing states.
Besides that, more problems you could have if you run in hashbang mode, in particular in your html links. In this case it's preferable to use ui-sref rather than ng-href (or just href).
In my opinion, you should always think in term of states rather than paths. Obviously you can mix the services if you know what you're doing
Thanks #wilver for answering it.
As I dug deeper into angular and learned different ways of structuring my projects, I got to understand these states and paths better. And yes, I've found states much better than paths.
$state.go, which comes with $stateProvider - a provider by ui-router, will work based on state names. Major difference between previously inbuilt(now you need to include ngRoute) router and states is that "States can have nested states but with router it's not possible. And I suddenly realized that whole of Ionic framework is possible because of this concept - I was able to understand this while working on an angular web app based on ngRoute and ionic app based on ui-router.
Ionic works with app as basic state and all other screens defined as its sub states. That's why you see app.screen1, app.screen2 inside $stateProvider in app.js.
So when you have routes, you use $location.path("<routeUrl>") and
when you have states, you use $state.go("<stateName>")
I use ionic and one of the differences that I have observed but not yet figured out why is that $location.path is much slower than $state.go

angular ui-router best practice inheritance vs metadata

I am converting my application from ngRoute to uiRouter. I have read and watched a lot of tutorials but I am still lacking the experience to decide on best practices.
First of all a major change I have done is break the state declaration to each module/controller. This feels more natural and cleaner to me but introduces some complexity when wanting to apply a global rule to many states. For example half my routes require authentication and the other half do not.
With ngRoute I had a data attribute denoting the auth level required in each route. With uiRouter I understand there is this way of doing it and there is the state inheritance way. So a route could be public.myRoute where public is an abstract route declared at the application level. This creates the issue though of the module not being able to work standalone if someone does not define the public state.
In contrast if I add a metadata attribute in the data object, like "auth_level: user" this would not affect the module if no one is dealing with it. But this feels more "magic" and less maintainable.
The same issue arises with the navigation bar. Half my views have a navigation bar and the other half don't. Until now I used a isNavbarVisible boolean attribute but I understand this should be part of the state? Maybe a second ui-view in the layout.html template instead of using ng-include with ng-if as I did so far?
Finally, I am wondering about the best practice in requiring a promise in every route to be resolved. For example, no matter where the application entry point is, the user rights should be resolved first before loading the view. In ngRoute I was looping through all the routes in their definition and adding that promise.
Is there a good guide for best practices when migrating from ngRoute to uiRouter, because other than generic recommendation like "replace ng-include" with a name ui-view or that state inheritance should be preferred, I haven't found any concrete implementations demonstrating that.
I am in the same situation than the question author, Here's some very interesting information about how to drive this change.
https://github.com/angular-ui/AngularJS-StyleGuide
ui-router is a 3rd-party module and is very powerful. It supports everything the normal ngRoute can do as well as many extra functions.
Here are some common reason ui-router is chosen over ngRoute
ui-router allows for nested views and multiple named views. This is very useful with larger app where you may have pages that inherit from other sections.
ui-router allows for you to have strong-type linking between states based on state names. Change the url in one place will update every link to that state when you build your links with ui-sref. Very useful for larger projects where URLs might change.
There is also the concept of the decorator which could be used to allow your routes to be dynamically created based on the URL that is trying to be accessed. This could mean that you will not need to specify all of your routes before hand.
states allow you to map and access different information about different states and you can easily pass information between states via $stateParams.
You can easily determine if you are in a state or parent of a state to adjust UI element (highlighting the navigation of the current state) within your templates via global $state provided by ui-router
Overall, ngRoute merely allows you to assign controllers and templates to URL routes, whereas the fundamental abstraction in ui.router is states, which is a more powerful concept.

Doubly nested views : UI-Router or UI-Bootstrap tabs / accordion?

I am a total Angular (and JS) beginner.
I want to develop something like this:
(with apologies to #PhillipKregg for borrowing his excellent illustration).
Effectively, I want nested tabbed notebooks - a row of tabs (views?), each which can contain data or another row of tabs (each of which ...).
Googling seems to return more recommendations for UI-Router, but I imagine that UI-Bootstrap's Tabs or Accordion could also be used (or even UI-Bootstrap's Pagination, with a single view whose contents I update according to the selected page?).
All else being equal, I will go with whichever is easiest for a novice to understand and implement (which is that?).
But - are there performance issues? For instance, will one download the content of all the views immediately or initial page load (thus increasing initial page download time)? Will one only download the data for a view when it becomes active (which seems preferable)?
Anything else I need to consider?
Yes, ui-router & ui-bootstrap.tabs are the best tools for the job at the moment. To do something similar would require mixing two types of ui-router config patterns, nest views & multiple named views. I'd suggest reading both these wiki pages:
https://github.com/angular-ui/ui-router/wiki/Nested-States-&-Nested-Views
https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
Here's a basic draft demo of something similar to your illustration, using ui-router & ui-bootstrap.tabs: http://plnkr.co/edit/BUbCR8?p=preview
The easiest way to get started is to use ng-boilerplate https://github.com/ngbp/ngbp, it uses ui-router & has best-practice directory structure. It also addresses performance issues by compiling html to js & adding templates to $templateCache, thus kicking lots of XHR requests to the curb.
Regards to data downloads, data would typically be managed by a angularJS service singleton instance, separate from any views. How & when you invoke any service from any view is totally your choice. This is a pretty good tutorial on angular services: http://www.ng-newsletter.com/posts/beginner2expert-services.html
I would recommend to use angular $routeProvider for your task. This will make easy to handle code and view fragments.
With bootstrap you will need to put all the code on single page and that is less manageable. Have a look at
http://viralpatel.net/blogs/angularjs-routing-and-views-tutorial-with-example/ and
For nested views
http://www.bennadel.com/blog/2441-Nested-Views-Routing-And-Deep-Linking-With-AngularJS.htm
Also $routeProvider is better for navigation. Back Forward through view...
Angular will load views when required.(Lazy loading.) So better for performance...
Hope this will help.
I personally don't get the point of wanting to use bootstrap tabs with angular's ui-router. It is counter-intuitive. Just don't use bootstrap's tabs and set up the "sub-tabs" in the angular config. This will also make your code more readable. Only add ui-bootstrap if you NEED the extra features. An example config is below
$stateProvider.state('A', {
url: "/A",
controller: "testController",
templateUrl:'pages/A.html'
})
.state('A.B', {
url: "/A/B",
controller: "testController2",
templateUrl:'pages/A.B.html'
})

Resources