Angular-UI-Router: ui-sref not building href with parameters - javascript

I have an HTML page, once loaded in the user's browser the 'list' state is activated and the 'list' partial is pulled by Angular and populated with a list of servers.
Each server has a 'details' link that specifies the 'details' state for that server.
<td><a ui-sref="details({ serverName: '{{server.name}}' })">Details</a></td>
When rendered the 'ui-sref' generates the expected 'href' url based on the route and its optional parameters.
<a ui-sref="details({ serverName: 'SLCMedia' })" href="#/details/SLCMedia">Details</a>
When clicked it works as expected and the 'details' partial is pulled and in the controller assigned to that state pulls the server with the name specified.
The issue I am running into is the fact that once the 'details' partial is loaded, it too has a 'ui-sref' to an 'edit' state.
<a ui-sref="edit({ serverName: '{{server.name}}' })">
<button class="btn btn-lg btn-labeled btn-primary">
<span class="btn-label icon fa fa-edit"></span>
Edit
</button>
</a>
But when this partial is loaded the 'ui-sref' is not generating the correct 'href' url.
<a ui-sref="edit({ serverName: 'SLCMedia' })" href="#/edit/">
<button class="btn btn-lg btn-labeled btn-primary">
<span class="btn-label icon fa fa-edit"></span>
Edit
</button>
</a>
As you can see the 'href' url is '#/edit/' not '#/edit/SLCMedia' as would be expected. It's got to be something simple that I am missing. Does the change of state have something to do with it?
Here are all of defined 'states' for the page.
// Create the Angular App to rule the Server Management Page
var serverApp = angular.module('serverApp', [
'ui.router',
'serverControllers',
'utilitiesService'
]);
serverApp.config(function ($stateProvider, $urlRouterProvider) {
// For any unmatched url, redirect to /state1
$urlRouterProvider.otherwise("/list");
// Now set up the states
$stateProvider
.state('list', {
url: '/list',
templateUrl: '/views/pages/servers/list.html',
controller: 'serverListCtrl'
})
.state('details', {
url: '/details/:serverName',
templateUrl: '/views/pages/servers/details.html',
controller: 'serverDetailsCtrl'
})
.state('create', {
url: '/create',
templateUrl: '/views/pages/servers/create.html'
})
.state('edit', {
url: '/edit/:serverName',
templateUrl: '/views/pages/servers/edit.html',
controller: 'serverEditCtrl'
})
});
Here are my controllers
var serverControllers = angular.module('serverControllers', ['utilitiesService']);
serverControllers.controller('serverListCtrl', function ($scope, $http) {
$http.get('/servers/getList').success(function (data) {
$scope.serverList = data;
});
});
serverControllers.controller('serverDetailsCtrl', function ($scope, $stateParams, $http) {
var serverName = $stateParams.serverName;
$http.get('/servers/getServerByName/' + serverName).success(function (data) {
$scope.server = data;
});
});
serverControllers.controller('serverEditCtrl', function ($scope, $stateParams, $http, $state, showAlertMessage) {
var serverName = $stateParams.serverName;
$http.get('/servers/getServerByName/' + serverName).success(function (data) {
$scope.server = data;
});
$scope.server.submitForm = function (item, event) {
console.log("--> Submitting Server Update");
//TIMDO: Verify all required fields have been included
var responsePromise = $http.post("/servers/postEdit", $scope.server, {});
responsePromise.success(function(dataFromServer, status, headers, config) {
showAlertMessage({
type: 'success',
title: 'Success',
message: 'Server information updated'
});
$state.go('clear');
});
responsePromise.error(function(data, status, headers, config) {
showAlertMessage({
type: 'error',
title: 'Success',
message: 'Server information updated'
});
});
}
});

Hmm, I'm probably misunderstanding your issue but I see at least one obvious difference between the look of your code and the look of mine.
My angular-ui-router links look like this:
<a ui-sref="reps-show({ id: rep.id })">{{rep.name}}</a>
The difference is the absence of braces around rep.id. So I wonder if changing this
<td><a ui-sref="details({ serverName: '{{server.name}}' })">Details</a></td>
to this
<td><a ui-sref="details({ serverName: server.name })">Details</a></td>
might do something for you.
That's probably not it but that's the first thing that came to mind for me.

I created simplified, but working version here. Because there is nothing obviously wrong. This example should at least help you to assure that:
All you are trying to do is supposed to be working.
Here are states:
// States
$stateProvider
.state('list', {
url: "/list",
templateUrl: 'tpl.list.html',
controller: 'serverListCtrl',
})
.state('edit', {
url: '/edit/:serverName',
templateUrl: 'tpl.html',
controller: 'serverEditCtrl'
})
Here controller of a list loading data
.controller('serverListCtrl', ['$scope', '$http', function ($scope, $http) {
$http.get('server.json').success(function (data) {
$scope.serverList = data;
});
}])
(server.json) - example of data
[
{"name":"abc"},
{"name":"def"},
{"name":"xyz"}
]
And the same template:
<li ng-repeat="server in serverList">
<a ui-sref="edit({ serverName: '{{server.name}}' })">
<button class="btn btn-lg btn-labeled btn-primary">
<span class="btn-label icon fa fa-edit"></span>
Edit {{server.name}}
</button>
</a>
</li>
All is working as expected. Check it here.

I want to contribute with another datapoint in-case some other folks arrive here with a similar question, as I did.
I was using the non-curly-brace version in my app, and it wasn't working. My specifics involve the InfoWindow in Google Maps. I believe there is a rendering order "issue" such that the data required for the ui-sref link doesn't exist, and when it does finally exist, it's never "re-rendered".
Original (non-working) version:
%h3
{{window_info.data.user.name || "Mystery Person"}}
%a.fa.fa-info-circle{ ui: { sref: 'users.show({id: window_info.data.user.id })' } }
%pre {{window_info.data.user.id | json}}
Working version:
%h3
{{window_info.data.user.name || "Mystery Person"}}
%a.fa.fa-info-circle{ ui: { sref: "users.show({id: '{{ window_info.data.user.id }}' })" } }
%pre {{window_info.data.user.id | json}}
I placed the %pre tag with the info to prove to myself that the datum was in-fact present (at least ultimately/eventually), but even still the original code for the link was not working. I adjusted my code to use the interpolated curly-brace version as per the OPs situation and it worked.
Conclusion: Your solution could depend on the way in which the parent component is handling rendering. Google Maps in this case is fairly notorious for being "funky" (technical term) with rendering, particularly in Angu-land.

Related

Angular JS UI-Routing with stateparams not working after refresh

Using angular-ui-router with angular for routing in MEAN application
angular: 1.6.2,
angular-ui-router: 0.4.2
Having following state:
.state('myposts', {
url: '/your-posts',
controller:'PostListController',
templateUrl:'post-list.template.html'
})
.state('postdetail', {
url: '/post/:postId',
controller:'PostDetailController',
templateUrl:'postdetail.template.html',
resolve:{
postdetail: ['Post', '$stateParams', function (Post, $stateParams) {
var url = '/api/posts/edit/' + $stateParams.postId;
return Post.get(url);
}]
}
})
In post-list.template.html listed all posts in table and there is an link to edit particular post by using the following
<a ui-sref="postdetail({ postId: post._id })" class="btn btn-default">
It makes an transition from myposts to postdetail with postId parameter.
Actual URL http://localhost:8886/#/post/58d5167bf05b904a52158f58
Here postId is 58d5167bf05b904a52158f58
Resolve post with postId = 58d5167bf05b904a52158f58 in resolve property of ui-router and inject in PostDetailController controller
function PostDetailController($scope, $state, $stateParams, postdetail, Post){
$scope.post = postdetail;
....
}
It works normally first time, but not working when i refresh the page having url
http://localhost:8886/#/post/58d5167bf05b904a52158f58
Using express server ^4.13.4,
Anyone having solution of above problems, why it is happening
Thanks

Angularjs adding html to variable with ui-sref link

I have the following code that adds html to a variable. However, when it get's shown on the page, the link doesn't work.
What's the best way to get a ui-sref link to work when inserting it dynamically?
JAVASCRIPT
.controller('page', function($scope, $rootScope, $http, $state, $sce) {
$scope.message = $sce.trustAsHtml('A <a ui-sref="login">login</a> link');
})
HTML
<div ng-bind-html="message"></div>
There is a working plunker
I would say, that we can use combination of:
$state.href() (doc here) and
ng-href (doc here)
(but only in case, if the params passed are part of url)
This would be the result
<a ng-href="{{$state.href(myStateName, myParams)}}">
And now (in the plunker) we can change myStateName into parent, parent.child, home and it will change properly the generated href:
<input ng-model="myStateName" />
<input ng-model="myParams.param" />
Because these are states in plunker
$stateProvider
.state('home', {
url: "/home",
...
})
.state('parent', {
url: "/parent?param",
...
})
.state('parent.child', {
url: "/child",
...
Check it here

Removes hash when directing

First, the problem:
I have an overview of items, and I want to get directed to a detailpage when clicking on a item. So far so good, the path works and all, but somehow my code keeps directing and removes the hash of the link. My browser(google chrome) tells me "object not found then".
The routing code:
.when('/home/:category/', {
title: "Home",
name: "home",
templateUrl: './templates/frontend_home.php',
controller: "SearchListCtrl"
})
.when('/detail/:id', {
title: "Detailansicht",
name: "detail",
controller: "DetailController",
templateUrl: "./templates/frontend_detail.php"
})
I have an ng-repeat of <tr>, which link to the detailview like:
<tr ng-repeat="data in responseData | limitTo:limit" ng-click="showDetail(data.id)">
And the code in the SearchListCtrl:
$scope.showDetail = function(detailId){
console.log("showDetail");
$location.path('/detail/' + detailId);
}
The DetailController:
lmsApp.controller('DetailController', function ($scope, $routeParams, $http){
$scope.$on("$routeChangeSuccess", function(evt, absNewUrl, absOldUrl){
console.log(absOldUrl);
console.log(absNewUrl);
});
var ajax=$http.post("./includes/ajax_getDetailInformation.php", {"id": $routeParams["id"]});
ajax.success(function(data, status, headers, config) {
$scope.object=data[0];
});
ajax.error(function(data, status, headers, config){
console.log("Ajax failed");
});
});
So, first the link is like:
http://localhost/Diplomarbeit/lms_project/#/detail/168?query=violine
And than gets (automatically) to something like:
http://localhost/Diplomarbeit/lms_project/detail/168
I have tried to remove the search query with $location.url($location.path()); before changing the path already, but it doesn't make changes.
I can see the first(working) link in the history, but why does it keep redirecting?
I would appreciate every answer.
Greets,
Force0234

Click list item, page transits but details page shows only no item details except for ()

Currently, main list html works
<div class="post row" ng-repeat="(postId, post) in posts">
{{ post.title }}
But when I click the item (one of the many in the list) and go to another page, the new page does not display the item in detail?
When I add the line below, including $stateParams in the dependencies, into the controller js file, {{ post.title }} appears but the data does not pass through.
$scope.post = $scope.posts[$stateParams.id]
UPDATE
This is the states code. (ignore missing syntax...im shortening it). Someone helped resolved the previous issue and provided the below codes for the viewing part (the last 2 states).
.state('tab.view', {
url: '/posts/:postId',
views: {
'tab-view': {
templateUrl: 'templates/tab-showpost.html',
controller: 'PostViewCtrl'
How the details are access after clicking on the list item.
app.controller('PostViewCtrl', function ($scope, $stateParams, Post) {
$scope.Post = Post.find($stateParams.postId); //i think this may be broken
One key piece that is missing in your question is how your stateProvider is configured. Please ensure that your states have the url set up correctly to send data though state parameters. I have a codepen here that shows one way to to have a list of items where clicking on one will take the user to it's details. Note how the states are set up...
angular.module('ionicApp', ['ionic'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('tabs', {
url: "/tab",
abstract: true,
templateUrl: "tabs.html"
})
.state('tabs.home', {
url: "/home",
views: {
'home-tab': {
templateUrl: "home.html",
controller: 'HomeTabCtrl'
}
}
})
.state('tabs.detailview', {
url: "/detailview/:index", //NOTE: :index is how you use $stateParams later on.
views: {
'home-tab': {
templateUrl: "detailview.html",
controller: 'DetailviewTabCtrl'
}
}
});
$urlRouterProvider.otherwise("/tab/home");
});
Then, in your controller...
.controller('DetailviewTabCtrl', function($scope,$stateParams) {
$scope.id = parseInt($stateParams.index);//NOTE: This is the same 'index'
$scope.previous = parseInt($stateParams.index) - 1;
$scope.next = parseInt($stateParams.index) + 1;
});
I don't know what {{post.url}} is in the ng-repeat; but I think you need a different $state that should handle the detail View.
Do something like:
<div class="post row" ng-repeat="(postId, post) in posts">
<a ui-sref="postDetail({id:post.id })">{{ post.title }}</a>
</div>
You then need a state definition in your app config's $stateProvider like this:
.state('postDetail', {
url: "/post/:id",
//NOTE: :id will be accessed from the controller using $stateParams later on.
templateUrl: "post_detail.html",
controller: 'PostDetailCtrl'
}) ...
That should do it.

GET requests with submit forms using angularjs

So after learning a bit of AngularJS I was able to get a controller to call an API and store the results in a variable, which is then displayed on my page (whew...). If I go to:
http://127.0.0.1:3000/#/search
I see the page with the submit form but without the results, and if I go to:
http://127.0.0.1:3000/#/search?query=deep&learning
I see the page with the submit form + the results for the "deep & learning" query. The problem is: I have to enter "?query=deep?learning" manually, I'm unable to use the submit form to get there. I use this code:
<form name='input' action='#search' method='get'>
<div class='input-group'>
<input type='text'
class='form-control'
placeholder='Enter query.'
name='query'>
<div class='input-group-btn'>
<button class='btn btn-default' type='submit'><i class='fa fa-search'></i></button>
</div>
</div>
</form>
With this submit form, if I enter "deep & learning" in the form, I get to
http://127.0.0.1:3000/?query=deep&learning#/search
How do I change my code so entering "deep & learning" would get me to:
http://127.0.0.1:3000/#/search?query=deep&learning
?
Thank you
UPDATE1: code for routes:
var myApp = angular.module('myApp', ['ngRoute'])
.factory('myQuery', ['$http', function($http) {
var doRequest = function(query) {
return $http({
method: 'GET',
url: 'http://127.0.0.1:3000/api/v0/docs?search=' + query
});
};
return {
results: function(query) { return doRequest(query); }
};
}]);
myApp.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl : 'pages/home.html',
controller : 'mainController'
})
.when('/search', {
templateUrl : 'pages/search.html',
controller : 'searchController'
});
});
myApp.controller('mainController', function($scope) {
// ...
});
myApp.controller('searchController', ['$scope', '$routeParams', 'myQuery', function($scope, $routeParams, myQuery) {
myQuery.results($routeParams.query)
.success(function(data, status, headers) {
$scope.count = data.count;
$scope.results = data.results;
});
}]);
It should simply a matter of changing the action attribute value to get the URL format you want.
In other words:
<form name='input' action='search' method='get'>
Note that the destination URI is no longer prefixed with a hash.
When it is prefixed with a hash as you have it at the moment, it's actually equivalent to directing the submission to the root (i.e. '/') using search as the page anchor.

Categories

Resources