Phil Sandler Phil Sandler - 11 months ago 101
AngularJS Question

Using a Relative Path for a Service Call in AngularJS

I have the following code, which was working fine until I deployed to a test server:

$scope.getUserList = function (userName) {
method: "get",
url: "GetUserList",
params: { userName: userName }
success(function (data) {
$scope.users = data;
error(function () {
alert("Error getting users.");

The problem is that I deployed to a virtual directory, and the call below is attempting to hit GetUserList from the server root. This makes sense, and I know a number of ways to fix it.

What I would like to know is the right way to reference the service URL in a way that is portable and maintainable in Angular.

Answer Source

I'd suggest using an HTML base tag in the head, and coding all paths relative to this. In ASP.NET, for example, you can get a reference to the base of the application, which may or may not be the root path of the site, so using a base tag helps. Bonus: it works for every other asset too.

You can have a base path like this:

<base href="/application_root/" />

...and then links like "foo/bar.html" will actually be /application_root/foo/bar.html.

Another approach I like to use is to put named links in the header. I will often have an API root in one location and a directive template root somewhere else. In the head, I'll then add some tags like this:

<link id="linkApiRoot" href="/application_root/api/"/>
<link id="linkTemplateRoot" href="/application_root/Content/Templates/"/>

... and then use $provide in the module to get the link href and expose it to services and directives like so:

angular.module("", [])
    .config(["$provide", function ($provide) {
        $provide.value("apiRoot", $("#linkApiRoot").attr("href"));

... and then inject it to a service like this:

angular.module("").factory("myAdminSvc", ["apiRoot", function (apiRoot) {
    var apiAdminRoot = apiRoot + "admin/";

Just my opinion though. Do the least complex thing for your application.