history.pushState on sub pages in an Angular.js application - angularjs

I have a blank Angular.js 6 application that uses PathLocationStrategy for routing, and when on a subroute (e.g. /test) and executing the following:
history.pushState({}, '', '#abc');
window.dispatchEvent(new HashChangeEvent('hashchange'));
I would expect the URL to be changed to /test#abc but instead changes the page and URL to the home page (/#abc).
This can be fixed by pretending with the base URL, for example:
history.pushState({}, '', (new URL(window.location.href)).pathname + '#abc');
Unfortunately, I don't have control over the history.pushState command in this case as it's executed externally from ads.
I also tried this in a new Angular 15 application, where similarly the URL updates to /#abc instead of /test#abc but the page didn't change.
However, in for example a new Nuxt.js app, it behaves as expected and stays on the test page and the URL becomes /test#abc. So it seems to be perhaps related to Angular.js.
Does anyone know how I can configure my Angular application so it stays on sub-pages when executing:
history.pushState({}, '', '#abc');
window.dispatchEvent(new HashChangeEvent('hashchange'));
Thanks!

Fixed it by doing the following:
Removed the <base href="/"> element in file src/index.html
Added provider { provide: APP_BASE_HREF, useValue: '/' } in file src/app/app.module.ts
Added "deployUrl": "/" to the build configuration in file angular.json

Related

How to do serverside HTML5 mode URL Rewriting with NodeJS and browserSync

How to remove #! getting added to url in my AngularJS application?
I have tried:- $locationProvider.html5Mode(true).hashPrefix('!'); and adding <base href="/"> but to no avail. When I navigate to a particular url, #! disappears but when I tried to reload, it gives the error:- Cannot GET.
So I looked online, and found out that doing above is only half of the solution. We also need to rewrite the logic on server side as well. So I am using NodeJS and browserSync package to fire up localhost. So what is the solutioin to this?
Note:- My backend and frontend code are separate and both handle routing.
There is a option in Browsersync called single which serves the index.html as a fallback if the url does not exist.
Serve an index.html file for all non-asset routes. Useful when using client-routers
See documentation:
https://www.browsersync.io/docs/options#option-single
browserSync.init({
server: {
baseDir: 'dist',
},
single: true
});

Angularjs app refresh with tomcat going to 404 page

I have deployed angular app in tomcat7.
What did :
1 Made angular app as an html5 mode to true by adding fallowing code in app.js
if (window.history && window.history.pushState) {
$locationProvider.html5Mode(true);
};
2. Added `<base href="/dist/#/">` in index.html
2. Build the app by using grunt `grunt build`
3. Kept the dist into the folder `TOMCAT_HOME/webapp/ROOT`
Problem :
1. When i refresh the page it show 404
2. When I copy the URL and paste then also it's giving 404 error.
3. Provide me link for tomcat configurations
Note : If i hit the browser with Host/dist app is running (if i navigate state by state).
Please help me where i did mistake. And how to resolve it (with tomcat sever configuration if required).
URL's I fallowed :
Deploy AngularJS app on tomcat
http://diveintohtml5.info/examples/history/fer.html
Removing the fragment identifier from AngularJS urls (# symbol)
Not sure if you are still looking for the answer, but I will share my solution in case anyone needs it.
What I did was basically use http://tuckey.org/urlrewrite/
and set the rule as
<rule>
<from>^/search/$</from>
<to>index.html</to>
</rule>
I want to point out that I used the actual file name instead of the url I want to go.
Hope this helps!
Regards,
Berkan

Serve up web files from different directory - Error 400 Bad Request

I have an MVC app that uses AngularJS. I am in the process of organizing the folder structure to be feature based rather than type based.
An example folder structure is now
App (Folder within main project, at same level as Views)
Assets
CSS
JS
Pages
Home
home.js
home.tests.js
home.html
About (etc)
Now the problem is that when ui-router tries to load home.html the web server throws a 400 error. If I go to the file manually in the browser it works. What is the problem here? Why can I not serve files up from this directory. Note that I actually right click the 400 message in the console and choose open in new tab. So I know the file I am looking at is the URL being requested from AngularJS
Here is my ui-router setup
.state('home', {
url: '/home',
templateUrl: '/app/pages/home/home.html',
controller: 'mainPageController'
})
Note:
I serve up a .js file from the same directory which seems to work fine!
I had the exact same problem and it was caused by another developer trying to fix an IE caching bug.
I found the solution here by Ben Cull: https://stackoverflow.com/a/30014936/710268.
//initialize get if not there
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
//disable IE ajax request caching
$httpProvider.defaults.headers.get["If-Modified-Since"] = "Fri, 01 Jan 2010 00:00:00 GMT";
My problem was that the "If-Modified-Since" header was set to '0' and for some reason that was causing html template files to not load.
By default the router is going to start at the top level of your MVC project (i.e. where your Views and App folder sit) and not the folder where your JavaScript is served from.
So in Angular your templateUrl needs to be App/Pages/Home/home.html.
So in your angular router configuration have the property:
templateUrl: 'App/Pages/Home/home.html'

AngularJS and PhoneGap: $location.path causes subsequent tempateUrl lookup to fail

I'm having trouble getting path lookup to work with a AngularJS v1.2.0 and PhoneGap/Cordova Android application. I've come pretty far with html5mode(true) by setting <base href="."/> in index.html and then changing $routeProvider.when('/') to $routeProvider.when('/android_asset/www/index.html'). After that I am able to get redirectTo('login') to reach $routeProvider.when('/login') and there render templateUrl: 'static/partials/login.html' as expected.
The problem I have is that if I instead try to redirect to the login page from my Javascript code with $location.path('/login');, the route is found but templateUrl loading fails with an insecurl exception.
I've tried whitelisting access to file:// by using the new angular-sanitize module, but that does not help.
How can I make $location.path() do the same things as redirectTo so that the partial is loaded? Or is there some other way to solve this problem?
UPDATE: I got a bit forward by adding a call to replace() after the path function, e.g.:
$location.path('/login').replace();
but that seems like a hack, and it still causes the templateUrl in the otherwise route to fail with the same exception.
Any ideas on what might be wrong? Is it that html5mode(true) just does not work at this moment with Phonegap and the only way to fix this is to set it to false and add hashtags to every path (like is done in the angular phonegap seed project)?
For future reference, this is how I managed to solve the problem:
AngularJS currently does not seem to support html5mode(true) inside a Cordova application because of the insecurl problem I reported. What I had to do is add
var h5m = (typeof html5Mode !== 'undefined') ? html5Mode : true;
$locationProvider.html5Mode(h5m);
which gives me the possibility to explicitly set html5Mode in the PhoneGap index.html with a global variable:
<script>
var html5Mode = false;
</script>
So now $location.path('/login') as well as redirectTo: 'login' works, but links in html files, don't. To get those working in PhoneGap, with html5Mode disabled, I had to add #/ in front of every link, e.g. login.
That makes PhoneGap work, but breaks the web page which uses History API with html5Mode(true). The last piece of the puzzle was to add <base href="/"/> to the web page's index.html (and leave it out of the index.html of the PhoneGap project.) So now even though I have a link that says #/login in the web page, I get to the url http://example.com/login and don't see any hashes in the address bar.
**
So in the end I have History API working in my web page and History API disabled in the PhoneGap project (where there really is no need for History API as there is no address bar). The only downside is the extra #/ I have to put in each template html file, but that is a minor annoyance compared to the ability to use all of the same html and javascript files for both web and mobile.
I had this same problem as well. I managed to fix it by skipping the leading slash in the route config:
$routeProvider
// route for the foo page
.when('/foo', {
templateUrl: 'foo.html', //previously: '/foo.html'
controller: 'fooController'
}) //etc.

Running an Backbone app as an independent JS application - Routes not working

currently, I run backbone as the front-end of my rails 3.2 application. I need to migrate it into an independent JS application, as part of my putting it as part of Trigger.io.
It now exists as its own index.html file, referencing the assets folder.
When I open the file, it loads the Backbone modules, but the page remains empty. And when I run fetch() commands, it
So, I got a couple of qns:
1) How do I trigger the routes such that it goes to a designated page by default?
I know it gets triggered in Backbone.History.Start, but I am not sure what to do before that.
2) The url is "file://localhost/Users/mingyeow/Desktop/index.html"
How do I set the root url manually to use localhost:3000/my web address?
// define router
var Router = Backbone.Router.extend({
routes : {
'index' : 'indexAction',
'*default' : '_defaultAction'
},
indexAction : function() {
// this will be executed when user navigate to #index
},
_defaultAction : function() {
// this will be executed when user navigate anywhere else (#XXX)
}
});
// on document ready
$(function() {
// initialize router
new Router();
// and start history
Backbone.history.start();
});
You can navigate this way.
Or by clicking the link : Index route
You can use python server. To start it type in the Terminal:
$ python -m SimpleHTTPServer
And check http://localhost:8000
1) To trigger a route change you just need to navigate to a page via a href or JavaScript like window.location. Read up on Backbone Routes but essentially you need to write a function for every 'page'. Each function should take care of rendering the page.
2) This should be very simple. You need a local web server. What I started doing recently is just having a simple Node server. Node is very easy to install and its worth experimenting with. Download a static web server such as this one I made. To use it just put your backbone application in a directory named 'public' and run server.js in node.
If you don't want to do this you can run a simple LAMP/WAMP/MAMP installation and set the root of the Apache web server.

Resources