AngularJS Reading web.config value
I have an angularjs factory function that calls a REST service. My problem is currently. The REST url is hardcoded in the service factory. I want to remove this hardcoding
(function () {
'use strict';
var auctionServices = angular.module('auctionService', ['ngResource']);
//TODO: USE BASE URL SO THAT CAN POINT TO LOCALHOST OR ACTUAL WEB SERVER
var baseUrl = "http://localhost:5037";
auctionServices.factory('auctions', ['$resource', function ($resource) {
return $resource(baseUrl + '/services/rest/auctions', {}, {
filter: {
url: baseUrl + '/services/rest/auctions?location=:location&status=:status',
isArray: true,
params: { location: '@location', status: '@status' },
withCredentials: true,
cache: false
},
My problem is with the below line
var baseUrl = "http://localhost:5037";
I need to set baseUrl value from web.config or please help me with any other better approach.
source to share
If your problem is moving all your global configs into one file, you can use the constant: create config.js file like this:
angular.module('myApp').constant('configs', {
baseUrl: 'http://localhost:5037'
})
Then in the factory, enter configs:
auctionServices.factory('auctions', ['$resource', 'configs', function ($resource, configs){
}
configs.baseUrl contains your url
source to share
If your application is filed in "http://localhost:5037"
, you can simply do
$resource('/services/rest/auctions')
or
$resource('/user/:userId/card/:cardId')
Unless you are using cross domain, otherwise your application and REST API path are different.
In this case, you can put baseUrl like
module.value('APP_CONTEXT',{}).
module.run(function($location, APP_CONTEXT)) {
var baseUrlConstuct = null;
//your logic here to get the domain name from
//$location.path() and construct a base url.
APP_CONTEXT.baseUrl = baseUrlConstuct;
}
Then in your factories
auctionServices.factory('auctions',
['$resource', 'APP_CONTEXT', function ($resource, APP_CONTEXT) {
return $resource(APP_CONTEXT.baseUrl + '/services/rest/auctions', {}, {
}
}
I might suggest using Restangular - it's all pretty neat for you, including other gooodies.
source to share
We set it up in config.js file, by the way, we do this
//custom config settings
var appServicesHostName = "http\\://localhost\\:62784/api";
var memberServicesHostName = "http\\://localhost\\:48089";
var coverageServiceHostName = "http\\://localhost\\:5841";
var config = {
appServicesHostName: appServicesHostName,
memberServicesHostName: memberServicesHostName,
coverageServiceHostName: coverageServiceHostName,
};
app.value("config", config);
Then you can just inject it into your services, something like this
angular.module('app').factory(serviceId,
['$q', '$http', 'config', 'Dependents', inRelatedInsuredEditDataSvc]);
This answers your question, but you are still hard-coding parts of the URL. Your best bet is to customize the routes and name them. They can move routes, change them without changing them everywhere. For example in config.route.js
(function () {
'use strict';
var app = angular.module('app');
// Collect the routes
app.constant('routes', getRoutes());
// Configure the routes and route resolvers
app.config(['$routeProvider', 'routes', routeConfigurator]);
function routeConfigurator($routeProvider, routes) {
routes.forEach(function (r) {
$routeProvider.when(r.url, r.config);
});
$routeProvider.otherwise({ redirectTo: '/insureds/search' });
}
// Define the routes
function getRoutes() {
return [
{
name: 'InsuredsSearchView',
url: '/insureds/search',
config: {
templateUrl: 'app/insured/search/inSearch.html',
reloadOnSearch: false,
settings: {}
}
},
{
name: "InsuredCallLogAdd",
url: '/insureds/:insuredId/callLogs/add',
config: {
templateUrl: 'app/insured/callLog/edit/inCallLogEdit.html',
reloadOnSearch: false,
settings: {}
}
}
}
})();
As you can see, we name each route and refer to it by name, not hard-coded links all over the place. All you need now is a service to give a route like this
(function () {
'use strict';
var serviceId = 'routesSvc';
angular.module('app').factory(serviceId, ['$location', 'routes', routesSvc]);
function routesSvc($location, routes) {
// Define the functions and properties to reveal.
var service = {
getPath: getPath,
navigateTo: navigateTo,
getTemplateUrl: getTemplateUrl
};
return service;
function getPath(routeName, routeParameters) {
var route = _.findWhere(routes, { name: routeName });
if (route == undefined) {
//EP: finish - use $log and throw error
console.log("route: " + routeName + " does not exist");
}
var qParameterKeys = [];
var path = route.url;
for (var key in routeParameters) {
if (path.indexOf(":" + key) == -1) {
qParameterKeys.push(key);
} else {
path = path.replace(":" + key, routeParameters[key]);
}
}
if (qParameterKeys.length > 0) {
path = path + "?";
key = qParameterKeys[0];
var item = routeParameters[key];
var value = angular.isObject(item) ? angular.toJson(item) : item;
path = path + key + "=" + value;
for (var i = 1; i < qParameterKeys.length; i++) {
key = qParameterKeys[i];
item = routeParameters[key];
value = angular.isObject(item) ? angular.toJson(item) : item;
path = path + '&' + key + "=" + value;
}
}
return path;
}
function navigateTo(routeName, routeParameters) {
$location.url(getPath(routeName, routeParameters));
}
function getTemplateUrl(routeName) {
var route = _.findWhere(routes, { name: routeName });
if (route == null) throw (routeName + " is not defined in config.route.js");
return route.config.templateUrl;
}
}
})();
and then you can use it like this
<a data-ng-href="#{{getPath('BatchDefaultView',{batchId:result.batchId})}}">
See without hardcoded URL
and if you need other information about the route or patterns, you can even make it available through the scope, like
(function () {
'use strict';
var app = angular.module('app');
app.run(function ($rootScope, routesSvc) {
$rootScope.getPath = function (routeName, parameters) {
return routesSvc.getPath(routeName, parameters);
};
$rootScope.navigateTo = function(routeName, parameters) {
routesSvc.navigateTo(routeName, parameters);
};
$rootScope.getTemplateUrl = function(routeName) {
return routesSvc.getTemplateUrl(routeName);
};
});
})();
Hope this helps you keep it clean.
source to share