AngularJS and ExpressJS routing conflicts - angularjs

I am trying to pass an index value, for an array, into a route, so I can use the id to load a specific object into a detail view.
Controller that injects the index and changes path
location.path('/detail/'+index);
$routeProvider that handles the detail routing
.when('/detail/:index', {
controller: DetailViewCtrl, templateUrl: 'partials/detail'
});
Express script that handles the partial loading
app.get('/partials/:partial', function(req, res) {
return res.render('partials/' + req.params['partial']);
};
If I pass in an index of 5 then I expect the URL to look like "localhost:3000/detail/5", and I do get that in my browser but the server returns a 404 error where is was trying to look for some weird URL "localhost:3000/detail/partials/detail." I have no clue where the "detail " that is added before the partial is coming from.
It would be nice to know what is happening behind the scenes and how to fix the problem. How can I pass custom variables in the route and not have express freak out?

Prepend the templateUrl with /:
.when('/detail/:index', {
controller: DetailViewCtrl,
templateUrl: '/partials/detail'
});
or insert the base tag under the HTML head element as in:
<base href="/" />

Related

Angular templateUrl not redirecting to MVC controller

So I am having an issue in setting up my angular routes.
Moving straight to the point, my angular routes defined don't hit my mvc controller and thus action methods.
The action method return partial views, which represent my templates.
Here is an image of my route configuration.
Here is an image of my controller actions.
I am sure I am missing something, but can't seem to figure out what.
This example helps you to understand better about $routeProvider and $locationProvider.
The only issue I see are relative links and templates not being properly loaded because of this.
from the docs regarding HTML5 mode
Be sure to check all relative links, images, scripts etc. You must either specify the url base in the head of your main html file () or you must use absolute urls (starting with /) everywhere because relative urls will be resolved to absolute urls using the initial absolute url of the document, which is often different from the root of the application.
In your case you can add a forward slash / in href attributes ($location.path does this automatically) and also to templateUrl when configuring routes. This avoids routes like example.com/tags/another and makes sure templates load properly.
Here's an example that works:
<div>
Home |
another |
tags/1
</div>
<div ng-view></div>
And
app.config(function($locationProvider, $routeProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
templateUrl: '/partials/template1.html',
controller: 'ctrl1'
})
.when('/tags/:tagId', {
templateUrl: '/partials/template2.html',
controller: 'ctrl2'
})
.when('/another', {
templateUrl: '/partials/template1.html',
controller: 'ctrl1'
})
.otherwise({ redirectTo: '/' });
});
If using Chrome you will need to run this from a server.
Well what worked for me was to remove the setting for the $locationProvider.html5Mode. As someone mentioned in another stack overflow post, here MVC5 and Angular.js routing - URLs not matching using the locationProvider in MVC seems to screw up the routing. I am still to investigate why exactly this happens, as all I thought it did was remove the '#' in the url, but seems like there's more to it

Angular UI router dynamically inject URL to html

I am trying to build a simple app, which goes the following way:
I have 2 menu items in the navbar: home and contact.
The home should be a unique URL only once from the server, at initialisation, read from a QR code (i got this covered, that is no problem to me) and the contact should always be the same.
I got the contact done in the following way:
$stateProvider.state('contact', {
url: '/contact',
templateUrl: 'src/views/contact.html',
controller: 'contactController'
})
The problem is with the home, which should keep the unique URL received by the server. How should i write the state for that one?
.state('home', {
url: '/:uid',
templateUrl: 'src/views/home.html',
})
Also, the home should keep it's unique url generated by the server after refresh and while navigating from contact to home.
In the HTML i would have something like
<a ui-sref="home({uid: --some dynamic uid?--})">Home</a>
this is the part which also requires help.
Set the home state to
.state('home', {
url: /{uid},
templateUrl: 'src/views/home.html',
})
and you could grab the parameters by injecting $stateParams into the controller. $stateParams.uid would return the parameters and store that in local storage or cookies.
Check this link out
https://github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service
UPDATE:
for example, this is the sample controller that is attached to the home page
app.controller('homeCtrl', function($stateParams) {
var id = $stateParams.uid; //this is how you retrieve the uid
});
by going to your home page e.g. http://www.example.com/abcd12345, the above $stateParams.uid would return abcd12345
Now to set the url. simply use ui-sref instead of href on the <a> tag. ui-router will automatically generate href for you.
e.g.
<a ui-sref="home({uid:'abcd12345'})">Home</a>
You have to create a custom provider and inject it into the config.
eg:- .config($stateProvider, $urlRouterProvider,yourprovider) .
I am not sure about this. But please check this way too..

Angular/Express Redirect Initial Route (localhost:3000)

Simple question.
I'm building an Express web application with two views/routes (controlled by Angular):
localhost:3000/#/join
localhost:3000/#/find
I want the initial "localhost:3000" to forward to "localhost:3000/#/join", but currently, the page only loads the generic static content and does not include the unique html partial content associated with the view.
I'm using the following code.
require('./app/routes.js')(app);
app.all('*', function(req, res){
res.redirect('/#/join');
});
The forwarding works correctly for all url (e.g. localhost:3000/blah, localhost:3000/blah2, etc.) -- except for the initial localhost:3000.
Any suggestions?
Figured out the answer. I just need to include an "otherwise" statement at the end of my Angular routeProvider.
var app = angular.module('meanMapApp', ['addCtrl', 'queryCtrl','ngRoute'])
.config(function($routeProvider){
$routeProvider.when('/join', {
controller: 'addCtrl',
templateUrl: 'partials/addForm.html',
}).when('/find', {
controller: 'queryCtrl',
templateUrl: 'partials/queryForm.html',
}).otherwise({redirectTo:'/join'})
});

Dynamic route request render not working, backend express

I want to try dynamic route request but It's not working properly. And here I explain my coding style step by step.
<nav class="main-nav" ng-show="global.user.user_type!='admin'" ng-repeat="mMenu in Mainmenu">
{{mMenu.MenuName}}
</nav>
This code contain URL link and It's load every time with a variable that is web address link. And the link is something like that - http://localhost/views/adminpanel/about.html
In AngularJS Controller contain the code -
$scope.geturl = function(url)
{
var params = {
url1 : '/views/adminpanel/'+url
}
$http({'method' : 'post', url : 'views/adminpanel/'+url, data: params
}).success(function(data)
{
}).
error(function(data){
})
}
configuring and using ngRoute -
when('/views/adminpanel/:url', {
controller: 'homeCntrl',
templateUrl: 'views/adminpanel/:url'
})
In server side (Express) :
Routing HTTP requests, Configuring middleware and Rendering HTML views
app.post('/views/adminpanel/:url',auth.requiresLogin, users.geturl);
exports.geturl= function(req,res)
{
var url = req.body.url1;
res.render(url);
}
This is all about my rendering process but It's not working. In browser It only shows the URL link but not shows any content. How can I solve It any idea?
I think you are confusing things:
first of all you have a link together with a ngClick: you should have either of those
your ngClick has an empty success function, so it does nothing with the template
you have a route set with express that matches with the ngRoute (btw, POST is usually used to create resources, you should GET the template)
your templateUrl is going to send a GET request to (literally) /views/adminpanel/:url, it does not replace :url
To fix it:
set a different endpoint for your APIs
use a GET endpoint instead of a POST
change the ngRoute to:
when('/views/adminpanel/:url', {
controller: 'homeCntrl',
templateUrl: function(param) {
return '/api/<path>/' + param.url;
}
})
remove the ngClick from the <a>

send parameter along url angularjs

I am working on project where my role is server-side programmer.Client side developer used Angular js while designing pages.
Problem I am facing is we have one page where I need to pass one parameter along with url to server
<a id="startQuiz" href="#/Quiz" >Start Quiz</a>
jquery code is
$('#startQuiz').click(function (e) {
e.preventDefault();
window.location.href = '#/Quiz/' + selectedTopic;
}
Controller code is
#RequestMapping(value="/Quiz", method = RequestMethod.GET)
public String Quiz(HttpServletRequest request,Model model,HttpServletResponse response,#RequestParam(value = "topic", required = false) String topic) throws Exception {
System.out.println("select topic : "+topic);
}
I am getting topic as null cause Nothing after the hash # sign is getting sent to the server, hence the null values
Rounting file Is
app.config(function($routeProvider){
$routeProvider
.when("/Quiz", {templateUrl: "Quiz", controller: "PageCtrl"})
});
So, What change should I make in routing so I can get value of topic in Controller
Any way to do that?
The URL of the page is not what matters here. That URL will only load the main page template.
What matters is the URL used to send the AJAX request to your backend controller.
The route should be defined as
$routeProvider
.when("/Quiz/:topicId", {
templateUrl: "Quiz",
controller: "PageCtrl"
})
Then, using the $routeParams service in the PageCtrl, you can get the value of topicId, and send the appropriate AJAX request to the backend.

Resources