winzip
November 20, 2017, 10:05am
1
Hi,
I get undefined message in this code.
This is my controller code: // notations are standard
$scope.searchOutputLst=[];
$scope.searchOutputLst=MyService.retrieveData($scope.caasSearch); // this http call returns data : an array of objects
console.log($scope.searchOutputLst); // prints undefined
why its printing undefined ? what is the issue ? how to fix it ?
I am using angular js 1.3
I stab a guess at MyService.retrieveData()
being an asynchronous operation.
winzip:
how to fix it ?
use a callback.
winzip
November 20, 2017, 10:12am
3
Dormilich:
use a callback.
yes …asynchronous operation…you are right
Here is the code : MyService
this.retrieveData = function (newSearch) {
$http.post(searchUrl + '/search', newSearch)
.then(function(result) {
console.log("result");
console.log(result.data); // I get print : array of objects
return result.data;
})};
How do I use callback in this situation ?
I need controller to wait and populate my $scope.searchOutputLst and then move on.
Will callback help me with that ?
this.retrieveData = function (newSearch) {
return $http.post(searchUrl + '/search', newSearch)
.then( result => result.data )
};
MyService.retrieveData($scope.caasSearch).then(function (data) {
console.log(data)
})
You only have two options: either you use a callback, or you fire an event.
winzip
November 20, 2017, 10:20am
6
Dormilich:
result => result.data
what is the alternate way to write that ? I’m not comfortable with that arrow.
Is there any way to avoid that arrow and use simple syntax ?
result => result.data is effectively the same (if you ignore how the this keyword is handled) as:
function (result) {
return result.data;
}
winzip
November 20, 2017, 10:24am
8
okay…will try this out … will it work on angular js 1.3 ?
it will work on any Angular, as long as the browser supports JavaScript2015 or you use the babel transpiler.
All you need is JavaScript for it to work.
There are further details about arrow functions at the ES6 Arrow Functions: The New Fat & Concise Syntax in JavaScript article.
winzip
November 20, 2017, 10:29am
11
okay…checking it now …will update in 5 minutes
winzip
November 20, 2017, 10:40am
12
Not working …its printing BLANK …Here is my actual code for your convenience
controller
$scope.customerSearchOutputLst=[];
//$scope.customerSearchOutputLst=CustomerService.retrieveSearchCustomer($scope.caasCustomerSearch);
CustomerService.retrieveSearchCustomer($scope.caasCustomerSearch).then(function (data) {
console.log(data);
$scope.customerSearchOutputLst=data;
})
console.log("result$$$$$");
console.log($scope.customerSearchOutputLst); // its printing BLANK
service code
this.retrieveSearchCustomer = function (newCustomerSearch) {
return $http.post(customerUrl + '/searchcustomer', newCustomerSearch)
.then(result=>result.data)
};
Is there anything wrong ? what I am doing wrong ?
m3g4p0p
November 20, 2017, 11:13am
13
That’s because $scope.customerSearchOutputLst
still doesn’t have any value assigned to it – the $http
request is still pending at that point. If you leave aside the implementation details, the the flow of events is comparable to a timeout:
var data = null;
window.setTimeout(function () {
data = 'foo'
console.log(1, data)
}, 1000)
console.log(2, data)
This will immediately log 2 null
to the console, and only after one second 1 "foo"
. So all code that depends on operations inside the callback has to be in the callback as well.
As an alternative, AngularJS provides a mechanism to watch to changes of $scope
properties like this (note that you have to explicitly trigger the digest-cycle though):
$scope.data = null
window.setTimeout(function () {
$scope.data = 'foo'
$scope.$digest()
}, 1000)
$scope.$watch('data', function () {
console.log($scope.data) // Will first log null, and after one second "foo"
})
winzip
November 20, 2017, 11:43am
14
I can not use 1000 …because Its not possible to know the http response time.
How do you resolve this ?
You can use $q.all which is only resolved when all of the promises are resolved.
$scope.fromThen = $q.all([
p1.then(thenFn),
p2.then(thenFn)
])
.then(function(values) {
console.log(values);
return values;
});
You can see a good example of in use at http://jsfiddle.net/ThomasBurleson/QqKuk/
1 Like
m3g4p0p
November 20, 2017, 12:13pm
16
Exactly, this is why your code above doesn’t work. The timeout was just an example (a simple $http
mock if you like) to demonstrate that the order of the lines of code doesn’t necessarily reflect the order in which the code is getting executed.
winzip
November 20, 2017, 12:22pm
17
I could not find any example how $q can be used with $http . I need an example towards that.
this is very much confusing.
$http returns a promise, and $q.all accepts an array of promises.
winzip
November 20, 2017, 12:44pm
19
okay…I’m giving it a try with $q now
I am getting inject error with $q…not able to figure it out whats wrong .
Here is the code:
Service code:
app.service('CustomerService', ['$http','$q' function ($http,$q) {
var customerUrl="some url";
this.retrieveSearchCustomer = function (newCustomerSearch) {
var deferred = $q.defer();
$http.post(customerUrl + '/searchcustomer', newCustomerSearch)
.then(function(response){
deferred.resolve(response.data);
})
.catch(function(response){
deferred.reject(response);
});
return deferred.promise;
}
}]);
Controller code:
CustomerService.retrieveSearchCustomer($scope.caasCustomerSearch).then(function(data){
console.log("result$$$$$");
$scope.customerSearchOutputLst= data;
})
.catch(function(response){
console.log(response.status);
});
I am getting Inject error after deploy
Error:
angular.min.js:sourcemap:101 Error: [$injector:unpr] http://errors.angularjs.org/1.3.0/$injector/unpr?p0=CustomerServiceProvider%20<-%20CustomerService
whats wrong ?
also please let me know if I’m using the $q correctly in my code. …do you think any changes required ?
It looks like you’re missing a comma from the top line.