Param at ui-sref not passed - angularjs

I have my ui-sref code here.
<div class="container">
<div ng-repeat="vendor in Items"
id="scrollArea">
<img src='{{vendor.img}}'
style='width:100%;'
ui-sref='vendordetail({vendorId:1})'/>
</div>
</div>
And my $stateProvider
.state('vendordetail',{
views:{
url:'/:vendorId',
'mycontainer':{
templateUrl:'vendordetail',
controller:function($scope, $stateParams) {
console.log('vendordetail controller');
console.log($stateParams);
}
}
}
});
The templateUrl "vendordetail" is displayed on the targeted ui-view "mycontainer" successfully. "vendor detail controller" string is logged as well. But the $stateParams is an empty object {}. What did I actually missed out to pass the param vendorId to my state controller?
I hope I am not missing out any context. Thanks in advance.

Related

can't get the value of $stateParams in controller

I am trying to get the value of $stateParams in my controller but it is always undefined but I can see there is a value in my view.
As you can see there are values on each link.
app.js
.state('app.help', {
url: '/help',
views: {
'menuContent': {
templateUrl: 'templates/help.html'
}
}
})
.state('app.help-replies', {
url: '/help/:id',
views: {
'menuContent': {
templateUrl: 'templates/help-replies.html'
}
}
})
html view
this is the where the lists of data displays
<div ng-repeat="x in helpData">
<a class="row responsive-xs" href="#/app/help/{{x.id}}">
<div class="col"><h6>{{x.subject}}</h6></div>
</a>
</div>
this is where the single view of the clicked data in the above view.
<div class="row responsive-xs" ng-init="viewHelpAndReplies()">
<div class="col">
<h5>Subject: {{$scope.help_id}}</h5>
</div>
</div>
controller.js
$scope.viewHelpAndReplies = function(){
console.log($stateParams.id);
}
I think you should use ui-sref to pass data
<div ng-repeat="x in helpData">
<a class="row responsive-xs" ui-sref="app.help-replies({id: x.id})">
<div class="col"><h6>{{x.subject}}</h6></div>
</a>
</div>
and retrieve id with
$scope.id = $stateParams.id;
Okay I think I got what I needed. But I am not sure if this is good, but for me it is okay because it works.
Here's what I do:
I change the href
href="#/app/help/{{x.id}}"
into ng-click and create a function
ng-click="doViewHelp({id:x.id})"
and create function in my controller.js:
$scope.doViewHelp = function(data){
$state.go('app.help-replies');
// some codes...
}
Thanks.

Controller outside ui-view

I want to use a unique controller inside and outside ui-view.
Using ng-inspector I see <div ui-view> has another instance of myController, not sure why.
<div class="container" ng-controller="myController">
::{{_path}}
<a ng-click="action()">action</a>
<div ui-view class="view"></div>
</div>
app.controller("myController",function ($scope) {
$scope.action = function(){
$scope._path= "changed";
}
});
The result of this issue is if I click on <button ng-click="action()">action</button> I see the changes in _path, if the same button is inside ui-view, _path doesn't changes. How can I make this work?
When you define your state you can specify the controller you want to use inside your view as follows:
$stateProvider.state('myState', {
url: '/my-state',
templateUrl: '/templates/my-state.html',
controller: 'myController'
});
Hope this helps.

Angular Pages with QueryString

I want to create an event page and event detail page in angular. I created my states like this in my app.js
.state('app.event', {
url: "/event",
views: {
'menuContent': {
templateUrl: "views/event.html",
controller: "eventController"
}
}
})
.state('app.eventDetail', {
url: "/eventDetail/:eventId",
views: {
'menuContent': {
templateUrl: "views/eventDetail.html",
controller: "eventDetailController"
}
}
})
I m getting my events in my views/event.html page like this
<div class="list" ng-controller="EventController">
<div class="item item-avatar item-left" ng-repeat="EventName in Events track by $index">
<p>{{ EventName }}</p>
<p>{{ EventId }}</p>
</div>
</div>
My question is how can i redirect my Event page to EventDetail page with event Id ?
And my other question is how can i get that id in my EventDetail page ?
You could use ui-sref like this:
<div class="list" ng-controller="EventController">
<div class="item item-avatar item-left" ng-repeat="EventName in Events track by $index">
<a ui-sref="app.eventDetail({eventId: EventId})">{{ EventName }}</a>
</div>
</div>
Clicking the link for an event should redirect to the details page and then to get the parameter from the url you would use the $stateParams service:
app.controller('eventDetailController', function($scope, $stateParams) {
$stateParams.eventId;
});
I suspect that there may be a few errors in your code. So if you experience any issues with the above, please update your question with the code for both controllers and I'll try to update my answer to account for them.

ui router not activating the controller in template context

I have a template which would be resolved in ui-view as
<div class="row login" >
<div class="col-xs-12 col-sm-8 col-md-6 " ng-class="offSet">
</div>
</div>
Now The ui router state which resolves this template from templateUrl is
.state('login.register', {
url: "login/register",
views: {
"#": {
templateUrl: "/Account/Register"
},
controller: "loginController"
}
})
And the controller is :
ngApp.controller('loginController', ['$scope', '$state', function ($scope, $state) {
$scope.offSet = "col-lg-offset-3";
$scope.login = function () {
$state.go('dashboard.home');
}
}])
Now what I want is the ng-class should get applied as soon as the template resolves and rendered. But thats not happening . the ng-class is not getting applied if I dont provide ng-controller attribute .
However when I put the ng-controller='loginController' in my template as
<div class="row login" ng-controller="loginController">
<div class="col-xs-12 col-sm-8 col-md-6 " ng-class="offSet">
</div>
</div>
Then the class gets attached and I can see the effect on resulting dom.
But as far as ui router documentation says . the controlller gets attached to the dom as soon as the template is resolved .
Any idea why without ng-controller attribute its not working ????
You are almost there, solution here is surprisingly simple. Controller belongs to the view, in our case to "named" view, not to the cluster views:
.state('login.register', {
url: "login/register",
views: {
"#": {
templateUrl: "/Account/Register"
controller: "loginController" // here it will be used
},
//controller: "loginController" // just skipped
}
})
In case we'd like to reuse one controller for more named views, we just repeat its definition for each of them...

ui-router rendering ui-views in view templates

Just checking an approach for ui-router. Was sure it could do this but hitting some friction. I want my third template to render inside my 2nd template - but my controller is not even initialized for my 3rd state unless I define my ui-view in my 1st template.
Example code
Template 1 This is rendered from an MVC view
<div class ="animate-container" ng-app="uiRouter-Browse">
<div class="products-slide-animate" ui-view="cat1">
<div>
<div><a ui-sref="cat1({id:1})">1</a></div>
<div><a ui-sref="cat1({id:2})">2</a></div>
<div><a ui-sref="cat1({id:3})">3</a><div>
</div>
</div>
</div>
Template 2
<div>
<div class="row all-categories-wrapper">
<div class="col-xs-12 list-item">
<a href="#/" class="parent">
<i class="chevron-left"></i>
<div>All Categories </div>
</a>
</div>
</div>
</div>
<!--want 3rd template to render here -->
<div ui-view="cat2" class="products-slide-animate" autoscroll="false">
<div class="cat2-wrapper" ng-repeat="cat1 in data.Cat1s">
<div class="row">
<div class="col-xs-12 list-item">
<a ui-sref="cat2({id:{{cat1.ID}}, name:'{{cat1.UrlEncodedName}}'})">
<div class="list-item-text">{{cat1.Name}}</div>
<i class="chevron-right"></i>
</a>
</div>
</div>
</div>
</div>
Template 3
<div>
//some content to render
</div>
My ui-router script
var browse = angular.module('uiRouter-Browse', ['ui.router', 'ngAnimate'])
.run(
['$rootScope', '$state', '$stateParams',
$rootScope.$on('$stateChangeSuccess',
function (event, toState, toParams, fromState, fromParams) {
console.log(toState.name);
console.log(fromState.name);
}
);
}]);
browse.config(
['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.otherwise('/');
$stateProvider
.state('cat1', {
url: '/cat1/:id?name',
views: {
'cat1': {
templateUrl: '/Template1.html',
controller: //Get some data and return
}
}})
.state('cat2', {
url: '/cat2/:id?name',
views: {
'cat2': {
templateUrl: '/Template2.html',
controller: //Get some data and return
}
}
});
}]);
Most if not all of the examples I see the entire ui-view is replaced, as opposed to partially being replaced - i.e. the rendering of template 3 in the ui-view in template 2.
So when click on the cat 1 links from template 1, it transitions to the next state, the controller is invoked and my animations are pretty.
When I click on a cat2 link, my state is invoked correctly but the controller is not fired. I then just animate back to my previous view/state.
If I place a ui-view="cat2" div in template 1 then the controller fires and my template renders. I just would like it to render within the ui-view in template2.
Thanks
While not sure if it will really suite to your needs, the reason and solution is in a different state definition, we need state nesting. We simply cannot have two "totally" independent states, and try to inject one into another. We have to make one of them Parent and one to be a Child:
Current scenario:
$stateProvider
.state('cat1', {
...
}})
.state('cat2', {
...
});
Both states are in this snippet on the same "root" level. If we would like to nest the cat2 into cat1 they must be defined like this:
$stateProvider
.state('cat1', {
... // this is a parent
}})
.state('cat1.cat2', {
... // this is a child
});
That will lead to url for a (sub)state cat2 to be built from both parent and its own:
#/'/cat1/:id/cat2/:id?name&nameurl',
but if we do not need Parent url part and its parameters we can use absolute url:
.state('cat2', {
url: '^/cat2/:id?name',
See:
Methods for Nesting States
Absolute Routes (^)

Resources