controller.js
angular.module('app.main')
.controller('MainCtrl', function ($scope, currentUser, addAPI) {
$scope.form = {};
$scope.subdomain = currentUser.domainName;
$scope.add = function () {
addAPI.addAdmin(localStorage['token'], $scope.subdomain, $scope.form, onSuccess, onError);
};
take the details from the form and pass token and subdomain(took from current userDatService)
addAPI.js
angular.module('app.main').factory('addAPI', function ($resource, $http, Constant) {
var adminAPI = function () {
this.addAdmin = function (token, domain, dataObj, sucCall, errCall) {
$http({
method: 'POST',
url: Constant.API.prefix + domain + Constant.API.postfix + '/client/admin',
headers: {
'Token': token
},
data: dataObj
}).then(handleResp).catch(handleResp);
};
return new adminAPI;});
sending data to API URL
constants.js
angular.module('app.constants', [])
.constant('Constant', {
'API': {
prefix: 'http://api.',
postfix:'.dev.education.in/v1/academy-api/api/v.1.0'
}
});
1.I want to have a function in constants.js which accepts user or subdomain and returns URL?
2.is it the right way to format a base_url or any suggestions on improving.
3.I need to define a perfect base_url with prefix + domain + postfix + ...
I'm new to angularJs and Javascript and i tried my best to get a solution but functions are not working with constants
It may be a better method to put your constants in a vanilla javascript file and load them onto the stack (via html) before any angular-related scripts are loaded. That way they will already be in the global namespace and you can simply refer to them anywhere.
e.g.
Constant.js
var API = {
prefix: 'http://api.',
postfix:'.dev.education.in/v1/academy-api/api/v.1.0'
}
index.html
<script src="Constant.js"></script>
<script src="factories/addAPI.js"></script>
addAPI.js
angular.module('app.main').factory('addAPI', function ($resource, $http, Constant) {
var adminAPI = function () {
this.addAdmin = function (token, domain, dataObj, sucCall, errCall) {
$http({
method: 'POST',
url: API.prefix + domain + API.postfix + '/client/admin',
headers: {
'Token': token
},
data: dataObj
}).then(handleResp).catch(handleResp);
};
return new adminAPI;});
Related
angular.module('snswMock').factory('snswService', ['$http','$location' ,
function ($http, $location ) {
'use strict';
return {
getData: function(jsonData){
var jsonString = JSON.stringify(jsonData);
var serviceUrl = getServiceUrl();
$http({
url: serviceUrl,
dataType: 'string',
method: 'POST',
data: jsonString
}).success(function(response){
alert ("Success");
}).error(function(error){
alert ("Save company!");
});
},
getServiceUrl :function(){
var host = $location.host();
if (host === 'localhost') {
return $location.protocol() + '://' + host + ':9000/services/insert';
} else {
return $location.protocol() + '://' + host + '/services/insert';
}
}
}
}
]);
Hi am very new to the angular
this is my service
I am calling getServiceUrl inside getData function i am getting the below error
angular.js:11706 ReferenceError: getServiceUrl is not defined
can anyone please help me how can I call the method. is there any other way is there to call web service by passing a string as post request?
The controller where you are trying to access this service, do below things.
Inject this service in the controller.
Call this service like below
snswService.getServiceUrl();
You need to use this context to access a global object function -> this.getServiceUrl(). In your case myFactory is the object and inside your object all functions are globally accessible inside your object scope by using this context.
angular.module('snswMock').factory('snswService', ['$http', '$location', function($http, $location) {
'use strict';
var myFactory = {
getData: function(jsonData) {
var jsonString = JSON.stringify(jsonData);
var serviceUrl = this.getServiceUrl(); //modified
$http({
url: serviceUrl,
dataType: 'string',
method: 'POST',
data: jsonString
}).success(function(response) {
alert("Success");
}).error(function(error) {
alert("Save company!");
});
},
getServiceUrl: function() {
var host = $location.host();
if (host === 'localhost') {
return $location.protocol() + '://' + host + ':9000/services/insert';
} else {
return $location.protocol() + '://' + host + '/services/insert';
}
}
}
return myFactory;
}]);
Hi there I write a service of $resource for connecting the api.
here is the code in service.js
.factory('selfApi2', function ($resource, localStorageService) {
var AB = {
data: function (apiURL, header, data, params) {
return $resource("http://localhost:4000/api" + apiURL, null, {
update: {
method: 'POST',
headers: header,
data: data,
params: params
}
});
}
};
return AB;
})
in my controller.js
var header = {
'Content-Type': 'application/x-www-form-urlencoded'
};
var myData = {
'phone': '12345678'
};
selfApi2.data('/tableName',header,{where:{"name":"kevin"}).update(myData, function(result){
console.log("update Kevin's phone succeed",result);
})
it works. But why the variable myData should put inside the update() part rather than the data() part?
In your case, the data() is a function which will just create a ReST resource which would expose rest apis get save query remove delete as default.
So in this data() call you are just creating the rest resources. Passing myData with this function would not make any sense. The data() call would return the Resource instance which will have your update api function which accepts the parameters.
And, passing your data at api construction time does not make sense.
Here is the complete reference
I think it's because "data" is a function that returns object of $resource.
Try the scenario below:
// service
.factory('api', function ($resource) {
var api = {};
api.issues = $resource("http://localhost:4000/api/issues");
api.users = $resource("http://localhost:4000/api/users", {}, {
update: {
method: 'PUT',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
},
});
return api;
})
// controller
api.users
.update({where:{name:'kevin'}})
.$promise.then(function(success) {
// DO SOMETHING
});
...
api.issues.query().$promise.then(
function(success) {
// DO SOMETHING
});
config.js
angular.module('config', []).constant('ENV',
{
name: 'My Angular Project',
apiEndPoint: 'http://SOMEIP/myServer', //API host,
adminUrl:'/admin/regionid/site/siteid/admin/regionid', //endpoint
loginUrl:'/login/regionid/site/siteid/device'
});
controller.js
this.userLogin = function(username, password) {
var adminServicePath = ENV.apiEndPoint + ENV.adminUrl
//final url = http://SOMEIP/myServer/admin/1/site/1/admin/1
var loginServicePath = ENV.apiEndPoint + ENV.loginUrl
//final url = http://SOMEIP/myServer/login/2/site/2/device
return $http({
method: 'POST',
url: adminServicePath,
headers: {
"Authorization": "Basic ",
"Content-Type": "application/x-www-form-urlencoded"
}
})
};
Here I am appending API with endpoint to form a complete URL. My issue is regiondid and siteid are dynamic. After user logs in, one REST API request will fetch siteid and regionid in response.
How do I dynamically replace siteid and regionid in URL with ID's
received in API response? After receiving id's in response, call a function that replaces the value.
You can use the String.prototype.replace(substr, newsubstr)
You can keep regionID instead of ?
var ENV = {
name: 'My Angular Project',
apiEndPoint: 'http://SOMEIP/myServer', //API host,
adminUrl: '/admin/?/site/?/admin/?', //endpoint
loginUrl: '/login/?/site/?/device'
};
var adminServicePath = ENV.apiEndPoint + ENV.adminUrl.replace("?", 1).replace("?", 1).replace("?", 1);
console.log("Final url admin : " + adminServicePath);
var loginServicePath = ENV.apiEndPoint + ENV.loginUrl.replace("?", 2).replace("?", 2);
console.log("Final url login : " + loginServicePath);
instead of constant, you can use value.
angular.module('config', []).value('ENV',
{
name: 'My Angular Project',
apiEndPoint: '', //API host,
adminUrl:'', //endpoint
loginUrl:''
});
Inject ENV and set all values after API call.
ENV.name = xyz;
ENV.apiEndPoint = xyz;
ENV.adminUrl = xyz;
ENV.loginUrl = xyz;
but the values might get set to default once you refresh the browser.
I'll assume that the siteid and the regionid can only be obtained from the response to the login endpoint.
Using a constant might not be the best idea here for obvious reasons (i.e. they're constant, and can't be created at the time you want to create them).
Instead, you could do one of a few things - a simple solution that probably works for a lot of use cases would be to create a login service that wraps your API call and then sets a value either in the service or another service that can be injected into wherever you need it.
It might look like this:
angular.module('app')
.service('loginService', function($http) {
var siteId,
regionId;
function login(username, password) {
return $http({
method: 'POST',
url: '<login endpoint here>',
headers: {
"Authorization": "Basic ",
"Content-Type": "application/x-www-form-urlencoded"
}
})
.then(function(result) {
siteId = result.siteId;
regionId = result.regionId;
});
}
);
This makes the values available to you any time you need to make an API call after logging in. However, this isn't great since you will need to inject the loginService into any controller/service that needs it, and that controller/service might not really care about the login service at all.
An improved approach to this could be to have an API service that performs the http gets/sets/puts/posts/whatever and that is accessed by your data access layer. Inside this service, you can set/get the siteid and regionid.
It might look like this:
angular.module('app')
.service('api', function($http) {
var siteId,
regionId;
var defaultHeaders = {
"Authorization": "Basic ",
"Content-Type": "application/x-www-form-urlencoded"
};
function post(url, options) {
return $http({
method: 'POST',
url: url,
headers: options.headers ? options.headers : defaultHeaders
});
}
// Other functions to perform HTTP verbs...
});
angular.module('app')
.service('loginService', function(api) {
function login(username, password) {
api.post('urlHere', options)
.then(function(result) {
api.siteId = result.siteId;
api.regionId = result.siteId;
});
}
});
You can then access the siteid and regionid where you like.
For example:
angular.module('app')
.controller('someService', function(api) {
function doSomethingWithTheApi() {
var url = 'www.google.com/' + api.siteId + '/' + api.regionId + 'whatever-else';
return api.post(url, {});
}
);
Note: the code above isn't complete, but it gives you a very good idea of the approach you could take that is reasonably clean, not too hacky and is easily testable :)
Hope that helps!
I have to use global variable in angular service.
I have function to get session id from parent application. like this
var sessionID;
function AddSessionID(e) {
sessionId = e;
}
This is the function I have used for get sessionid and this function called in parent app.
I need to use this session id(sessionID) inside angular service as a parameter.
this is my service call
(function () {
"use strict";
mApp.service('compasService', ['$http', '$q', function ($http, $q) {
//Public API
return {
initialLayout: initialLayout
};
function initialLayout() {
var dataObj = {};
dataObj.command = 'getLayoutCstics';
dataObj.sessionID = sessionId;
dataObj.userid = userID;
var transform = function (data) {
return $.param(dataObj);
},
request = $http({
method: "POST",
url: myURL,
//params:For passing via query string
transformRequest: transform,
dataType: "text",
//To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
crossDomain: true
});
return (request.then(successHandler, erroHandler));
}
})();
Please get me a proper way to get it.
Architectually speaking, if you must use global variables, you want to limit the places that must use the global context. In this case, you might benefit from a sessionService in Angular that encapsulates access to the session Id.
(function(global) {
'use strict';
mApp.service("sessionService", function() {
return {
getSessionID: function() {
return global.sessionId;
},
getUserID: function() {
return global.userID;
}
};
});
}(this));
Then you can specify that as a dependency in your other Angular services:
(function () {
"use strict";
mApp.service('compasService', ['$http', '$q', 'sessionService', function ($http, $q, sessionService) {
//Public API
return {
initialLayout: initialLayout
};
function initialLayout() {
var dataObj = {
command: 'getLayoutCstics',
sessionID: sessionService.getSessionID(),
userId: sessionService.getUserID()
},
transform = function (data) {
return $.param(dataObj);
},
request = $http({
method: "POST",
url: myURL,
//params:For passing via query string
transformRequest: transform,
dataType: "text",
//To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
crossDomain: true
});
return (request.then(successHandler, erroHandler));
}
})();
The successHandler and erroHandler appear to be global functions as well. The second function, erroHandler appears to be misspelled and should be errorHandler (notice the "r" before the "H"), though I don't know if the spelling is an actual problem.
The whole point is to encapsulate access to global variables in one or more services so you limit your use of globals in your other services, modules and controllers.
I have a factory where I have a function getExpenseList which does an ajax call which queries the expense table and gives me the result.
Now I have two routes, 1 which is listing of expenses which is pushing the expense through the above function and the second route is an add. When I do a route change and come back to the listing page, the ajax call is made again. Ideally I should be able to store the expense object on the first ajax call and then reference the same object till someone is manually refreshing the browser.
please help me on this. Here is my factory code. Ideally I would like to refer to this.expenses if the data is present.
admin.factory('expenseFact', ['$http', function($http) {
var expense = {};
this.expenses = "";
expense.getExpenseList = function() {
this.expenses = $http({
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: "GET",
url: base_url + "rest/expenses"
});
return this.expenses;
};
return expense;
}]);
And here is my controller code
admin.controller('expenseLandCtrl', function ($scope,$rootScope,expenseFact) {
$scope.pageTitle = $rootScope.pageTitle;
expenseFact.getExpenseList().then(function (data) {
$scope.expenses = data.data;
});
});
admin.controller('expenseAddCtrl', function ($scope,$rootScope,expenseFact) {
$scope.pageTitle = $rootScope.pageTitle;
});
your factory will be like this
admin.factory('expenseFact', ['$http', function($http) {
return {
getExpenseList: function() {
var expense = {};
this.expenses = $http({
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: "GET",
url: base_url + "rest/expenses"
});
return this.expenses;
}
}
}]);
and you can call it from controller same way and it wont call it automatically.
btw i recommend use of promises.
below is same code with use of promise
admin.factory('expenseFact', ['$http', '$q'. function($http, $q) {
return {
getExpenseList: function(){
var deferred = $q.defer();
$http({method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).
then(function(response) {
deferred.resolve(response.data);
}, function(response) {
deferred.reject(response.status)
});
return deferred.promise;
}
}
}]);
You need to get the expenses once when the factory is loaded for the first time;
admin.factory('expenseFact', ['$http', function($http) {
var expenses = null;
$http({
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: "GET",
url: base_url + "rest/expenses"
}).success(function (exp) {
expenses = exp;
}); // get the expenses when the factory is loaded
return {expenses: expenses};
}]);
What this does is that it makes the expenses return from the factory refer to the one-time ajax call to get the expenses.