AngularJs Routing with parameters - angularjs

Can someone explain how I can route to a Url using parameters?
E.g. id like to click on a product and open more info of the product by Id.
My Routing so far ...
angular.module('shop', ["customFilters", "cart", "ngRoute"])
.config(function ($routeProvider){
$routeProvider.when("/complete", {
templateUrl: "../app/views/orderComplete.html"
});
$routeProvider.when("/placeorder", {
templateUrl: "../app/views/placeOrder.html"
});
$routeProvider.when("/checkout", {
templateUrl: "../app/views/checkoutSummary.html"
});
$routeProvider.when("/products", {
templateUrl: "../app/views/productList.html"
});
$routeProvider.when("/product:", {
templateUrl: "../app/views/product.html"
});
$routeProvider.otherwise({
templateUrl: "../app/views/productList.html"
});
});
So By clicking ...
<a class="btn btn-default" href="#/product/{{item.id}}">More Info</a>
Id like to be routed to product/{{id}}.html ...
Can someone advise what I am missing in ...
$routeProvider.when("/product:id", {
templateUrl: "../app/views/product.html"
});

2 things, but you are basically there.
First you are missing a slash before the URL param. Happens to the best of us.
routeProvider.when("/product/:id", {
templateUrl: "../app/views/product.html"
});
Secondly you should use ng-href instead href when you have dynamic URL params.
<a ng-href="#/product/{{item.id}}">More Info</a>

I thinks this issue is duplicate, see response How to pass parameters using ui-sref in ui-router to controller
you can send paramters to state name as home({foo: 'fooVal1', bar: 'barVal1'})
with a url '/:foo?bar'
see this exemple:
$stateProvider
.state('home', {
url: '/:foo?bar',
views: {
'': {
templateUrl: 'tpl.home.html',
controller: 'MainRootCtrl'
},
...
}
and send values as:
<a ui-sref="home({foo: 'fooVal1', bar: 'barVal1'})">

Related

Append id to url

<a ui-sref="Contacts.Details.{{contact.Id}}" ng-click="showContactDetail(contact.Id)">
Here there is a ui-sref in which i am giving id.
I want the url as per that contact.Id
state('Contacts.Details', {
url: '/Details',
templateUrl: 'Contact/Detail',
controller: 'formController'
})
here is the config for contacts.details
i want to get contacts/details/(id which i clicked)
can any one help me out.
Here is how to do it
state('Contacts.Details',
{
url: '/Details:id',
templateUrl: 'Contact/Detail',
controller: 'formController'
})
Then you use
$state.go('Contacts.Details', {'id' : yourid});
to go where you want
(edit : here is how to use ui-sref)
ui-sref="Contacts.Details({id : yourid})"
Pass the ID as a parameter in your state call:
<a ui-sref="Contacts.Details({contactId: contact.Id})">...</a>
And then recover it in your state:
state('Contacts.Details', {
url: '/Details/:contactId',
templateUrl: 'Contact/Detail',
controller: 'formController'
});
URL routing docs in ui-router

How to define defaults for query params in AngularJS UI-Router?

I have a route:
.state('list', {
url:'/list?query',
templateUrl: '/views/list.html',
controller: 'ListCtrl as vm'
})
Is there a way to ensure a default value for the query?
I don't want to do it in the controller, as I use the same controller for other routes, and the controller has certain behaviour if the query is undefined.
What I want is this particular route to default that query.
In the old angular route I have done this sort of thing...
.when('/list',
templateUrl: '/views/list.html',
controller: 'ListCtrl'
controllerAs:true,
redirectTo:function(routeParams, path, search) {
if(!search.query) {
return "list?query=defaultSearch";
}
}
})
You could use the onEnter method to execute logic before your controller loads.
From the ui-router wiki https://github.com/angular-ui/ui-router/wiki:
$stateProvider.state("contacts", {
template: '<h1>{{title}}</h1>',
resolve: { title: 'My Contacts' },
controller: function($scope, title){
$scope.title = title;
},
onEnter: function($location){
if($location){ ... do something ... }
}
})
We can use a setting called params. There is a working plunker
.state('list', {
url:'/list?query',
templateUrl: 'views/list.html',
controller: 'ListCtrl as vm',
params: { query: 'DEFAULT VALUE' }, // here the default
})
and these links will work as expected
<a href="#/list?"> - with default 'query' value
<a href="#/list?query=someParam">
<a ui-sref="list({query:'theParam'})">
Check it in action here
The details are discussed here:
Angular ui router passing data between states without URL
If I am getting you right, you need to go to a state if the user requested state does not match any of the states defined.
If this is the requirement, then try using "otherwise" method of $urlRouterProvider
like,
$urlRouterProvider.otherwise("/default-state");

Angular ui router controlleras syntax not working

I an trying to develop an angular app using ui router, however I am stuck trying to get the controllerAs syntax working correctly.
my stateProvider looks like this
$stateProvider
.state('microsite', {
url: "/",
templateUrl: "microsite.tmpl.html",
abstract: true
})
.state('microsite.home', {
url: "",
templateUrl: "home.tmpl.html",
controller: 'MicrositeController as vm',
data: {
page_name: 'Introduction'
}
})
.state('microsite.features', {
url: "/features",
templateUrl: "features.tmpl.html",
controller: 'MicrositeController as vm',
data: {
page_name: 'Features'
}
})
.state('microsite.about', {
url: "/about",
templateUrl: "about.tmpl.html",
controller: 'MicrositeController as vm',
data: {
page_name: 'About'
}
});
As you can see I setup an abstract default view, and three pages.
I have also assigned a data object with a page_name for each page. This feeds into my controller
myapp.controller('MicrositeController', ['$state', function($state) {
var vm = this;
vm.page_name = $state.current.data.page_name;
vm.sidenav_locked_open = false;
vm.toggleSideNav = function() {
if ($mdMedia('gt-sm')) {
vm.sidenav_locked_open = !vm.sidenav_locked_open;
} else {
$mdSidenav('left').toggle();
}
}
}]);
and then delivers the name to the page via the vm.page_name variable.
However this is not happening. The variable never makes it to the page.
Also I have a vm.toggleSideNav function that is suppose to open and close the sidenav, but that never gets called.
the toolbar with the sidenav button is this
<md-toolbar layout="row" class="md-whiteframe-glow-z1 site-content-toolbar">
<div class="md-toolbar-tools docs-toolbar-tools" tabIndex="-1">
<md-button class="md-icon-button" ng-click="vm.toggleSideNav()" aria-label="Toggle Menu">
XXX
</md-button>
<h1>{{vm.page_name}}</h1>
</div>
</md-toolbar>
here is a plnkr example http://plnkr.co/edit/Na5zkF?p=preview
I am looking for someone to help me figure out the last piece on how to get the toggleSideNav function to get called when I click on the xxx button, and how to get the title to display in the toolbar.
From the Docs:
controller
(optional)
string
function
Controller fn that should be associated with newly related scope or the name of a registered controller if passed as a string. Optionally, the ControllerAs may be declared here.
controller: "MyRegisteredController"
controller:
"MyRegisteredController as fooCtrl"
controller: function($scope, MyService) {
$scope.data = MyService.getData(); }
— UI Router $stateProvider API Reference.
According to the Docs, your controller declaration is correct.
controller: 'MicrositeController as vm'
You need to look for your problem elsewhere.
UPDATE
Put the controller in the root state:
$stateProvider
.state('microsite', {
url: "/",
templateUrl: "microsite.tmpl.html",
//IMPORTANT == Put controller on root state
controller: 'MicrositeController as vm',
abstract: true
})
.state('microsite.home', {
url: "",
templateUrl: "home.tmpl.html",
̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶:̶ ̶'̶M̶i̶c̶r̶o̶s̶i̶t̶e̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶ ̶a̶s̶ ̶v̶m̶'̶,̶
data: {
page_name: 'Introduction'
}
})
.state('microsite.features', {
url: "/features",
templateUrl: "features.tmpl.html",
̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶:̶ ̶'̶M̶i̶c̶r̶o̶s̶i̶t̶e̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶ ̶a̶s̶ ̶v̶m̶'̶,̶
data: {
page_name: 'Features'
}
})
.state('microsite.about', {
url: "/about",
templateUrl: "about.tmpl.html",
̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶:̶ ̶'̶M̶i̶c̶r̶o̶s̶i̶t̶e̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶ ̶a̶s̶ ̶v̶m̶'̶,̶
data: {
page_name: 'About'
}
});
})
The DEMO on PLNKR
Try adding the option controllerAs: 'vm' to the state params instead defining the controller as in the controller option.
Try adding the option controllerAs: 'vm' to the state params instead defining the controller as in the controller option.
or, if I'm not mistaken, you can add
myapp.controller('MicrositeController as vm' ...

Why is ui-sref='tango::new' sending a request to /tangos/new (plural)?

HTML
<a ui-sref='tango::new'>Create Tango</a>
tango.routes.js
angular
.module('tango')
.config(config)
;
function config($stateProvider) {
$stateProvider
.state('tango', {
url: '/tango/:id',
templateUrl: '/states/tangos/tango.html',
controller: 'TangoController as vm'
})
.state('tango::new', {
url: '/tango/new',
templateUrl: '/states/tangos/tango.html',
controller: 'TangoController as vm'
})
;
}
This is the request that is going out when I click the link:
GET http://localhost:3000/tangos/new
Why is this? How can I stop it from happening?
There is a working plunker
The point here (despite of a bit unusual state name tango::new - which is still absolutely valid) is: the order of state definition:
the first (sooner) must be defined more specific, the second (later) the more generic
So, this should be the proper order:
.state('tango::new', {
url: '/tango/new',
templateUrl: 'states/tangos/tango.html',
controller: 'TangoController as vm'
})
.state('tango', {
url: '/tango/:id',
templateUrl: 'states/tangos/tango.html',
controller: 'TangoController as vm'
})
With this order in place, these links will work:
//ui-sref
<a ui-sref='tango({id:1})'>tango({id:1})
<a ui-sref='tango({id:22})'>tango({id:22})
<a ui-sref='tango::new'>Create Tango
//href
<a href="#/tango/333">
<a href="#/tango/4444">
<a href="#/tango/new">
Check it here

Angularjs - one route two possible views

I want to be able to use one single route for two different views.
For example right now, I have two routes.
One is /home which is the main page when someone can register/login
And the other one /feed, this is when the user is logged in.
What I want to do is having a single route like twitter for example :
twitter.com/
first they ask you to login
twitter.com/
Than we can see our feed wall. And it's still the same "/". Hope I'm clear :)
This is my code so far:
$stateProvider
.state('index', {
url: '/',
controller: function($state, $auth) {
$auth.validateUser()
.then(function(resp) {
$state.go('feed');
})
.catch(function(resp) {
$state.go('home');
});
}
})
.state('home', {
url: '/home',
templateUrl: 'home.html'
})
.state('feed', {
url: '/feed',
templateUrl: 'feed.html'
})
As far as I remember ui-router doesn't support such feature so you have to do it yourself.
What you can do is to define only a single state as you did in 'index' and instead of performing the $auth logic in the controller do it in a the "resolve" section.
then you can use "ng-if" and "ng-include" to define which .html file and controller you'd like to load, something like this:
app.js
$stateProvider
.state('index', {
url: '/',
resolve: {
isAuthenticated: function() {
return $auth.validateUser().then(function(res) {
return true;
}, function(error) {
return false;
});
}
},
controller: function($scope, isAuthenticated) {
$scope.isAuthenticated = isAuthenticated;
},
templateUrl: 'index.html'
})
index.html
<div ng-if="isAuthenticated">
<div ng-include="'feed.html'"></div>
</div>
<div ng-if="!isAuthenticated">
<div ng-include="'login.html'"></div>
</div>

Resources