I am pretty new to AngularJS and Javascript. I am creating a app in which I am planning to use one function to do all ajax related operation(factory in angularjs).
This function will be only one gateway for all ajax operations. When I return promise as a success it works properly. but returning error promise do not work.
Here is a sample code. I am expecting return of promise in error function if promise fails but it goes to success
var myApp = angular.module('myApp', []);
myApp.controller('FirstController, function($scope, util){
util.doAjax().then(function(response){
// This function is called in both success and error
}, function(err){
// This is never called why ?
});
});
myApp.factory('util, function($http){
return $http({
method: 'GET',
url: 'http://www.example.com'
}).then(function(response){
// This will return success promise
return response;
}, function(err){
// This should return error promise
return err;
});
});
Currently you are directly returning a data from error function, which is chaining the promise and calling it underlying .then method.
While returning an error you have to reject a promise by creating a new custom promise using $q
return $q.reject(err)
Other important thing is, you should create method in a service with name
myApp.factory('util', function($http, $q){
//Exposed method
return {
doAjax : function() {
return $http({
method: 'GET',
url: 'http://www.example.com'
}).then(function(response){
// This will return success promise
return response.data; // returned data
}, function(err){
// return error promise with err object
return $q.reject(err);
});
}
}
});
This way you are not returning a promise.
You must return the $http promise instead like so:
myApp.factory('util', function($http){
return {
ajax: function () {
var httpPromise = $http({
method: 'GET',
url: 'http://www.example.com'
});
httpPromise.then(function(response){
// This will return success promise
// return response;
}, function(err){
// This should return error promise
// return err;
});
return httpPromise;
};
});
And also, return inside promise resolutions are not needed, you can use it for loggin and stuff but it doesn't require a return value because it is the resolution it self.
Related
I have a function getPackageName, and inside this function i defined a promise , i need to save the value of this promise and return the value outside , so whenever i call getPackageName,it will return promise result value ...
getPackageName(modelName){
let modelReq = new Ext.Promise(function(resolve, reject){
Ext.Ajax.request({
url: `db/code/pkgname?tablename=${modelName}`,
method: 'GET',
callback: function(options, success, response){
if (success){
if (response){
resolve(response);
}
else{
console.log("No response from server");
}
}
});
});
modelReq.then(res){
return res.res
}
}
it's not working as expected , and whenever i call getPackageName, it will return undefined .
Any help would be appreciated for sure .
I am trying to delete a post from a list. The delete function is performing by passing serially to a delete function showed below.
$scope.go = function(ref) {
$http.get("api/phone_recev.php?id="+ref)
.success(function (data) { });
}
After performing the function, I need to reload the http.get request which used for listing the list.
$http.get("api/phone_accept.php")
.then(function (response) { });
Once the function performed. The entire list will reload with new updated list. Is there any way to do this thing.
Try this
$scope.go = function(ref) {
$http.get("api/phone_recev.php?id="+ref)
.success(function (data) {
//on success of first function it will call
$http.get("api/phone_accept.php")
.then(function (response) {
});
});
}
function list_data() {
$http.get("api/phone_accept.php")
.then(function (response) {
console.log('listing');
});
}
$scope.go = function(ref) {
$http.get("api/phone_recev.php?id="+ref)
.success(function (data) {
// call function to do listing
list_data();
});
}
Like what #sudheesh Singanamalla says by calling the same http.get request again inside function resolved my problem.
$scope.go = function(ref) {
$http.get("api/phone_recev.php?id="+ref).success(function (data) {
//same function goes here will solve the problem.
});}
});
You can use $q - A service that helps you run functions asynchronously, and use their return values (or exceptions) when they are done processing.
https://docs.angularjs.org/api/ng/service/$q
Inside some service.
app.factory('SomeService', function ($http, $q) {
return {
getData : function() {
// the $http API is based on the deferred/promise APIs exposed by the $q service
// so it returns a promise for us by default
return $http.get("api/phone_recev.php?id="+ref)
.then(function(response) {
if (typeof response.data === 'object') {
return response.data;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
};
});
function somewhere in controller
var makePromiseWithData = function() {
// This service's function returns a promise, but we'll deal with that shortly
SomeService.getData()
// then() called when gets back
.then(function(data) {
// promise fulfilled
// something
}, function(error) {
// promise rejected, could log the error with: console.log('error', error);
//some code
});
};
I'm trying to submit a form that require that the user email is not duplicated, but I want to make an small animation before the POST request. In the $scope.process function I'm getting:
TypeError: Cannot read property 'catch' of undefined.
That's happening because $scope.process is returning before the $http.post is complete, but how can I make process() return the promise instead of undefined?
So, this is what I have so far:
//The submit form function
$scope.submitForm = function () {
$('.btn').attr('disable');
if ($scope.form.$valid) {
$scope.process($scope.account)
.catch(function (err) {
if (err.code === 'duplicate') {
// handle error
}
});
return false;
}
};
//This is the one in charge to send the request
$scope.process = function(body) {
// Timeout before http post to wait for animation
$timeout(function() {
return $http.post(postUrl, body).then(function (response) {
// This return a promise if I remove the $timeout
var nextPage = response.data;
}).catch(function (err) {
throw err;
});
}, 300);
// Return undefined due to $timeout
};
Thanks in advance.
You were getting TypeError: Cannot read property 'catch' of undefined, because you weren't returning promise from process function at all.
Do return $timeout promise from process function & apply .then & .catch over $timeout promise object.
By returning $timeout service the inner $http.post will return a data, so that will make proper chaining mechanism.
Code
$scope.process = function(body) {
// returned promise from here
return $timeout(function() {
//returned $http promise from here.
return $http.post(postUrl, body).then(function (response) {
// This return a promise if I remove the $timeout
nextPage = response.data;
return nextPage; //return data from here will return data from promise.
}).catch(function (err) {
throw err;
});
}, 300);
};
I am trying to reject a deferred object within a $http.get call but it is not being properly rejected. The errorcallback is not being called, and I just can't figure out why.
Here is basically what I have:
var promise = this.SomeAsyncCall(this.$.SomeID)
.then(
function ()
{
service.SendAsyncDownloadReqeuest(someOtherID);
},
this.ErrorHandler.HandleError)
.then(this._DownloadInitiated, this.ErrorHandler.HandleError);
promise["finally"](this._DownloadRequestFinished);
And here is the service.SendAsyncDownloadRequest:
var SendAsyncDownloadReqeuest = function (ID)
{
var url = "someUrl?ID=" + customerID;
var navigator = self.$window.navigator;
var window = self.$window;
var deferred = self.$q.defer();
self.$http.get(url, { responseType: 'arraybuffer' })
.success( function(data, status, headers) {
var success = false;
//Initiate download via blob. Set success
success ? deferred.resolve() : deferred.reject();
})
.error(function (data, status)
{
var error =
{
//Some error properties
}
deferred.reject(error);
});
return deferred.promise;
};
When I test this by returning a 500 status code from the server, it reaches the .error block of the http get call and completes the reject line, but the ErrorHandler's HandleError method is not reached. The HandleError method is correct since it works with errorcallbacks for promises rejected in anything that's not $http.get.
You're never passing the promise from service.SendAsyncDownloadReqeuest(someOtherID); back to your HandleError function. You need to change your code to this:
var promise = this.SomeAsyncCall(this.$.SomeID)
.then(
function ()
{
return service.SendAsyncDownloadReqeuest(someOtherID);
},
this.ErrorHandler.HandleError)
.then(this._DownloadInitiated, this.ErrorHandler.HandleError);
promise["finally"](this._DownloadRequestFinished);
If you want to be a little clearer you could change it to this:
var promise = this.SomeAsyncCall(this.$.SomeID)
.then(function () {
service.SendAsyncDownloadReqeuest(someOtherID).then(
this._DownloadInitiated,
this.ErrorHandler.HandleError);
},
this.ErrorHandler.HandleError);
promise["finally"](this._DownloadRequestFinished);
Don't use the success method either way.Both methods have been deprecated.
The $http legacy promise methods success and error have been
deprecated. Use the standard then method instead. If
$httpProvider.useLegacyPromiseExtensions is set to false then these
methods will throw $http/legacy error.
Here is the shortcut method
$http.post('/someUrl', data, config).then(successCallback, errorCallback);
Here is a longer GET method sample
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Official Documentation
i've a function that return a boolean according to http.get call.
function checkValue (value) {
var defer = $q.defer();
var request = $http({
method: "get",
url: "someurl"
});
request.success(function (data) {
defer.resolve(data.response);
});
return defer.promise;
}
The problem is that return value is an object like this:
d {$$state: Object}
$$state: Object
status: 1
value: true
__proto__: Object
__proto__: d
How could i resolve it?
Yes, your function is returning a Promise object. The $$state property belongs to the promise object and is used by Angular internally (as suggested by $$ prefix) and therefore not to be used by developers using Angular. More interesting is that promise object has a "then" method which can be used to attach handlers that are called when the promise gets resolved. Promise gets resolved when the defer object related to the promise is resolved.
So, you could use your code as
checkValue.then(function (data) {
// This is called when the XHR response comes in and
// defer.resolve() is called in the checkValue function.
});
But, there is a better approach to this. Using promise chaining.
Which essentially removes the need to create a new defer object.
function checkValue (value) {
return $http({
method: "get",
url: "someurl"
}).then(function (data) {
return data.response;
});
}
Explaining everything about how Promises work is may be too much for this post. There are already awesome works done on that.
But, basically, $http already returns a promise. So you can just use this promise instead of creating a new one. The end usage of the function remains exactly the same as the snippet above.
BTW, .success() handlers are deprecated. So better start using .then() on your apps already.
Since you are using Promise, you need to use .then callback in order to get response or error:
function checkValue (value) {
var defer = $q.defer();
var request = $http({
method: "get",
url: "someurl"
});
request.success(function (data) {
defer.resolve(data.response);
});
return defer.promise;
}
var promise = checkValue('Hello World');
promise.then(function(response) {
//success
console.log(response);
}, function(reason) {
//failed
console.log(reason);
});
then(successCallback, errorCallback, notifyCallback) – regardless of
when the promise was or will be resolved or rejected, then calls one
of the success or error callbacks asynchronously as soon as the result
is available. The callbacks are called with a single argument: the
result or rejection reason. Additionally, the notify callback may be
called zero or more times to provide a progress indication, before the
promise is resolved or rejected.
But the optimized approach would be using $http's inbuilt promise instead of creating a new one.
var request = $http({
method: 'GET',
url: '/someUrl'
});
request.then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
You should try this,
function checkValue (value) {
return $q(resolve, reject) {
$http({
method: "get",
url: "someurl"
}).success(function (data) {
resolve(data.response);
}).then (function (error) {
reject(error);
});
}
}
This will resolve your data