Using $location service with non SPA - angularjs

I am trying to build a non SPA angularjs app. Routing from my server works fine but the problem I have encountered is that the $location service seems unable to understand my url. For example, if I have http://localhost:9000/test/item?id=abc123 and I call $location.search() in my controller, it returns an empty object. It appears as though angular always assumes there is a hash (#) in your url. I tried using the $locationProvider to turn on html5 mode and in this mode $location.search() will return an object with id=abc123 as expected. However, with html5 mode turned on, non of my links are hitting up the server for routing anymore. The url in the address bar gets changed but no server call is made.
So, how do you build a non SPA site with angular and still make use of the $location service for parsing query params. Is this possible or do I have to write my own url parser?
update: I am using angular 1.3.15

Related

Angular Router not updating browser URL when called from AngularJS

I have an AngularJS application, which I'm in the process of converting to a hybrid Angular/AngularJS application using ngUpgrade. The AngularJS application is unusual in that it doesn't use the AngularJS or Angular UI router - instead it has its own hand-rolled navigation solution, which doesn't update the URL displayed in the browser, or interact with the browser's history API. So far, so good.
I want to start using the Angular Router in the hybrid application, but initially only for new pages.
To get the 2 parts of the application - Angular and AngularJS - interoperating with each other, I have downgraded the Angular Router service and injected it into one of my AngularJS services, so that I can call Router.navigateByUrl() to navigate to a new Angular page component, from my AngularJS code.
This works correctly - the Angular page component is added to my <router-outlet> and is displayed in the browser as expected.
Strangely though, the browser URL does not change. When I enable tracing for the Router, I can see the new route being correctly processed, and the new page is displayed in the browser, but the browser URL still shows the old route. Also, if I look at the browser history, the new route has not been added to it.
I've tried injecting NgZone into my AngularJS service and calling Router.navigateByUrl() inside NgZone.run(), but it doesn't make any difference.
When I call Router.navigateByUrl() from my Angular code, everything works fine - except when I do this after I've done it from AngularJS, when I then see the same symptoms. It's as if calling the Router directly from AngularJS is somehow breaking the link between the route and the browser URL bar.
Can anyone help please...?
So the issue was that the AngularJS $location service wasn't being updated when the route changed, leaving a disparity between its value and the value being displayed in the browser. There was also a watch in this service which was being triggered in every digest cycle, that was then resetting the browser url from the value in the $location service!
Turns out this was because I needed to configure the Unified Angular Location Service in my AppModule viz:
imports: [
LocationUpgradeModule.config()
]
and downgrade the $locationShim service for injection into AngularJS viz:
angularJS.module('my-app')
.factory('$location', downgradeInjectable($locationShim));

http://localhost:3000/#!/ why do I get "#!/" in my localhost link.

I am using Angularjs to build a web app but I am getting http://localhost:3000/#!/ instead of http://localhost:3000/ when I go to my index page.
I couldn't figure out why it's happening.
Some help would be great.
The hashBang #! is usually added by angularjs between the url and the angular routes. You can disable it in the .config() using $locationProvider and setting the html5Mode to true like so :
.config('$locationProvider', function($locationProvider){
$locationProvider.html5Mode(true);
})
Using HTML5 mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html). Requiring a <base> tag is also important for this case, as it allows AngularJS to differentiate between the part of the url that is the application base and the path that should be handled by the application. For more information, see AngularJS Developer Guide - HTML5 Mode Server Side.

how to prevent $location in controller changing hash

The site is build in angularjs but the visualization is coded seperately not in angularjs.
When adding $location to the controller of the app, it changes the hash-part in the url from
app/#hashpart
to
app/#/hashpart
Is there a way to prevent this? The visualization is creating and interpreting the first version and when I call my_function (that builds my site and calls the visualization):
$scope.$on('$locationChangeSuccess', function(event) {
$scope.my_function(location.hash.substr(2));
});
then the browser switches between both hash-versions for eternety.
Use html5mode in angular js. This removes # from url.
You need to make changes at server that whenever any page is requested, always reply with index.html, otherwise 404 will be encountered. (search for url rewrite rules for your server)

Removing the hashtag from AngularJS when working with SailsJS

I'm getting really frustrated with configuring the Routing on our app, which is using sailsJS and angularJS.
The problem is, that the browser doesn't know about angular, so any request like /login returns a 404 Error from sails. I need a solution, to keep the sails routes from the angular ones,
One solution would be to disable html5Mode, but i really don't like the look of URLs with the /#/ which is typical for angular.
I have researched a lot on this and haven't yet found a good answer or maybe a working project for this.
Is what I am trying to do even possible right now?
If you're using HTML5 mode with Angular, then you need to configure your web server (in this case SailsJS) to respond with your index.html file for requests to /login or any arbitrary routes.
If you navigate directly to http://localhost:3000/login in your web browser (assuming you're running Sails on localhost:3000), Sails needs to respond with your index.html so that your Angular app can bootstrap and then display the appropriate route. Then, subsequent links that the user clicks on in your app will be intercepted directly by the Angular router instead of Sails directly.
Angular has documentation about making HTML5 mode work correctly here.
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html). Requiring a <base> tag is also important for this case, as it allows Angular to differentiate between the part of the url that is the application base and the path that should be handeled by the application.

Is there a way to prevent angular from redirecting #foo to #/foo?

I'm migrating an app to AngularJS, I want to do it in a modular way, just parts by parts. For now, the URLs are not to be handled by Angular. But when I use ng-include angular automatically starts rewriting the URL, for no reason, since ng-include got nothing to do with the URL.
So I'm trying to use an Angular module in a page with the website.com/#somethingAfterTheHash URL, and when I use ng-include, the URL turns into website.com/#/somethingAfterTheHash. And the app breaks.
Is there a way to stop Angular? Or will be better off trying to stop the app from breaking?
You can configure angular not to use it like this: $locationProvider.html5Mode(true). Read more about it here. The hashtag is used for older (non-HTML5) browsers.
To configure the $location service, retrieve the $locationProvider and set the parameters as follows:
html5Mode(mode): {boolean}
true - see HTML5 mode
false - see Hashbang mode
default: false

Resources