Using relative path to call a service in AngularJS

I have the following code that worked fine until I deployed to a test server:

$scope.getUserList = function (userName) { $http({ 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 tries to get to GetUserList from the server root. It makes sense, and I know several ways to fix it.

What I would like to know is the correct way to reference the service url in such a way that it is portable and supported in Angular.

+65
javascript angularjs
Jun 09 '13 at 16:19
source share
9 answers

I would suggest using the basic HTML tag in the head and encode all the paths regarding this. For example, in ASP.NET you can get a link to the application database, which may or may not be the root path for the site, so it’s useful to use the base tag. Bonus: it works for all other assets.

You can have a base path as follows:

 <base href="/application_root/" /> 

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

Another approach that I like to use is to put named links in the header. I will often have the root of the API in one place and the root of the directive template somewhere else. I will add the following tags first:

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

... and then use $ provision in the module to get the href link and set it to services and directives as follows:

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

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

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

Just my opinion. Do the least difficult thing for your application.

+100
Jun 09 '13 at 19:39
source share
— -

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

 // Module specific configuration angular.module('app.config') .value('app.config', { basePath: '/' // Set your base path here }); 

You can then access this from anywhere in your application thanks to AngularJS dependency injection:

 // Make sure your config is included in your module angular.module('app', ['app.config']); // Access your config eg in a controller angular.module('app') .controller('TestCtrl', ['$scope','app.config', function($scope, config){ // Use config base path to assemble url $scope.url = config.basePath + 'GetUserList'; ... }]); 

If you change the base path (for example, when switching to another server or host), you just need to change it in your global configuration, and everything will be ready.

+27
Jun 14 '13 at 15:28
source share

I was unable to use the <base> , because my application was created in a popup window dynamically from another source. I considered the others option in this thread to use something like the basePath variable and use it in every $http, ng-src, templateUrl , etc.

But it was a little overhead, built an interceptor that changed every url before xhr was done

 var app = angular.module("myApp", []); app.config(["$httpProvider", function($httpProvider) { $httpProvider.interceptors.push('middleware'); }]); app.factory('middleware', function() { return { request: function(config) { // need more controlling when there is more than 1 domain involved config.url = "//example.com/api/" + config.url return config; } }; }); app.controller("Ctrl", ["$http", function($http) { $http.get("books"); // actually requestUrl = http://example.com/api/books }]) 

And html as well

 <div ng-include src="'view'"> <!-- actually src = http://example.com/api/view --> </div> 

But I recommend using the <base> instead if you are not using window.popup ()

+13
Sep 26 '13 at 21:48
source share

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

See here: http://docs.angularjs.org/guide/dev_guide.services.$location

+4
Jun 09 '13 at 16:24
source share

The accepted answer helped me. I am using Angular for my MVC application. I took one extra step so that my baseUrl can be used in my Angular controllers for calling web api or for accessing templates.

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

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

Angular controller

  $scope.manageCustomerGroups = function () { openDialog($scope.baseUrl + 'content/templates/customerGroups.html'); } 
+2
Feb 17 '15 at 15:09
source share

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

 <base href="~/" /> 
+2
Aug 19 '16 at 13:48
source share

In a simple way, I use ASP.NET Razor (Web MVC), so I get the path to the program and create it as the application base.

 <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Title</title> <meta name="description" content=""> @{ var appPath = Request.ApplicationPath.ToString(); if (!appPath.EndsWith("/")) { appPath = appPath + "/"; } } <base href="@appPath" /> 
0
Sep 28 '17 at 7:20
source share

I would just do all the urls.

 url: "../GetUserList", 

instead

 url: "GetUserList", 

Hard coding for the dose <base href="/application_root/" /> not a good idea for me, since you may need to change this environment to the environment and have a dependency on the name of the virtual directory.

0
Nov 28 '17 at 19:37
source share

In the ng-init function, pass a parameter containing the value of the virtual directory (int.SP.NET stored in Request.ApplicationPath).

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

Inside the angular controller, use this value as the URL prefix in every HTTP call. You can use this function to combine 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; } 
-one
Sep 18 '15 at 2:52
source share



All Articles