I am a newbie to AngularJs world - I am trying to get data from two REST WS calls.
First one returns a set of data (works fine)- using the value of data from frist one I need to make another webservice call and retrive the data and print in a table.
Below is what I have tried so far: HTML:
<table ng-table="tableParams" id="request_table" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Number</th>
<th>Price</th>
<th>Short Description</th>
<th>Requested for</th>
<th>State</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="request in req_list | orderBy:sortType:sortReverse | filter: searchItem">
<p ng-repeat="item in fetchRequest(request.price)"></p>
<td>{{request.number }}</td>
<td>{{request.price}}</td>
<td>{{request.short_description}}</td>
<td>{{request.requested_for.display_value}}</td>
<td>{{request.stage}}</td>
</tr>
</tbody>
Script:
angular.module('sc_request_list')
.controller('MyRequestItems', [
'$scope',
'$http',
function($scope, $http) {
$scope.sortType = 'number' //set the default sort type
$scope.sortReverse = false; // set the default sort order
$scope.searchItem // set the default search/filter term
$scope.itemUrl = '/api/sc_request';
$scope.reqUrl = '/api/sc_req_item';
$http.defaults.headers.common.Accept = "application/json";
$scope.fetchRequestItemList = function() {
$http({
method: 'GET',
url: $scope.itemUrl,
}).
success(function(data, status) {
var result = data;
var json = JSON.stringify(result);
var data = JSON.parse(json);
$scope.req_list = data.result; // response data
}).
error(function(data, status) {
$scope.req_list = [{
"req_list": "Error fetching list"
}];
});
}
$scope.fetchRequest = function(request) {
console.log("Request Number is: " + request);
$http({
method: 'GET',
url: $scope.reqUrl + "/" + request,
}).
success(function(data, status) {
var result = data;
var json = JSON.stringify(result);
var data = JSON.parse(json);
$scope.req = data.result; // response data
}).
error(function(data, status) {
$scope.req = [{
"req": "Error fetching list"
}];
});
}
}
]);
Any help much appreaciated.
I would do it like that, with the second call inside the success response.
function getFirstItem(){ // Here I declare a function that will return a promise.
return $http({
method: 'GET',
url: $scope.itemUrl
});
}
function getDependantItem(){ // I declare a second function that returns a promise
return $http({
method: 'GET',
url: $scope.otherUrl
});
}
$scope.fetchRequest = function(request) { // Here is a function that can be called by the view.
getFirstItem()
/*
* I call the first function that returns a promise.
* the "then" is just setting a
* callback that will be executed when your server will respond.
* The next thing the code does, after registering the callback,
* is going to the end of your function,
* and return nothing.
*/
.then(function(result1){
$scope.req = result1.result; // Now that the server has answered, you can assign the value to $scope.req, and then, call the second function.
getDependantItem().then(function(result2){
// This is still an async call. The code keeps on running, and
// you will only have this callback running when your server will have responded
// Handle your response here and assign your response to a $scope variable.
}, function(error2){
// If an error happened during the second call, handle it here.
});
}, function(error1){
// If an error happened during first call, handle it here.
});
// If you want to return something, you must do it here.
// Before your promises would ever be resolved
// That's the reason why you got an undefined
};
Few things can be noted about your code :
Avoid .success
and .error
, use .then(function(success){}, function(error){});
. The 2 firsts are deprecated from most of the frameworks, and the angular doc doesn't speak about it at all anymore.
https://docs.angularjs.org/api/ng/service/$q
Avoid putting everything in the $scope. Just put things that need to be shared with the view, or other controllers.
ASAP, learn about services to share functionalities, and have 1 layer of your application responsible for 1 thing
With $q service, you can chain your promise objects like this:
$scope.fn1 = function(){
var deferred = $q.defer();
$http.({ method: 'GET', url: 'YOUR_1st_API' }).success(function(data){
deferred.resolve(data);
});
return deferred.promise;
}
$scope.fn2 = function(data){
var deferred = $q.defer();
$http.({ method: 'GET', url: 'YOUR_2nd_API' }).success(function(data){
deferred.resolve(data);
});
return deferred.promise;
}
// after $scope.fn1() is done pass data with resolve method to $scope.fn2() , now you can access data from fn1 inside fn2
$scope.fn1().then($scope.fn2);
And it would be better if you separate your business logic like data fetching to "service" or "factory" and inject them to your controller. With this way your code will be a lot easier to read and maintain.
More info for $q service
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With