Best way to provide url to angular $http.get/.post - angularjs

I am using angular with MVC4. I would like to call a MVC controller method from javascript using $http.get(). It requires a url (obviously). I would like this to be a relative path, but how do I write that? My controller is in Controllers/Api/ExampleController. I would like the path to resolve even if I move the javascript file into another location, meaning I would like the path to be relative to application root as opposed to the javascript file. I Have tried "~/Controllers/Api/ExampleControllerMethod" and "Controllers/Api/ExampleController/Method.

The $location service does provide information from the url. So, you could construct something to then make the host and port dynamic:
var url = $location.host() + '/Controllers/Api/ExampleControllerMethod';
From the documentation:
**url: http://www.example.com/base/path?a=b#h**
$location.protocol() = http
$location.host() = www.example.com
$location.port() = 80
$location.path() = /path
$location.search() = {"a":"b"}
$location.hash() = h

Thanks for the ideas but this kind of thing is what I was looking for:
Configure the WebApiConfig to add a route like so (should have it as default):
config.Routes.MapHttpRoute(
name: "ApiMethods",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
So now I can go $http.get('api/{controller}/{method}')

What worked for me was to provide the Url as "/ControllerName/Action" (instead of "ControllerName/Action")

Related

pass relative url in signalR hub connection

I am trying to implement signalR in angularJS,
I want to pass relative url to hub connection, but it's making current url (on which my angular application is hosted)
My API base url : http://localhost:81/NrsService/api/TestSignal
My angular application running at
http://localhost:81
Here is my signalR setup :
$.connection.hub.url = "/NrsService/api/TestSignal";
//Getting the connection object
connection = $.hubConnection();
Like it is sending request at http://localhost:81/signalr/negotiate? but I want it to be http://localhost:81/NrsService/api/TestSignal/negotiate?
You have to edit the generated JavaScript code where the client proxy is defined. As of SignalR 2.4.0 there is a createHubProxies function defined where you should find this line of code:
signalR.hub = $.hubConnection("/signalr", { useDefaultPath: false });
Change it to the following to prevent the "/signalr" ending in your requests:
signalR.hub = $.hubConnection("", { useDefaultPath: false });
After that, you can simply change the url which should be called the way you provided in your question, e.g.:
$.connection.hub.url = "/NrsService/api/TestSignal";
If you also want to change this Url dynamically, you can use the document.location properties. In my case, I did something like this:
var subPath = document.location.pathname.substr(0, document.location.pathname.lastIndexOf("/"));
$.connection.hub.url = subPath; // subpath equals to "/NrsService/api"
Hope this helps.

I want my $http.get(..../Login) to be dynamically change as per environment and my project name should also be dynamic

$http.get('localhost:8080/myApp/Login).success(function() {.....
…..
…
});
I want to replace 'localhost:8080/myApp with the host where I will deploy my project with project name at that time …
What I am doing is that using angular I am mapping the URL to spring controller method . So I don't want it to be static I want 'localhost:8080/myApp to be taken dynamically where I am deploying my project with the project name …
While working
Projects name: myApp
Host:localhost:8080
When deployed
Projects name: myApplication
Host:www.xyz.com
So my
$http.get('www.xyz.com/myApplication/Login). success(function(){...
….
…});
Update:I also want my project name to be automatically taken in which my js and Java controller is there
The $location service does provide information from the url. So, you could construct something to then make the dynamic host:
// given URL http://example.com/#/some/path?foo=bar&baz=xoxo
var host = $location.host();
// => "example.com"
// given URL http://user:password#example.com:8080/#/some/path?foo=bar&baz=xoxo
host = $location.host();
// => "example.com"
host = location.host;
// => "example.com:8080"
First you need to declare $location in your service then you can extract dynamic location host port.
To know more about $location service please check angular api doc
Extract Project Name:
For Extract Projet name i make my custom method which get project name from $location.absUrl() use Following function:
var url= $location.absUrl();
url= getProjectName(url);
function getProjectName(url){
var index,int;
for (int = 0; int <3; int++) {
index = url.indexOf("/");
url= url.substring(index+1);
}
var index = url.indexOf("/");
url = url.slice(0, index);
return url;
}

dynamic subdomain with angularjs

I am new to Angularjs and I would like to add dynamic subdomain such as sub.domain.com.
By changing sub, I would be able to ask the proper data from the server. However, the home page will still be the same.
sub1.domain.com and sub2.domain.com will have the same home.tpl.html page except that the data returned will be specific to the domain.
It will be the same for other pages too.
Is there a way to do that?
The main thing you need to look at is the $location service, in particular the $location.host() method. That will return you the full domain, from there it is easy to get the subdomain and use that.
You could even do a really simple service that you could inject anywhere to get access to the subdomain easily.
Something like:
app.factory('subdomain', ['$location', function ($location) {
var host = $location.host();
if (host.indexOf('.') < 0)
return null;
else
return host.split('.')[0];
}]);
Then you can use this as a simple injectable value in your controllers, directives, etc.
app.controller('SomeCtrl', ['$scope', 'subdomain', function ($scope, subdomain) {
// use subdomain same as any other variable
}]);
Subdomains are served by server, angular in turn serves hash/hashbang urls and knows nothing about subdomain.
U can have 3 subdomain, for example:
en.example.com (configured manually on server)|
de.example.com (configured manually on server)| -> example.com
it.example.com (configured manually on server)|
Each of them refers to the main example.com, but you wanna achieve something by using subdomains, for example i18n (with angular).
Thus, when someone connects to en.example.com (in fact, the request goes to example.com where you angular app is hosted) you can extract subdomain in angular(en in this case, see example in the post above) and translate you angular view.
Why no split by dots and count the elements of host()?
var host = $location.host();
var parts = host.split('.');
var subdomain = null;
// more than domain.cn, will always return the first
if (parts.length > 2)
subdomain = parts[0];
return subdomain;
hope it helps!

Why does angular prefix redirect url with 'localhost' when using $location.path?

The following snippet of code doesn't redirect me to the specified page (redirectUrl) - but rather, prefixes redirectUrl with the string 'localhost'.
I end up redirected to "localhost/http://localhost/example/page".
How can I avoid this?
var redirectUrl = "http://localhost/example/page";
$location.path(redirectUrl); //redirects to "localhost/http://localhost/example/page".`
$scope.$apply();
You need to modify your path to a relative path rather than an absolute path. so it would be something like this:
var redirectUrl = "/example/page";
$location.path(redirectUrl); //redirects to "http://localhost/example/page".`
angular's $location service works based on relative url.
To redirect to absolute url you can use.
window.location.href="http://localhost/example/page";
or using angular's $window
$window.location.href="http://localhost/example/page";

Whats the better way to identify the context path in Angular JS

I have my web application deployed to tomcat with an applicatio context.
For example my URL looks something like this.
http://localhost:8080/myapp
myapp - is the application context here.
Now in an Angular service if i want to call a webservice say getusers. My URL should be this /myapp/getusers. But I want to avoid hardcoding the application context as it might change from one deployment to other.
I have managed to figureout the contextpath from $window.location.pathname but it looks very stupid. Is there a betterway?
FYI I am using Spring MVC for restful services.
What I have done is declared a variable in the main jsp file. Then that variable will be available throughout the angular application.
<script type="text/javascript">
var _contextPath = "${pageContext.request.contextPath}";
</script>
This code should be written in header before including other JavaScript libraries.
I'm also using tomcat and Spring MVC. Using relative url in JavaScript will do the trick.
For doing this you just need to remove the / at the begining of REST url. so that your url starts from the current url in your browser.
replace $resource('/getusers') with $resource('getusers')
Inject the $location service to your controller.
var path = $location.path(); // will tell you the current path
path = path.substr(1).split('/'); // you still have to split to get the application context
// path() is also a setter
$location.path(path[0] + '/getusers');
// $location.path() === '/myapp/getusers'
// ------------------ \\
// Shorter way
$location.path($location.path() + '/getusers');
// $location.path() === '/myapp/getusers'
In Angular 2 (if using hashbang mode). Below code can be used to form the url.
document.location.href.substr(0, document.location.href.lastIndexOf("/#")) + "/getusers";
Inspired from the answer of #jarek-krochmalski
if you are using hashbang mode, with "#", you can do something like that:
$location.absUrl().substr(0, $location.absUrl().lastIndexOf("#")) + "/getusers"
For AngularJS $http service you are good to go with url : 'getusers', as follows:
$scope.postCall = function(obj) {
$http({
method : 'POST',
url : 'getusers',
dataType : 'json',
headers : {
'Content-Type' : 'application/json'
},
data : obj,
});
};
In general, you should use injection in your controller like the following:
angular.module("yourModule").controller("yourController", ["$scope", "yourService", "$location", function($scope, yourService, $location){
....
//here you can send the path value to your model.
yourService.setPath($location.path());
....
}]);

Resources