How to use constants in angularjs defined in same file - angularjs

I'm new to angular js. Is it possible to reuse the constants defined in the same file like below. If not please let me know a better way to reuse the defined constants. My intention behind this is I should be able to use LoginQuery.url in my service instead of concatenating.
angular.module('myApp.constants', []).
constant('ServerConfig', {
'url': 'http://localhost:3000/'
}).
constants('LoginQuery', {
'url': ServerConfig.url + "/login"
}
);
Thanks

I tend to do this the following way:
angular.module('myApp.constants', [])
.constant('urlsConst', (function(){
var protocol = 'http://';
var domain = 'www.mydomain.com';
var base = '/api/';
return {
category: protocol + domain + base + 'category/',
home: protocol + domain + base + 'home/',
products: protocol + domain + base + 'products/'
}
})()
);

Related

What is the best practice to manage API paths in an angular app?

I was looking for a way to manage the external API paths into a single location. Currently, I am storing them as a constant object.
var Resources = function () {
var baseURL = 'http://localhost:3000/'
var apiURL = baseURL + 'api/v1/';
return {
URL: {
API: apiURL,
ITEMS: {
INDEX: apiURL + 'items/'
},
CATEGORIES: apiURL + 'categories/',
AUTHORS: apiURL + 'authors/'
}
};
angular
.module('testApp')
.constant('RESOURCES', Resources());
However, now I am facing problem adding nested endpoints
eg: http://localhost:3000/api/v1/items/1/lease
Here, the above method fails, as "item_id" cannot be placed in the constant object
Interesting approach. We store this as a constant as well, but use string replacement for path variables. For instance:
{
"getStatusById": "/status/:id"
}
Then:
var url = endpoints.getStatusById.replace(':id', id)

How do I use $resource to post to a web-service?

I'm not very good with angular. I want to post to a web service, sending some xml with my search parameters. I don't want to send the parameters in the query string. I've read the official documentation, but I'm still confused. I'm mostly hung up on how to define the $resource to be able to post the way I want.
The error I get is: POST 'https://someWebservice/searchnet'::ERR_INSECURE_RESPONSE
My code is below:
'use strict';
angular.module('app').controller('inventorySearchController', inventorySearchController);
inventorySearchController.$inject = ['$scope','$http', '$resource'];
function inventorySearchController($scope, $http, $resource) {
console.log("controller initialized...");
$scope.callService = function(){
console.log("callService function called...");
var urlSearchService = 'https://someWebservice/search';
var skuVal = $scope.skuField;
var mVenVal = $scope.mVendorField;
//need to somehow specifiy that xml is a #FormParam
var xmlItemSearchRequest = "<ItemSearchRequest>"
+"<skuid>" + skuVal + "</skuid>"
+"<mvendor>" + mVenVal + "</mvendor>"
+"</ItemSearchRequest>";
console.log('calling: ' + urlSearchService + 'sending xml: ' + xmlItemSearchRequest);
var Results = $resource(urlSearchService, {
save: {
method: 'POST',
isArray: true
}
});
var result = Results.save();
console.log('Results: ' + Results);
console.log('result: ' + result);
var successfunction = function(){
$scope.searchResults = data;
console.log('call to ' + urlSearchService + ", was a success.");
};
var errorfunction = function(){
console.error('Calling error', status, data);
};
};
};
The error shown is not about how you posted data. Instead, response was not signed by a valid SSL certificate (or the certificate could not be accepted). That is due to the use of HTTPS protocol. You should consider using HTTP instead.
You can try the approach suggested here to confirm that this is the case.

How can I change the base URL of an AngularJS HTTP call?

My application calls $HTTP many times like this:
this.$http({
method: this.method,
url: this.url
})
The this.url is always set to something like /app/getdata
Now I have moved the back-end of my application to another server and I will need to get data like this:
https://newserver.com/app/getdata
Is there a way that I can supply a base URL that will be used for all the $http calls?
I found a alternative solution instead of <base> tag:
written in coffeescript
$httpProvider.interceptors.push ($q)->
'request': (config)->
if config.url.indexOf('/api') is 0
config.url = BASE_URL+config.url
config
I usually keep settings in angular constants and inject them to services.
I tend to keep my urls close to where they are needed. So if I have a service, then I'd keep the base url there; like this: this.rootUrl = '/api/v1/';
This allows me to have additional contextual methods that 'extend' the url.
For example:
this.getBaseUrl = function(client_id, project_id) {
return this.rootUrl + 'clients/' + client_id + '/projects/' + project_id + '/';
};
Which I can then use like this:
this.createActivity = function(client_id, project_id, activity_name, callback) {
$http.post(this.getBaseUrl(client_id, project_id) + 'activities', {activity: {name: activity_name}})
.success(callback)
.error(this.handlerError);
};
or like this (within the same service):
this.closeActivity = function(activity_id, callback){
$http.get(this.rootUrl + 'close_activity/' + activity_id)
.success(callback)
.error(this.handlerError);
};
set baseUrl in $rootScope:
app.run(function($rootScope) {
$rootScope.baseUrl = "https://newserver.com";
});
add $rootScope into your app's controllers:
app.controller('Controller', ['$rootScope', function($rootScope){
...
this.$http({
method: this.method,
url: $rootScope.baseUrl + this.url
})

URL rewrites - routing in Backbone

I have a www.example.com domain, and I need it to make it URL friendly. That domain need to be in multilanguage, like this:
http://{language}.example.com/restufullurls
How is that achievable in Backbone/Marrionette, only using routes?
First make a config file somewhere:
var config = {
lang: 'en',
domain: 'example.com'
};
Then make a base model that will rewrite the url of all models. What this does is rewrites the URL you specify in a model by appending the correct URL from the config file:
var BaseModel = Backbone.Model.extend({
initialize: function(){
this.url = 'http://' + config.lang + '.' + config.domain + '/' + this.url;
}
});
Then every time you need a new Model, you can extend the Base
var SomeModel = BaseModel.extend({
url: 'some/rest/url'
});
If you need to switch the language just do
config.lang = 'new-language';
If you would like to use the same URL as the file is being served from just do:
var BaseModel = Backbone.Model.extend({
initialize: function(){
this.url = window.location.origin + '/' + this.url;
}
});

Paramaterize the base URL in an Angular JS $resource

I'm using several Angular JS $resource definitions all of which retrieve their base URL from a configuration service. For example:
$resource(config.baseURL() + '/api/v2/foo/:id', {id: '#id'})
$resource(config.baseURL() + '/api/v2/bar/:id', {id: '#id'})
The reason this is done is that the base URL can be changed via a query string parameter when the application is first loaded.
I figured out that (obviously in retrospect) the URL used by the $resource is initialized just once so it's possible to get a race condition where the URL for a particular $resource is initialized before the base URL query string parameter is dealt with. So I tried to change the $resource declaration to this:
$resource(':baseURL/api/v2/foo/:id', {baseURL: config.baseURL(), id: '#id'})
Unfortunately the base URL is getting escaped – the // is converted to %2F%2F – so the whole URL then doesn't work properly.
Is there any way to suppress the escaping for that parameter? (or maybe a better way to solve the problem in general)?
Another way you can tackle this is use a provider and config it in the config stage.
Here is an example of something similar I did a while back.
.provider('Environment', function () {
var environments = {
dev: {
root: 'http://localhost',
port: 3000,
api: '/api',
version: 'v1'
}
};
var selectedEnv = 'dev';
var self = this;
this.setEnvironments = function (envs) {
if (!Object.keys(envs).length)
throw new Error('At least one environment is required!');
environments = envs;
};
this.setActive = function (env) {
if (!environments[env])
throw new Error('No such environment present: ' + env);
selectedEnv = env;
return self.getActive();
};
this.getEnvironment = function (env) {
if (!env)
throw new Error('No such environment present: ' + env);
return environments[env];
};
this.getActive = function () {
if (!selectedEnv)
throw new Error('You must configure at least one environment');
return environments[selectedEnv];
};
this.getApiRoute = function () {
var active = self.getActive();
return active.root + (active.port ? ':' + active.port : '') +
active.api + (active.version ? '/' + active.version : '');
};
this.$get = [function () {
return self;
}];
})
Then in the config phase:
.config(function (EnvironmentProvider) {
EnvironmentProvider.setEnvironments({
dev: {
root: 'http://10.0.0.3',
api: '/api',
version: 'v1'
},
localonly: {
root: 'http://localhost',
api: '/api',
version: 'v1'
},
prod: {
root: 'https://myapp.mybackend.com',
api: '/api',
version: 'v1'
}
});
//Set prod as the active schema
EnvironmentProvider.setActive('prod');
});
Later in some controller/service/factory:
.factory('API',function($resource, Environment){
return {
User: $resource(Environment.getApiRoute() + '/users/:id', {id: '#_id'}),
OtherResource: $resource(Environment.getApiRoute() + '/otherresource/:id', {id: '#_id'})
}
});
Why not make use of the $location service?
For example, how about the following to handle the base url, and, if the application is running from localhost, include the port number? Additionally, be able to include either http or https based on the current URL?
var host = $location.host();
if (host === "localhost")
host += ":" + $location.port();
var url = $location.protocol() + "://" + host + "/whateverElseYouWantInThePath";
and then use url where you need it?
From the Definition of resource,
#param {string} url A parametrized URL template with parameters prefixed by : as in
/user/:username. If you are using a URL with a port number (e.g.
http://example.com:8080/api), you'll need to escape the colon character before the port
number, like this: djResource('http://example.com\\:8080/api').
So you have to define your config.baseURL() as follows,
config.baseUrl = function(){
return 'http://server.com\\:port/rest_part/';
}
Here is a horrible but working workaround. Instead of...
$resource(config.baseURL() + '/api/v2/foo/:id', {id: '#id'})
... which is only evaluated once, use an object that implements String-methods that ngResource evaluates before each request:
var url = {};
url.value = function() {return config.baseURL() + '/api/v2/foo/:id'};
url.split = function (separator,limit) { return url.value().split(separator,limit) };
url.replace = function (match, other) { return url.value().replace(match, other) };
url.toString = function() { return url.value(); }
$resource(url, {id: '#id'})

Resources