AngularJs Separate function under factory - javascript

I am using AngularJs and backend CodeIgniter REST API .Here is the sample of code
data.js
`
app.factory("Data", ['$http', 'toaster','$log',
function ($http, toaster,$log) {
// This service connects to our REST API
var serviceBase = 'link';
var obj = {};
obj.toast = function (data) {
toaster.pop(data.status, "", data.message, 10000, 'trustedHtml');
}
obj.get = function (q) {
return $http.get(serviceBase + q).then(function (results) {
return results.data;
});
};
obj.post = function (q, object) {
//$log.log(object.customer);
$http({
method: 'POST',
url: serviceBase + q,
headers: {
Accept: "application/json",
"REST-API-KEY": "key"
},
data: object.customer
})
.then(function (results) {
$log.log(results);
return results.data;
});
};
obj.put = function (q, object) {
return $http.put(serviceBase + q, object).then(function (results) {
return results.data;
});
};
obj.delete = function (q) {
return $http.delete(serviceBase + q).then(function (results) {
return results.data;
});
};
return obj;
}]);
authctrl.js
app.controller('authCtrl', function ($scope, $rootScope, $routeParams, $location, $http, Data,sData) {
//initially set those objects to null to avoid undefined error
$scope.login = {};
$scope.signup = {};
$scope.doLogin = function (customer) {
Data.post('login', {
customer: customer
}).then(function (results) {
Data.toast(results);
if (results.status == "success") {
$location.path('dashboard');
}
});
};
$scope.signup = {email:'',password:'',name:'',phone:'',address:''};
$scope.signUp = function (customer) {
sData.post('signUp', {
customer: customer
}).then(function (results) {
Data.toast(results);
if (results.status == "success") {
$location.path('dashboard');
}
});
};
$scope.logout = function () {
Data.get('logout').then(function (results) {
Data.toast(results);
$location.path('login');
});
}
});
It is having an error which is
TypeError: Cannot read property 'then' of undefined
at h.$scope.doLogin (authCtrl.js:8)
at $a.functionCall (angular.min.js:172)
at angular.min.js:189
at h.a.$get.h.$eval (angular.min.js:108)
at h.a.$get.h.$apply (angular.min.js:109)
at HTMLButtonElement. (angular.min.js:189)
at angular.min.js:31
at q (angular.min.js:7)
at HTMLButtonElement.c (angular.min.js:31)
And also as you can see i am using single post method for both login and signUp function .So what i want to make it separate function like
For Login
obj.post = function (q, object) {
//$log.log(object.customer);
$http({
method: 'POST',
url: serviceBase + q,
headers: {
Accept: "application/json",
"REST-API-KEY": "3e9aba65f0701f5e7c1c8a0c7315039e"
},
data: object.customer
})
.then(function (results) {
$log.log(results);
return results.data;
});
};
For Sign up
obj.post = function (q, object) {
//$log.log(object.customer);
$http({
method: 'POST',
url: serviceBase + q,
headers: {
Accept: "application/json",
"REST-API-KEY": "3e9aba65f0701f5e7c1c8a0c7315039e"
},
data: object.customer
})
.then(function (results) {
$log.log(results);
return results.data;
});
};
How to write it in angularJs?

because you are returning nothing from Data.post, instead of returning the promise .
i.e. change your Data.post to
obj.post = function (q, object) {
//$log.log(object.customer);
return $http({
method: 'POST',
url: serviceBase + q,
headers: {
Accept: "application/json",
"REST-API-KEY": "key"
},
data: object.customer
});
};

Related

not able to get function return value in angularjs http request

I am getting undefined for the value returned by the function which is an http request. So I am calling http request inside http.
bmgApp.controller('cmpUserSoftwares', function($scope, $http) {
$scope.records = {};
$http({
method: 'GET',
url: 'http://megabot/mautonew/wp-json/bmg-comp-listing/v1/company/1'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
$scope.records = response.data;
for (var i = 0; i < $scope.records.length; i++) {
console.log($scope.records[i]);
angular.forEach($scope.records[i], function(value, key) {
if (key == "maincategoryid") {
value = getSoftwareCategory(value);
}
console.log(value + ' : ' + key);
});
}
function getSoftwareCategory(value) {
$http({
method: 'GET',
url: 'http://megabot/mautonew/wp-json/bmg-comp-listing/v1/software-category/' + value
}).then(function successCallback(response) {
var software_category = response.data;
console.log(software_category);
return software_category;
}, function errorCallback(response) {
console.log("Error");
});
}
/*angular.forEach($scope.records, function(value, key){
console.log( $scope.records[key].value + ' : ' + key);
});*/
//console.log(response.statusText);
}, function errorCallback(response) {
console.log("Error");
});
});
The console.log inside getSoftwareCategory function is returning the value but not getting assigned to value variable. I am getting undefined
getSoftwareCategory is calling an asynchronous call and from inside and it doesn't actually return anything. (The return value of the inner then() handler is not returned when the parent function is called)
Although this could probably be done better, as a first step, return the promise from getSoftwareCategory and do the value assignment using a then() block.
EDIT: New code based on discussion in comments
$http({
method: 'GET',
url: 'http://megabot/mautonew/wp-json/bmg-comp-listing/v1/company/1'
}).then(function successCallback(response) {
function getSoftwareCategory(record) {
return $http({
method: 'GET',
url: 'http://megabot/mautonew/wp-json/bmg-comp-listing/v1/software-category/' + record.maincategoryid
}).then(function successCallback(response) {
record.maincategoryid = response.data;
return record;
}, function errorCallback(response) {
console.log("Error");
});
}
var records = response.data;
var promises = records.map(function (record) {
return getSoftwareCategory(record);
})
return $q.all(promises).then(function (results) {
$scope.records = results;
});
}, function errorCallback(response) {
console.log("Error");
});
You are doing it in the wrong way I think you are not familier with async programming in JavaScript. The value in value = getSoftwareCategory(value); will be always undefined because your getSoftwareCategory is not returning any value. To handle this kind of task in your code you should first read about promises in javascript. So your code will be like this after modifying this
bmgApp.controller('cmpUserSoftwares', function($scope, $http) {
$scope.records = {};
$http({
method: 'GET',
url: 'http://megabot/mautonew/wp-json/bmg-comp-listing/v1/company/1'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
$scope.records = response.data;
for (var i = 0; i < $scope.records.length; i++) {
console.log($scope.records[i]);
angular.forEach($scope.records[i], function(value, key) {
if (key == "maincategoryid") {
getSoftwareCategory(value).then(software_category => {
console.log(software_category)
});
}
console.log(value + ' : ' + key);
});
}
function getSoftwareCategory(value) {
return $http({
method: 'GET',
url: 'http://megabot/mautonew/wp-json/bmg-comp-listing/v1/software-category/' + value
}).then(function successCallback(response) {
var software_category = response.data;
console.log(software_category);
return software_category;
}, function errorCallback(response) {
console.log("Error");
});
}
/*angular.forEach($scope.records, function(value, key){
console.log( $scope.records[key].value + ' : ' + key);
});*/
//console.log(response.statusText);
}, function errorCallback(response) {
console.log("Error");
});
});

Service method not getting fired using .then

Below is my AngularJs code where I am trying to call TalentPoolService.search() after succussfull ProcessCriteria call, however for some reason it not hitting the TalentPool.Service. What am I doing wrong here?
$scope.Search = function (item, SolrLabel) {
if (item != null) {
console.log('Item: ' + item.Key);
console.log('SolrLabel: ' + SolrLabel);
console.log($localStorage.message);
var pvarrData = new Array();
pvarrData[0] = JSON.stringify($localStorage.message);
pvarrData[1] = item.Key;
pvarrData[2] = SolrLabel;
$http({
method: 'POST',
url: '/api/TalentPool/ProcessCriteria',
data: JSON.stringify(pvarrData),
headers: { 'Content-Type': 'application/json' }
}).then(function (response) {
console.log('ProcessCriteria Success fired');
$localStorage.message = response.data;
console.log(response.data);
return response.data;
},
function (response) {
// failed
console.log('facet post error occured!');
}).then(
function () {
TalentPoolService.search().then(function successCallback(response1) {
$scope.talentpoolist = response1.data.model;
$localStorage.message = response1.data.baseCriteria;
console.log('TalentPoolService.search successCallback fired');
setTimeout(function () {
LetterAvatar.transform();
}, 20);
}, function errorCallback(response1) {
$scope.errors = [];
$scope.message = 'Unexpected Error while saving data!!' + response;
})
}
);
}
}
You must return data for chaining to work.
$http({
method: 'POST',
url: '/api/TalentPool/ProcessCriteria',
data: JSON.stringify(pvarrData),
headers: {
'Content-Type': 'application/json'
}
}).then(function(response) {
console.log('ProcessCriteria Success fired');
$localStorage.message = response.data;
console.log(response.data);
return response.data; // **return here**
},
function(response) {
// failed
console.log('facet post error occured!');
}).then(
function() {
TalentPoolService.search().then(function successCallback(response1) {
$scope.talentpoolist = response1.data.model;
$localStorage.message = response1.data.baseCriteria;
setTimeout(function() {
LetterAvatar.transform();
}, 20);
}, function errorCallback(response1) {
$scope.errors = [];
$scope.message = 'Unexpected Error while saving data!!' + response;
})
}
);
Why because, the next then which you are using expects some data to work on. So, if you don't return it can't. So, must return data.

Binding a service response in Angular JS

I am trying to send the http response as a JSON body to an error handler if an error occurs. I am not really sure how to do this as I am a little inexperienced in this area. Here is the relevant code that I have currently:
Controller:
for (var prop in $scope.applicants) {
var applicant = $scope.applicants[prop];
$scope.sendApplicantsToSR(applicant).then(null, $scope.sendATSError.bind(null, applicant));
}
$scope.sendATSError = function (applicant, error) {
return AtsintegrationsService.applicantErrorHandling(applicant.dataset.atsApplicantID);
};
$scope.sendApplicantsToSR = function(applicant) {
return AtsintegrationsService.sendApplicantsToSR(applicant);
};
Service:
srvc.sendApplicantsToSR = function (applicant) {
var applicantURL = {snip};
return $http({
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: 'POST',
url: applicantURL,
data: applicant
});
};
srvc.applicantErrorHandling = function (applicantID, error) {
var url = srvc.url + {snip};
return $http({
method: 'POST',
url: url,
data: { "error_message": error }
});
};
So, ideally, I would like to pass the result of $scope.sendApplicantsToSR to $scope.sendATSError only when an error occurs.
Inside your controller
YourService.getdatafromservice().then(function(SDetails) {
//response from service
console.log(SDetails);
});
Inside your service
return {
getData: getData
};
function getData() {
var req = $http.post('get_school_data.php', {
id: 'id_value',
});
return req.then(handleSuccess, handleError);
function handleSuccess(response) {
response_data = response.data;
return response_data;
}
function handleError(response) {
console.log("Request Err: ");
}
}

AngularJs conversion of service

the title to this is a bit ambiguous I know, but I couldn't think of what to call it :)
Hopefully this description will help.
I have this current "service" which looks like this:
.factory('MoltinApi', ['$cookies', '$q', '$resource', '$http', 'moltin_options', function ($cookies, $q, $resource, $http, options) {
var api = $resource(options.url + options.version + '/:path', {
path: '#path'
});
var authenticate = function () {
if (!options.publicKey)
return;
var deferred = $q.defer();
//var authData = angular.fromJson($cookies.authData);
var authData = false;
if (!authData) {
console.log('from api');
var request = {
method: 'POST',
url: options.url + 'oauth/access_token',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: "grant_type=implicit&client_id=" + options.publicKey
};
deferred.resolve($http(request).success(function (response) {
$cookies.authData = angular.toJson(response);
setHeaders(response.access_token);
}));
} else {
console.log('from cookie');
deferred.resolve(setHeaders(authData.access_token));
}
return deferred.promise;
};
var setHeaders = function (token) {
$http.defaults.headers.common['Authorization'] = 'Bearer ' + token;
}
return authenticate().then(function (response) {
return api;
});
}]);
As you can see, when we authenticate, we then return the api function.
I have decided that using $resource isn't working as good as I had hoped, so I have now tried to change the service to this:
.factory('MoltinApi', ['$cookies', '$q', '$http', 'moltin_options', function ($cookies, $q, $resource, $http, options) {
// Private variables
var headers;
// Build request call
var buildRequest = function (path, method, data) {
var request = {
method: method,
url: options.url + options.version + path,
data: data
};
console.log(headers);
if (headers) {
angular.extend(request, headers)
}
return $http.request(request);
}
// GET
var $get = function (path) {
var request = buildRequest(path, 'GET')
return $http.request(request);
}
// POST
var $post = function (path, data) {
var request = buildRequest(path, 'POST', data)
return $http.request(request);
}
// PUT
var $update = function (path, data) {
var request = buildRequest(path, 'PUT', data)
return $http.request(request);
}
// DELETE
var $delete = function (path) {
var request = buildRequest(path, 'DELETE')
return $http.request(request);
}
// authentication
var authenticate = function () {
if (!options.publicKey)
return;
var deferred = $q.defer();
//var authData = angular.fromJson($cookies.authData);
var authData = false;
if (!authData) {
console.log('from api');
var request = {
method: 'POST',
url: options.url + 'oauth/access_token',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: 'grant_type=implicit&client_id=' + options.publicKey
};
deferred.resolve($http(request).success(function (response) {
$cookies.authData = angular.toJson(response);
headers = { headers: { 'Authorization': 'Bearer ' + response.access_token } }
}));
} else {
console.log('from cookie');
deferred.resolve(
headers = { headers: { 'Authorization': 'Bearer ' + authData.access_token } }
);
}
return deferred.promise;
};
return authenticate().then(function (response) {
// Need to return $post, $get, $update and $delete
});
}]);
But I am at a loss on how to return my methods after we have athenticated...
Can someone help me out?
you need to wrap all the methods into an object, and return the object. Try:
var api = {};
...
api.$get = function (path) {
...
api.$post = function (path, data) {
...
//etc
return authenticate().then(function (response) {
return api;
});

How to call ajax from service in AngularJS?

I have Employee controller which is having property Id, Name , Specification. I have made one Employee service which is having ajax call and get employee list. But every time getting '' in User.
When i debug the code i found that it call success first and then it goes for Ajax call.
When i do ajax call without service it works fine.
angular.module('EmployeeServiceModule', [])
.service('EmployeeSer', ['$http',function ($http) {
this.Users = '';
this.errors = '';
this.SearchEmployee = function () {
// Ajax call
$http({
method: 'GET',
url: '/Home/GetEmployeeList',
params: { filterData: 'Test' },
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(onSuccess, onError);
var onSuccess = function (response) {
this.userUsers = response.data;
this.errors = '';
};
var onError = function (reason) {
this.userUsers = reason;
this.errors = "Error in retrieving data.";
};
return this.Users;
}
}]);
angular.module('Employee', ['EmployeeServiceModule'])
.controller('EmployeeController', ['EmployeeSer', '$scope', '$http', function (EmployeeSer, $scope, $http) {
this.Id = '';
this.name = '';
this.expertise = '';
$scope.repoSortOrder = 'id';
$scope.filterField = '';
// Call to service
this.GetAllEmployee = function () {
// Initiates the AJAX call
$scope.User = EmployeeSer.SearchEmployee();
// Returns the promise - Contains result once request completes
return true;
};
this.AddEmployee = function () {
var empData = {
Id: $("#txtId").val(),
Name: $("#txtName").val(),
Expertise: $("#expertise").val()
};
$http({
method: 'POST',
url: '/Home/Create',
params: JSON.stringify(empData),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(onSuccess, onError);
// Returns the promise - Contains result once request completes
return true;
};
var onSuccess = function (response) {
$scope.user = response.data;
$scope.error = '';
};
var onError = function (reason) {
$scope.error = "Error in retrieving data.";
};
}]);
It's because you are returning the users before the data is fetched from the server. Also it doesn't seem like you are assigning them correctly.
Here are two ways to solve the problem:
Firstly. You bind your controller user-data to the user-data in the service.
angular.module('EmployeeServiceModule', [])
.service('EmployeeSer', ['$http',function ($http) {
this.Users = '';
this.errors = '';
$http({
method: 'GET',
url: '/Home/GetEmployeeList',
params: { filterData: 'Test' },
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(onSuccess, onError);
var onSuccess = function (response) {
this.Users = response.data;
this.errors = '';
};
var onError = function (reason) {
this.users = null;
this.errors = "Error in retrieving data.";
};
}
}]);
angular.module('Employee', ['EmployeeServiceModule'])
.controller('EmployeeController', ['EmployeeSer', '$scope', '$http', function (EmployeeSer, $scope, $http) {
this.users = EmployeeSer.users;
EmployeeSer.SearchEmployee();
}]);
And the second way would be to return the promise in the service and unwrap it in the controller.
angular.module('EmployeeServiceModule', [])
.service('EmployeeSer', ['$http',function ($http) {
this.SearchEmployee = function () {
return $http({
method: 'GET',
url: '/Home/GetEmployeeList',
params: { filterData: 'Test' },
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
}
}]);
angular.module('Employee', ['EmployeeServiceModule'])
.controller('EmployeeController', ['EmployeeSer', '$scope', '$http', function (EmployeeSer, $scope, $http) {
this.GetAllEmployee = function () {
EmployeeSer.SearchEmployee()
.then(onSuccess, onError)
};
var onSuccess = function (response) {
$scope.user = response.data;
$scope.error = '';
};
var onError = function (reason) {
$scope.error = "Error in retrieving data.";
};
}]);
OFF TOPIC
You should probably consider using ngModel instead of jQuery to get you data to the controller.
Not like this:
var empData = {
Id: $("#txtId").val(),
Name: $("#txtName").val(),
Expertise: $("#expertise").val()
};
// Here serverRequest is my service to make requests to the server
serverRequest.postReq = function(url, data, sucessCallback, errorCallback){
$http({
method: 'POST',
url: urlToBeUsed,
data:data,
headers : {'Content-Type': 'application/x-www-form-urlencoded'}})
.success(function(data, status, headers, config) {
sucessCallback(data);
})
.error(function(data, status, headers, config){
errorCallback(data);
})
}
// In the controller
serverRequest.postReq('urlToBeCalled', dataToBeSent, scope.successCb, scope.errorCb);
scope.successCb = function(data){
// functionality to be done
}
scope.errorCb = function(data){
// functionality to be done
}
Try it this way your problem might be solved
Promise must be unwrapped in your controller if you want to use it

Categories

Resources