0

In our app, we are serving static angular app files out of foobar.com/public/angular. The home page (foobar.com) is configured to serve foobar.com/public/angular/index.html. Thus, in our index file's <head>, we have:

<base href="http://foobar.com/public/angular">

However, during development, we use foobar.com/debug, which causes the server to use this instead:

<base href="http://foobar.com/public/angular-debug">

The server returns unprocessed (not minified, uglified, etc) versions of the files from this url. We are also using angular-route for our views.

TLDR:

  • We have a production route: foobar.com
  • We have a dev route: foobar.com/debug
  • We have a base tag: <base href="http://foobar.com/public/whatever">
  • We are using hash-bang urls for angular routes

The trouble is generating urls on the client side. As discussed in comments, <a href="#/new/route">Click here</a> does not work because the resulting url contains the base tag, which the server rejects and looks odd since the user starts somewhere else: foobar.com/public/angular/#/myRoute). The best I could think of to create the desired url was this:

  /**
   * Returns current url after replacing everything after the hashbang with a new string.
   *
   * @param {string} s - string to change route with (e.g. 'asdf')
   * @return {string}  - new url e.g. http://google.com/foobar/#!/asdf
   */
   makeRouteUrl = function(s) {
    var root = $location.absUrl().match(/.*#!/);
    if (root && (root.length > 0)) {
      root = root[0];
      return( root + s );
    } else {
      // no hashbang in path? Choose home page (not intended use)
      return "/";
    }
  }

However, this just seems a little gross. Is there a function in angular that makes the above function unnecessary? I have looked for functions in $location, $route, etc., but nothing seems to handle our complex setup correctly. We need to ultimately get the url as a string, not navigate (we are supporting open in new tab, so need to used ng-href). Since Angular apps often use hashbang urls for routing, I figured there must be something that allows you the just change the route after the hashbang while still preserving what's in front of it.

6
  • Not 100% clear where the problem exists. Is it only in opening a new tab ( ie target="_blank")? Commented Feb 24, 2015 at 23:17
  • @charlietfl sorry for lack of clarity -- I edited the question. In essence, the problem is that <a href="#/new/route">Click here</a> does not work elegantly due to the base tag (it works as the spec says it should, but extra routing code would need to be added to server to handle changed url) Commented Feb 25, 2015 at 15:29
  • I don't get it. Anything with hash in it will be handled by angular routing and will all be relative to application entry point regardless of which directory it is served from. Also shouldn't even need a base tag if not using html5 mode Commented Feb 25, 2015 at 15:34
  • @charlietfl Sorry, you replied before I could edit my comment. Hopefully it's clear. We don't want to use HTML5 mode at the moment. Commented Feb 25, 2015 at 15:36
  • right, so base isn't even needed. All the angular routing is relative so I can't see where problems occur unless you are having server mod rewrite problems Commented Feb 25, 2015 at 15:38

2 Answers 2

2

I'm not entirely sure if I understand the problem...

$location.url('/stuff/after/hash?params=hey');

Or if you only want to set the path after #:

$location.path('/stuff/after/hash');

Is what I usually use. But you need to return the url without hash after this? How about

window.location.origin + window.location.pathname

For the current url without hashes and parameters?

Sign up to request clarification or add additional context in comments.

4 Comments

I basically need $location.path('/stuff/after/hash');, except I need to get the URL as a string -- this method causes the browser to immediately navigate to another page (because I want to put the url in an <a> tag)
And you cannot use <a href="#/this/be/my/new/route/son">Click here</a> ?
It almost works, except the server doesn't recognize the route and it comes out ugly because of the base tag (result is foobar.com/public/angular/#/the/route -- the public/angular is the part that shouldn't be there).
Ok... And you need the base tag set to public/angular because of other non-angular things?
1

Have you considered using the UI Router library?

In general, it's excellent.

Specific to your question, the UrlMatcher service provides a method format that- unless I'm misunderstanding what you're asking- does what you're trying to do.

new UrlMatcher('/your/route/here').format(optionalNamedParameters);
// returns a formatted URL

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.