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 .
Related
I want to wait constructor() which has async method handled by Promise
What I want to do is waiting two async method in constructor, and then wait constructor itself.
However my code shows the error Uncaught (in promise) ReferenceError: resolve is not defined
What is the best practices for this purpose??
class MyClass{
constructor(){
var p1 = new Promise(function(resolve, reject){
$.ajax({
type: "GET",
url: api1
success: function(response) {
console.log(response);
resolve();
}
});
});
var p2 = new Promise(function(resolve, reject){
$.ajax({
type: "GET",
url: api2
success: function(response) {
console.log(response);
resolve();
}
});
});
Promise.all([p1,p2]).then(function(value){
console.log("finish");
resolve(); // this shows error.
});
}
}
$(function() {
var temp = new Promise(function(resolve,reject){
var myClass = new MyClass();
});
temp.then(function (value) {
console.log("finish all");
});
}
A constructor will always run synchronously. In addition to that, you don't want the explicit Promise construction anti-pattern, so you wouldn't want to call resolve inside a Promise.all anyway. The Promise.all([p1,p2]) will be a Promise that resolves when both p1 and p2 have resolved, so assign that a property to the instance, and call .then on that property. Change
Promise.all([p1,p2]).then(function(value){
// ...
});
to
this.apiPromises = Promise.all([p1,p2]);
and, when constructing the instance:
$(function() {
const myInstance = new MyClass();
myInstance.apiPromises
.then(function (value) {
console.log("finish all");
})
.catch((error) => {
// handle errors
});
});
(If you aren't calling either of the resolves of with anything in p1 or p2, best to delete the value parameter, since it holds no useful information)
$.ajax returns a thenable already, so you don't need to call new Promise when creating the p1 and p2s:
var p1 = $.ajax({
type: "GET",
url: api1, // remember to put commas after values in an object to avoid a SyntaxError
success: function(response) {
console.log(response);
}
});
var p2 = $.ajax({
type: "GET",
url: api2, // remember to put commas after values in an object to avoid a SyntaxError
success: function(response) {
console.log(response);
}
});
(using the above will also properly reject the Promise.all when an error occurs)
I feel like this is really easy, but I can not figure it out.
I want to set the currentUserId inside of the getCurrentUser function, which I would like to be able to call inside other functions.
Below is what I have now, and it returns undefined. What am I missing?
var currentUserId;
function getCurrentUser() {
$.ajax({
type: "GET",
url: '/set_user',
success: function(result) {
currentUserId = result.id;
return currentUserId;
},
error: function(err) {
console.log(err);
}
})
};
getCurrentUser();
console.log("current user id is " + currentUserId);
This happens because inside getCurrentUser method you are doing an asynchronous AJAX call, so the value is not yet ready when you print it with console.log.
The value will be correctly set when the GET /set_user request will end successfully, only in that case the function:
success: function(result) {
currentUserId = result.id;
return currentUserId;
}
will be executed and currentUserId will be set.
Based on jQuery.ajax() documentation, the value returned by $.ajax call is a Promise. So first, return the promise to the caller (1) and then wait the promise is resolved to print the value (2).
var currentUserId;
function getCurrentUser() {
return $.ajax({ // 1. Return the Promise here
type: "GET",
url: '/set_user',
success: function(result) {
currentUserId = result.id;
return currentUserId;
},
error: function(err) {
console.log(err);
}
})
};
// 2. Then wait the call to succeed before print the value (use the 'done' method)
getCurrentUser().done(function() {
console.log("current user id is " + currentUserId);
});
Like Andrea explain, the value was not ready yet when you make a ajax call.
One way to avoid this is use callback:
function getCurrentUser(callback) {
$.ajax({
type: "GET",
url: '/set_user',
success: function(result) {
var currentUserId = result.id;
if (callback)
callback(currentUserId);
},
error: function(err) {
console.log(err);
}
})
};
function displayResult(userId){
console.log("current user id is " + userId);
}
getCurrentUser(displayResult);
And this will also avoid the use of globe variable currentUserId.
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.
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
When using JQuery.Deferred is it OK to invoke reject() directly? Without having invoked a async function?
Perhaps I want some kind of test in the beginning of my async function. If the test fails I want to reject immediately. See the first if block below.
function doSomethingAsync() {
//Test if the ajax call should be invoked
var testFailed = true;
var dfd = $.Deferred();
//Check if test failed
if (testFailed) {
var asyncResult = {
success: false,
data: 'test failed'
};
//Is this OK usage of reject on the same thread?
dfd.reject(asyncResult);
return dfd.promise();
}
$.get('/api/testapi/get').done(function (data) {
var asyncResult = {
success: true,
data: data
};
dfd.resolve(asyncResult);
}).fail(function (err) {
var asyncResult = {
success: false,
data: err
};
dfd.reject(asyncResult);
});
return dfd.promise();
}
When using JQuery.Deferred is it OK to invoke reject() directly? Without having invoked a async function?
Yes, it's totally OK to return an already rejected promise, and to reject deferreds immediately. You only might need to verify that your callbacks don't rely on asynchronous resolution, which jQuery does not guarantee (in contrast to A+ implementations).
Notice that in your code you should use then instead of manually resolving the deferred:
function doSomethingAsync() {
var testFailed = /* Test if the ajax call should be invoked */;
var dfd = testFailed
? $.Deferred().reject('test failed')
: $.get('/api/testapi/get');
return dfd.then(function (data) {
return {
success: true,
data: data
};
}, function (err) {
return {
success: false,
data: err
};
});
}
You can do it quickly, as your function return a Promise object:
return Promise.reject('test failed');