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.



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.


I would suggest defining a module that contains a global config that you can then pass around your application:

// Module specific configuration
  .value('app.config', {
    basePath: '/' // Set your base path here

Then you can access this from anywhere within your application thanks to AngularJS dependency injection:

// Make sure your config is included in your module
angular.module('app', ['app.config']);

// Access your config e.g. in a controller
  .controller('TestCtrl', ['$scope','app.config', function($scope, config){

    // Use config base path to assemble url
    $scope.url = config.basePath + 'GetUserList';

Whenever the base path changes (e.g. when you change to another server or host), you just need to change it in your global config and you're done.


I wasn't able to use <base> tag since my application was created in a popup dynamically from another origion. I was considering the others option in this thread to use something like a basePath variable and use it in every $http, ng-src, templateUrl etc

But that was a bit overhead, built a interceptor that change every url before a xhr is made

var app = angular.module("myApp", []);

app.config(["$httpProvider", function($httpProvider) {

app.factory('middleware', function() {
    return {
        request: function(config) {
            // need more controlling when there is more than 1 domain involved
            config.url = "//" + config.url
            return config;

app.controller("Ctrl", ["$http", function($http) {
    $http.get("books"); // actually requestUrl =

And html aswell

<div ng-include src="'view'">
    <!-- actually src = -->

But i do recommend to use <base> tag instead unless you are using window.popup()


Use the $location service - it will return your path, the hash, the server address.. Everything you need! Your call would be to $location.path()+"/GetUserList" or something similar.

See here:$location


A simple way, I'm using ASP.NET Razor (Web MVC), so I get the Application path and make it as the base of app.


<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="description" content="">
@{ var appPath = Request.ApplicationPath.ToString();
    if (!appPath.EndsWith("/")) {
        appPath = appPath + "/";
<base href="@appPath" />

I would just make all URL relative.

url: "../GetUserList",


url: "GetUserList",

Hard coding for the, <base href="/application_root/" /> dose not sound good idea to me as you might need to change this environment to environment, and has dependency over virtual directory name.


In the ng-init function pass a parameter that contains the value the virtual directory (int ASP.NET stored in Request.ApplicationPath).

<div ng-controller="ControllerName" ng-init="init('@Request.ApplicationPath')">

Inside the angular controller, use this value as prefix of URL in every http call. You can use this function to combine the paths

function combinePath(path1, path2) {
    if (path1 == null) {
        return path2;
    var last = path1.slice(-1);
    var first = path2.charAt(0);

    if (last == '/' && first == '/') {
        path1 = path1.substring(0, path1.length - 1);
    return path1 + path2;

I had a similar problem I solve it with the just one line of code in my MVC page

<base href="~/" />

The accepted answer helped me. I'm using Angular served up my an MVC app. I took one extra step so that my baseUrl could be used within my angular controllers for web api calls or for accessing templates.

Using ng-init to set the baseUrl (from a server side populated value)

<html ng-app="app" ng-controller="AppController">
    <base href="{{baseUrl}}" ng-init="baseUrl = '@Model.BaseUrl'" />

Angular controller

    $scope.manageCustomerGroups = function () {
        openDialog($scope.baseUrl + 'content/templates/customerGroups.html');


Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.