Removes hash when directing - javascript

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

Related

AngularJS not routing properly

I am learning Angular, so here is my testapp : http://enrolin.in/test/#/students
Now here I want to search the database by name. So I created the php that returns exactly what I need. Here is the php : http://enrolin.in/test/login.php?p=fetchbyname&&name=ak You have to replace name in the url to anything you need to search. I also created a partial page that returns absolutely correct results, here is the page: http://enrolin.in/test/#/studentSearch/ak Everything was fine till now But here is the problem:
When I try to search in http://enrolin.in/test/#/students , angularJS does not route me to something like http://enrolin.in/test/#/studentSearch/ak but instead to the default that I have set in $routeProvider
Here is my angularJS (I have removed some unimportant code):
The route provider:
.config(function ($routeProvider) {
$routeProvider
.when("/students/:id", {
templateUrl: "templates/studentDetails.html",
controller: "studentDetailsController"
})
.when("/studentSearch/:name", {
templateUrl: "templates/studentSearch.html",
controller: "studentSearchController"
})
.otherwise({
redirectTo: "/home"
})
})
The Controller that passes the link:
.controller("studentsController", function ($scope, $http, $route,$location) {
$scope.searchStudent=function(){
if($scope.name){
$location.url("/studentsSearch/" + $scope.name);
}
else{
$location.url("/studentsSearch/");
}
}
$scope.reloadData=function(){
$route.reload();
}
$http.get("http://enrolin.in/test/login.php?p=fetchall")
.then(function (response) {
$scope.students = response.data;
})
})
The controller that fetches data and displays:
.controller("studentSearchController", function ($scope, $http, $routeParams) {
if($routeParams.name)
{
$http({
url: "http://enrolin.in/test/login.php?p=fetchbyname&&name=",
method: "get",
params: { name: $routeParams.name }
}).then(function (response) {
$scope.studs = response.data;
})
}
else
{
$http.get("http://enrolin.in/test/login.php?p=fetchall")
.then(function (response) {
$scope.students = response.data;
})
}
})
Previously everytime I wanted to put a link in html to route I used to write like courses But now when I want to put it in the function instead, I am not sure what to write. Please Help.
Hi #AkhilEshKhajuria,
You are not using the same name what you have mentioned in the routing config. Routing name is "/studentSearch/:name?" but you have used in the function as "/studentsSearch/".
Please try replacing $location.url("/studentsSearch/" + $scope.name); with $location.path("/studentsSearch/" + $scope.name);
Correct the naming issue and it should work.
I tried this and it works fine.

Creating dynamic link for ng-repeat

I have a list of articles in this tableofcontent.html file, and they are all clickable links. This page works correctly, and is showing a list of all of the titles. When I click on the links though, it goes to the right template file, but none of the right data is populated in the article.html file. How do I get the data for each link to show up correctly in the articles.html page?
tableofcontent.html
<div class="row" ng-controller="TableofContentController">
// non relevant code removed
<ul>
<li ng-repeat="article in data">
<a ui-sref="article">{{article.title}}</a>
</li>
</ul>
article.html
<div class="row" ng-controller="ArticlesController">
// non relevant code removed
<h3>{{article.title}}</h3>
<h6>Author: {{article.author}} on {{article.date}}</h6>
<p>{{article.body}}</p>
//etc
app.js
// service to retrieve and share data
articleApp.factory('Data', function ($timeout, $http) {
var articles = {
fetch: function() {
return $timeout(function() {
return $http.get('articles.json')
.then(function(response) {
return response.data;
});
}, 30);
}
}
return articles;
});
articleApp.controller('TableofContentController', function ($scope, Data) {
Data.fetch().then(function(data) {
$scope.data = data;
});
});
articleApp.controller('ArticlesController', function ($scope, Data) {
Data.fetch().then(function(data) {
$scope.data = data;
});
});
also in app.js
// table of content state
.state('tableofcontent', {
url: '/index',
templateUrl: 'templates/tableofcontent.html'
})
// main articles page state
.state('article', {
url: '/{{article.title}}',
templateUrl: 'templates/articles.html',
controller: 'ArticlesController',
controllerAs: 'articles',
})
There are actually a bunch of issues here, what you want to do is, when someone clicks on the list of these links, instead of doing
<a ui-sref="article">{{article.title}}</a>
You probably want to do
<a ui-sref="article({id : article.id})">{{article.title}}</a>
Now that you are passing the id of the article, the modules state definition needs to be modified to accept this article id as follows.
.state('article', {
url: 'article/:id',
templateUrl: 'templates/articles.html',
controller: 'ArticlesController',
controllerAs: 'articles',
})
So now when you click on the articles, you should see a network request that looks like this : article/1234 where 1234 is the id of the selected article.
In this example you always seem to be loading the same article.json data, but when interacting with the server you can access the selected article id by using the $stateParams service which you can just inject into your controller.

ui-router activates 404 instead of requested state

I am using WordPress rest API and I have states in my AngularJS app as below:
.state('public.blog', {
abstract: true,
url: '/blog',
template: '<ui-view/>',
})
.state('public.blog.home', {
url: '/',
templateUrl: 'public/blog.html',
controller: 'PublicBlogCtrl',
controllerAs: 'vm',
})
.state('public.blog.post', {
url: '/:slug',
templateUrl: 'public/blog.post.html',
controller: 'PublicBlogPostCtrl',
controllerAs: 'vm',
})
And for example i have an article like 'http://example.com/blog/what-is-angularjs'. It's work fine when I clicking on a link in my application like this:
<a ui-sref="public.blog.post({ slug: post.slug })">
But the problem is when I writing the URL 'http://example.com/blog/what-is-angularjs' directly in browser address bar. When I do this, angular can't handle URL and recognize it as a wrong URL which doesn't match with any state, then it looks for $urlRouterProvider.otherwise('/404'); and shows my 404 - Not Found Page.
So whats the wrong?
UPD #1
When I send slug post's slug as parameter the issue occurs, but when I use post's ID to retrieve post, it's work fine. So I think some thing is wrong in wp-api's slug.
UPD #2
The controller looks like this:
function PublicBlogPostCtrl($scope, $stateParams, WPService) {
var vm = this;
WPService.getPost($stateParams.slug).success(function(res) {
$scope.post = res[0];
}).error(function(err) {
console.error(err);
});
}
app.controller('PublicBlogPostCtrl', PublicBlogPostCtrl);
And the WPService.getPost as below:
WPService.getPost = function(slug) {
return $http.get('wp-json/wp/v2/posts/?filter[name]=' + slug).success(function(res, status, headers) {
return res;
}).error(function(err) {
return err;
});
};
Could it be the url for blog posts? instead of /:slug, should it be /blog/:slug?
It would work from clicking on a link because you supply the state and slug directly instead of via a URL.

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

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.

Resolving data in Angular Controller

I'm pretty new to Angular and I've been going round in circles on this one for a while now.
A bit of background first, I'm using the MEAN stack from mean.io which uses Angular UI Router.
I have a Post model in my DB which can have a category id assigned to it.
When I create a new post I want to load the existing categories from the DB and display them in a select box.
From what I can see I need to use resolve, first of all it doesn't feel right having logic in the resolve property which is in a file called config.js - so far I've placed the call to a service in there and im getting the categories back using the following code:
.state('create post', {
url: '/posts/create',
templateUrl: 'views/posts/create.html',
controller: 'PostsController',
resolve: {
loadCategories: function (Categories) {
Categories.query(function(categories) {
return categories;
});
}
}
})
The first problem is that I can't access the returned data in my controller or view.
Secondly I only want to load Categories that belong to a certain Organisation. I will be assigning an organisation id to each user so how can I access the currently signed in user when I'm in config.js - again this doesn't feel like the right place to be doing this sort of logic though.
Any help would be really appreciated.
Thanks
config.js:
register post state :
.state('post', {
url: '/posts/create',
templateUrl: 'views/posts/create.html',
controller: 'PostsController',
resolve: PostsController.resolve
})
register posts controller:
.controller({
PostsController: ['$scope', 'loadCategories', PostsController],
...
})
controller function:
function PostsController($scope, loadCategories){
$scope.categories = loadCategories;
};
PostsController.resolve = {
loadCategories: ['dependencies', function(dependencies){
return dependencies.query(...)
}]
};
Angular manage your dependency injection
Assuming Categories is an angular resource, you should be able to just
loadCategories: function (Categories) {
return Categories.query();
}
And then in your controller:
.controller('PostsController', function ($scope, loadCategories) {
$scope.categories = loadCategories;
});
Ok, reading your comments, it sounds like you'll have some issue because you want to inject this into the controller, but only in certain states. You could try:
.state('create post', {
url: '/posts/create',
templateUrl: 'views/posts/create.html',
controller: 'PostsController',
data: {
categories: Categories.query()
}
})
and then
.controller('PostsController', function ($scope, $state){
console.log($state.current.data.categories);
});
Which should work...

Categories

Resources