AngularJS - How to get serverside and clientside routing to work together - javascript

Im working on porting a project over to an angular based SPA. Its currently a more "traditional" node/locomotivejs app that serves up templates from the server side (never known the proper term for this).
The projects too large to to migrate all at once, so we are converting it to angular a page at a time.
My problem: if you load the angular part of the app, everything works fine. You can go to the angular routes correctly. However if you then go to a non-angular route (that should be handled serverside), then nothing loads (the ng-view goes blank, rather than a whole new template being loaded up). If you go to a serverside route first or hit refresh, the page loads correctly.
My guess is that angular is trying to handle these routes, and i am unsure how to get it to let the server take back over.
app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.when('/something/page1', {
templateUrl: '/page1.html',
controller: 'page1Ctrl'
});
$routeProvider.when('/something/page1/subpage', {
templateUrl: '/subpage.html',
controller: 'subpageCtrl'
});
}]);
this is my angular routeProvider. No "otherwise" specified. Serverside I have something like:
this.match( '/someOtherPage', 'someOtherPage#showstuff');
If i go to /someOtherPage directly, it loads correctly from the serverside. If i go to /something/page1, then go to /someOtherPage, it does not seem to contact the server.

Because you are using angular html 5 mode angular cannot tell the difference between a route that you want angular to handle, and one you don't. I think you need to tell angular to ignore certain routes. Looks like this is what you are looking for:
https://docs.angularjs.org/guide/$location#html-link-rewriting
So change your links to non-angular pages to use a target.
ex. link

Related

how I can change URL on page refresh angular js

let's say initially I am on page which has URL like "www.example.com/check/checkid now when I refresh page I want the URL to be changed how I can do that in angular Js .
You can use $routeProvider, which is the provider of the $route service. This service makes it easy to wire together controllers, view templates, and the current URL location in the browser.
I hope It will help.
http://viralpatel.net/blogs/angularjs-routing-and-views-tutorial-with-example/
Maybe you can add a run block to do that, for example:
angular.module("myApp", [])
.run(['$location', function($location) {
// some logic
$location.path("/somepath");
}]);

Integrating login Authentication module with existing Angular JS application

I have purchases an Angular JS theme and started developing our application. The $routeProvider of that app looks like this:
$routeProvider
.when('/', {
redirectTo: '/dashboard'
})
.when('/:page', {
templateUrl: function($routeParams) {
return 'views/'+ $routeParams.page +'.html';
},
controller: 'PageViewController'
})
.when('/:page/:child*', {
templateUrl: function($routeParams) {
return 'views/'+ $routeParams.page + '/' + $routeParams.child + '.html';
},
controller: 'PageViewController'
})
.otherwise({
redirectTo: '/dashboard'
});
It is a single page Application
Now I need to integrate login authentication module to it. I'm relatively new to AngularJS. I searched and got lot of articles about login, authentication modules for AngularJS application (few good answers in stack overflow as well) , which I could understand how it works.
But I'm not knowing how to make login work together with the existing application. Either having by having 2 different apps (one for login-authentication, and one for main app) or integrating login as separate angular.module in the main app. Please guide me how should I do...
All the examples have only 2 or 3 items in the $routeProvider including login and logout and the main app page. But in this case, main app page itself has many route providers.
I think I have some basic disconnect here. Please help me understanding the disconnect and integrating login-authentication with the existing application.
I don't know what more code components to add. Will share additional code if required.
Thank you.
I think that it could be a long answer if you are searching for a complete solution. What I could say quickly is that, in my opinion, you have to:
create a login page and put it in views folder
create a specific login Controller
add a route to login page before ':/page' route that uses the login Controller you just created
if your application require authentication, you have to edit PageViewController in order to redirect to login page if the current user is not logged yet.
As I said, it's a quick answer in order to the big work you have to do, but I hope you found this useful.
Bye

AngularJS html5mode and hard 404

I have a AngularJS app working with html5mode set to true.
Currently, the app shows a soft 404 page, with the .otherwise setting in the router.
Is there a way I could serve actual 404 HTTP response, for the sake of SEO while using html5mode?
If I understand correctly what you want, you have to do the following:
hard redirect the browser (bypassing the angular routing) on the otherwise path, with something like this:
$routeProvider
.otherwise({
controller: function () {
window.location.replace('/404'); // your custom 404 page
// or a non existing page
}
});
if you have a regular single-page-application where all the server request are redirected to the same SPA entry point, you have to configure on your server to make a routing exception for your custom 404 page, which will should also be served with a 404 status.
Otherwise, I can't see how you would do that with just History API, without an external request, because it's whole point in angular routing is to bypass external requests.
If you just want non-existing routes to return 404, then you must configure your server to match all your angular routes, and return 404 otherwise.
Seach engines works with SPA applications through prerendered pages, using _escaped_fragment_ . And you can use Prerender.io (or simply PhantomJS) to generate any status codes for search engines, like this https://prerender.io/documentation/best-practices
But this schema is deprecated by Google: http://googlewebmastercentral.blogspot.ru/2015/10/deprecating-our-ajax-crawling-scheme.html At this moment Google tries to understand your JS with usual crawling schema.
Hard redirection to 404.html page is not a good practice: url must stay the same, like https://stackoverflow.com/somepage
You can try Angular2 with server rendering feature: https://docs.google.com/document/d/1q6g9UlmEZDXgrkY88AJZ6MUrUxcnwhBGS0EXbVlYicY/edit
You have to make your server issue 404s. Angular cannot help in anyway here.

Adal.js not triggering the authentication

I am trying to integrate adal.js in my application. Below is my Code. Could someon please let me know why the authentication is not triggered.
var app = angular.module('TestWebApp', [
'ngRoute',
'testControllers',
'testServices',
'datatables',
'AdalAngular'
]);
/**
* Configure the Routes
*/
app.config(['$routeProvider', '$httpProvider', 'adalAuthenticationServiceProvider', function ($routeProvider, $httpProvider, adalAuthenticationServiceProvider) {
$routeProvider
// Home
.when("/dashboard", {templateUrl: "partials/package.html", controller: "searchCtrl",requireADLogin: true})
// else 404
.otherwise("/404", {templateUrl: "partials/404.html", controller: "searchCtrl"});
adalAuthenticationServiceProvider.init(
{
tenant: 'test.onmicrosoft.com',
clientId: '23234sf-sdf-------'
},
$httpProvider
);
}]);
And my page url is something link this.
http://localhost:8081/test-ui/#/dashboard
This should go to the Azure login page but its not going.
I think that your tenantID is probably right - it needs to be whatever your AD portal had for the app id URI(minus the name of the application) inside your azure portal. I would also look at the manifest - This is a pretty big deal to have changed. The steps are on the page Omar linked. The SinglePageApp example is a great resource in starting out, and the example is clean, if maybe a bit trivial for the adal portion. You should also check outvittorio's excellent deep dive for a good explanation and great review of adal.js
For me the problem was that I had a login button with a form that was redirecting because of action="#" and so the Azure redirecting was not working.
I just removed the whole action-attribute and it worked
Your issue: I think you have an issue with the link. Your link should be like this:http://localhost:8081/test-ui#/dashboard
Home
ToDo List
Contact List
Adal.Js uses requireADLogin keyword to interrupt the route change event. If you don't see any redirection, it could be related to the routechange event not firing. I suggest to add different routes to your app to verify angular routes first.
General guideline: You can try the sample app first to see if your configurations is working.
Sample app:https://github.com/AzureADSamples/SinglePageApp-DotNet
If you have an issue with config, you can follow the steps in the ReadMe file to setup your app config.
If sample app works for your config and your app is having issues, you can see the calls with Fiddler and further debug into adal.js as well. Login redirect event also broadcasts adal:loginRedirect.

Angular - UI Router Routes - HTML5 Mode

I'm trying to use HTML5 push state links with my Angular app. What I have is a series of routes similar to the following
$stateProvider.state('product', {
url: '/product/:productCode',
templateUrl: 'product/product.html',
controller: 'ProductCtrl'
}
});
This works when I navigate to [host]/#/product/ABC123 - It displays the url in the browser as /product/ABC123, then when I start clicking through to my other routes (using ui-sref) everything works as expected.
However - I'd like the ability to both refresh the browser, and remain in the same state, as well as be able to copy and paste that link and route to the right state.
eg. If I got to [host]/product/ABC123 - I want to display the content from the #/product/ABC123 route. Currently, this will give me a not found.
I'm using nginx as my app server. I believe I'll have to add something to handle it at that level, but I'm not sure where to start.
The issue you have is that your server does not know how to respond to /product/ABC123.
I am currently using node.js for my backend with angular, and to solve this I return the angular app for all routes, not just the usual root route for example.
So you might have used something like this in the past:
app.get('/', ...);
Which would have returned the angular app just for the root route. Now I use something like:
app.get('*', ...);
Which will return the angular app for all routes.
I should have mentioned that this can act as a catch all placed after other routes such as for static files. Another alternative is to mark all the routes you want specifically for the angular app, eg:
app.get('/', ...); app.get('/product/:productId', ...); etc

Categories