How to call ajax from service in AngularJS? - javascript

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

Related

How to Pass Data in Angularjs

firstapp
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http.get("welcome.htm").then(function (response) {
$scope.myWelcome = response.data;
});
});
sencond app
var app = angular.module('myApp2', []);
app.controller('myCtrl2', function($scope, $http) {
$http.get("fsd.htm").then(function (response) {
$scope.myWelcome = response.data;
});
});
How to Pass data from one app to another app in angularjs ?
You can use shared service to communicate between two angular apps.
However using multiple apps is not a good practice unless it is the only option left.
angular.module('sharedService', []).factory('SharedService', function() {
var SharedService;
SharedService = (function() {
function SharedService() {}
SharedService.prototype.setData = function(name, data) {};
return SharedService;
})();
if (typeof(window.angularSS) === 'undefined' || window.angularSS === null) {
window.angularSS = new SharedService();
}
return window.angularSS;});
angular.module("angularApp1", ['sharedService'])
/*code */
angular.module("angularApp2", ['sharedService'])
/*code */
Create function like this in Service Lyaer
editTool: function(yourData) {
var basicAuth = YOurauthenticateFuntion;
var url = 'url';
var deferred = $q.defer();
$http.post(url, yourData, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': basicAuth
}
}).then(function(data) {
if(data.status == 200) {
deferred.resolve(data.data);
} else {
deferred.reject(data);
}
}, function(error) {
deferred.reject(error);
});
return deferred.promise;
}
and then can call in any controller using factory name.. that you have created for serviceCalls

call $http in response of another http - angular js

I am new on angular JS. I am tried to implement $http in the response of $http.
My issue is that when i call $http in response of anoter $http. It doesn't show the data on view. The view is rendered before the second $http call. I have used promises but no luck. Here is the code from other answer which i used by changing a little.
angular.module('App', [])
.controller('Ctrl', function($scope, resultsFactory) {
resultsFactory.all().then(
function(res){
$scope.results = res;
},
function(err){
console.error(err);
}
);
})
.factory('resultsFactory', function($http, $timeout, $q) {
var results = {};
function _all(){
var d = $q.defer();
$http({
url: url,
method: 'POST'
}).then(function (response) {
var f = {};
f.id = response.data.id;
f.name = response.data.name;
$http({
url: url,
data: "id="+response.data.parent_id,
method: 'POST'
}).then(function (response1) {
f.parentname = response1.name;
d.resolve(f);
});
});
return d.promise;
}
results.all = _all;
return results;
});
The id and name is shown properly on view but it is showing nothing for parent name. I have debug it. It is undefined when rendering view. After rendering it is setting their value to parentname. Can any one help me to resolve this issue?
You shouldn't need a deferred for this: just chain the promises:
return $http({
url: url,
method: 'POST'
}).then(function (response) {
var data = {};
data.id = response.data.id;
data.name = response.data.name;
return $http({
url: url,
data: "id="+response.data.parent_id,
method: 'POST'
}).then(function (response1) {
data.parentname = response1.name;
return data;
});
});
You overwrote your d variable...
.factory('resultsFactory', function ($http, $timeout, $q) {
var results = {};
function _all() {
var d = $q.defer();
$http({
url : url,
method : 'POST'
}).then(function (response) {
var secondD = {};
secondD.id = response.data.id;
secondD.name = response.data.name;
$http({
url : url,
data : "id=" + response.data.parent_id,
method : 'POST'
}).then(function (response1) {
secondD.parentname = response1.name;
secondD.resolve(d);
});
});
return d.promise;
}
results.all = _all;
return results;
});

Services in AngularJS with YoutubeAPI v3

I've used services once before (still not very good at it) and I've encountered a lot of issues already, so know I'm going to ask (I think my problem is easy AF:) )
I need to get some ChannelDetails with the use of YoutubeApi v3.
My Service:
appApi.factory('ServiceAPI', ['$http', function($http) {
var factory = {};
factory.channelDetails = function(channelname){
return $http.get('https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername='+channelname+'&key=AIzaSyDQv-WpATIWLinCB3H_sH4W1sKx7plyvRA')
.success(function(data) {
return data;
})
.error(function(data) {
return data;
});
}
}]);
then my controller:
var appApi = angular.module('YoutubeAPI', ['ngRoute'])
appApi.controller('youtubeCTRL', ['$scope','$http','$q','ServiceAPI', function ($scope, $http, $q, ServiceAPI) {
$scope.channel = [];
//GET Id on channelname
$scope.saveNewchlName = function () {
var channelname = $scope.newchlName;
$scope.channelDetails = function(channelname){
ServiceAPI.channelDetails(channelname).success(function (data) {
$scope.newchannelNames = {
channelName: $scope.newchlName,
channelId: data.items[0].id,
playlistId: data.items[0].contentDetails.relatedPlaylists.uploads
};
console.log($scope.newchannelNames)
$http({
method: 'POST',
url: 'http://localhost:8080/api/resources/channelNames/',
data: $scope.newchannelNames,
dataType: 'json'
}).success(function (data) {
$scope.channel.push(data);
console.log('SUCCESS!');
$scope.error = null;
}).error(function (data, status) {
if (status == 401) {
$scope.error = "You are not authenticated to Post these data";
return;
}
$scope.error = data;
});
});
}
}
My problem is that I keep encounter problems with injection. Now I got one which says: Provider 'ServiceAPI' must return a value from $get factory method.
I need to implement the channelname within the URL to get the specific details.
This seems to work.
Service:
appApi.factory('ServiceAPI', ['$http', function($http) {
var factory = {};
factory.channelDetails = function(channelname, success, error){
var promise = $http.get('https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername='+channelname+'&key=AIzaSyDQv-WpATIWLinCB3H_sH4W1sKx7plyvRA')
if(success){
promise.success(success);
}
if(error){
promise.error(error);
};
}
return factory;
}]);
controller:
var appApi = angular.module('YoutubeAPI', ['ngRoute'])
appApi.controller('youtubeCTRL', ['$scope','$http','$q','ServiceAPI', function ($scope, $http, $q, ServiceAPI) {
$scope.channel = [];
$scope.video = [];
var pagetokenarr = [];
//GET Id on channelname
$scope.saveNewchlName = function () {
var channelname = $scope.newchlName;
ServiceAPI.channelDetails(channelname, function(data){
$scope.newchannelNames = {
channelName: $scope.newchlName,
channelId: data.items[0].id,
playlistId: data.items[0].contentDetails.relatedPlaylists.uploads
};
console.log($scope.newchannelNames)
$http({
method: 'POST',
url: 'http://localhost:8080/api/resources/channelNames/',
data: $scope.newchannelNames,
dataType: 'json'
}).success(function (data) {
$scope.channel.push(data);
console.log('SUCCESS!');
$scope.error = null;
}).error(function (data, status) {
if (status == 401) {
$scope.error = "You are not authenticated to Post these data";
return;
}
$scope.error = data;
});
});
}

Can not read property then of undefined error in angular JS

This is my angularJS service and controller.
sampleApp.factory('BrandService', function($http, $q) {
var BrandService = {};
var BrandList = [];
BrandService.GetBrands = function() {
var Info = {};
Info.Action = "GET";
Info = JSON.stringify (Info);
var req = {
url: BrandURL,
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: Info
};
if ( BrandList.length == 0 )
{
$http(req)
.success(function(response) {
BrandList = response.data
alert ('Brand Fetching is successful');
return response.data;
})
.error(function (data, status, headers, config) {
alert ('Brand Fetching Error');
alert (status);
alert (data);
});
}
else
{
var deferred = $q.defer();
deferred.resolve(BrandList);
return deferred.promise;
}
}
return BrandService;
});
sampleApp.controller('BrandController', ['$scope', 'BrandService', function ($scope, BrandService){
$scope.Brands = [];
$scope.GetBrands = function() {
BrandService.GetBrands().then(function(data) {
$scope.Brands = data;
});
};
$scope.GetBrands();
}]);
When controller is loading I m seeing the following error.
Cannot read property 'then' of undefined
at l.$scope.GetBrands (Controllers.js:337)
Can please someone help me what i m doing wrong?
You are not returning promise in case of HTTP request when data is not yet cached.
Correct code would be:
sampleApp.factory('BrandService', function($http, $q) {
var BrandService = {};
var BrandList = [];
BrandService.GetBrands = function() {
var req = {
url: BrandURL,
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
data: JSON.stringify({Action: 'GET'})
};
if (BrandList.length) {
return $q.when(BrandList);
}
return $http(req)
.success(function(response) {
BrandList = response.data
alert('Brand Fetching is successful');
return response.data;
})
.error(function(data, status, headers, config) {
alert('Brand Fetching Error');
alert(status);
alert(data);
});
}
return BrandService;
});
Also you don't need to create dummy deferred object, you can return resolved promise with $q.when.

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;
});

Categories

Resources