call $http in response of another http - angular js - javascript

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

Related

How to call other service from one service response in AngularJS?

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http.get("myservice").then(function (response) {
$scope.studentdata = response.data;
});
});
Based on student data i need to call other service like student address.how to achieve i am new to angular js please help.
You need to use promise chains to call the request after another
function firstReq(){
return $http({
method: 'POST',
url: 'http://localhost/api/users',
headers: {'Content-Type': 'application/json'},
data: JSON.stringify($scope.user)
})
}
function secondReq(){
return $http({
method: 'POST',
url : 'http://localhost/api/users/' +$scope.user_id + '/accessTokens',
})
}
$scope.processform = function() {
firstReq()
.then( function( response )
{
console.log(response.data.user_id);
$scope.user_id = response.data.user_id;
return secondReq();
})
.then(function(response){
console.log(response.data);
})
}

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

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.

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

Angular promises using multiple http requests

I have read a few forum posts before on angular promises but can't get it to work in my instance. I am using nodejs /locomotive for the backend and Angular form the frontend.
I have the following code in a controller, basically I want to use the path to slides.path, how would I go about doing this using promises? any help would be gratefully received.
function ProductCtrl($scope, $http, $q) {
$scope.events = [];
$scope.times = [];
var html = [];
var chapters = [];
var path;
//var paPromise = $q.defer();
$http({
url: '/show',
method: 'GET',
params: { eventid:$scope.$routeParams.eventid}
}).success(function(response, code) {
$scope.events = response;
angular.forEach($scope.events.slides, function(slide) {
$http({
url: '/upload',
method: 'GET',
params: {uploadid: slide.upload.toString()}
}).success(function(response, code) {
return "http://www.example.com/"+response.path;
},path);
slide.path = path;
chapters.push(slide);
});
});
}
You can use $q.all do get this multiple promise problem done. Like this:
function ProductCtrl($scope, $http, $q) {
$scope.events = [];
$scope.times = [];
var html = [];
var path;
function fetchChapter() {
var chapters = [];
var httpPromise = $http({
url: '/show',
method: 'GET',
params: {
eventid: $scope.$routeParams.eventid
}
});
//Return the value http Promise
return httpPromise.then(function (response) {
$scope.events = response;
var promises = [];
angular.forEach($scope.events.slides, function (slide) {
var inPromise = $http({
url: '/upload',
method: 'GET',
params: {
uploadid: slide.upload.toString()
}
}).then(function (response, code) {
//each promise makes sure, that he pushes the data into the chapters
slide.path = "http://www.example.com/" + response.path;
chapters.push(slide);
});
//Push the promise into an array
promises.push(inPromise);
});
//return the promise from the $q.all, that makes sure, that all pushed promises are ready and return the chapters.
return $q.all(promises).then(function () {
return chapters;
});
});
}
fetchChapter().then(function(chapters){
//populate here
});
}
The httpPromise will return the promise from $q.all.
EDIT: How to fetch the data then
Wrap a function around, i did with fetchChapter and pass a function into the then there will be the value you need as a parameter.

Categories

Resources