I'm new to mocha, and am trying to implement a new test. I'm finding that the callback to my end method never gets called
it('should allow valid urls', function(){
var myUrl = "http://localhost:8080/test";
api.get(myUrl)
.end(function(err, res) {
console.log('THIS IS THE END, MY FRIEND');
});
});
Does anyone know why? I've tried expect with a callback as well, and it never gets called too.
Turns out that mocha does analysis of the function arguments, and I'd forgotten to put an argument in my mocha callback - even though it's never referenced in my function or any visible code at all!
So the solution was simply to add a variable, done as a function parameter to my it function, and it worked, even though it's not visibly used in the immediate context ;-)
it('should allow valid urls', function(done){
...
EDIT: Note that done should be used in my callback, as mentioned by # oligofren, but I hadn't gotten to that point yet and was surprised to see the callback itself not firing.
Related
I'm having a function that return a promise expected to return a u128 value from another contract. How can I get this value from this promise?
Here is my codes:
I tried async await in future/rust but it didn't work
The value is baked into the call_result variable you have there. The promise will be scheduled after query_staked_amount finishes and then once the promise finishes executing, the callback query_staked_amount_callback is invoked.
In this callback, the result of the original promise (get_staked_amount) will be available in that variable you have call_result.
Hope that answers your question.
Can someone explain to me why this is not getting caught by the catch block, I am thinking its because I have a switch map, which would unsubscribe from the first observable. Have commented it out with no luck. The first observable (this.apiPaymentService.deleteStoredPaymentMethod()) is the one causing a 403
try {
this.apiPaymentService.deleteStoredPaymentMethod()
.pipe(
switchMap(() => this.apiPaymentService.getStoredAchPaymentMethods(),
catchError((err) => { return throwError(err)})
).subscribe()
} catch (error) {
console.log('I am never called ')
this.errorModal(error);
}
First: Make sure your code parses
If I throw this into my IDE, I get a parsing error immediately. I'll assume you don't want an operator as a second parameter to switchMap and that you've simply forgotten an ) near the end of the line.
What's happening inside your try block?
Inside your try block, you subscribe to an observable. That's it. That's what happens there. The subscription happens without an error. So your try-catch will complete without an error.
If this.apiPaymentService.getStoredAchPaymentMethods() is asyncronous, the try block will have completed (and may not even be on the call stack anymore) before getStoredAchPaymentMethods() resolves with a value.
How to manage Asynchronous Errors
You're already most of the way there! Instead of catching and then rethrowing an error, you can manage it right there.
The following is a no-op:
catchError((err) => { return throwError(err)})
But you can return something else instead, or you can retry or something like that :)
Aside: not just observables
Here's some old-skool code with the same underlying phenomenon.
function throwErrorFunction() {
console.log("Throwing an error!");
throw 'Throwing an error from my throw error function';
}
try {
setTimeout(throwErrorFunction, 5000);
} catch (error) {
console.log('I am never called ');
}
Here's a way to think about this. The code above never calls the throwErrorFunction. Function application in JavaScript is done wiht parenthesis. So you'd need something like throwErrorFunction() somewhere in order to call the function. But that never happens here.
But somehow the console will still read "Throwing an error!". So how does that happen if we've not called throwErrorFunction? Well... setTimeout eventually calls throwErrorFunction for us! In this case, it waits 5 seconds and then calls the function.
But by the time five seconds have elapsed, the try-catch statement has already been executed. Same deal as before! :)
I was working on a react project and the following three cases came up. Can someone give me some pointers as to what the differences are when making AJAX request using axios as well as redux-promise?
Case 1 (the payload is undefined - why?):
axios.get(link)
.then(callback)
Case 2 (the payload is also undefined - why?):
axios.get(link)
.then(() => callback())
Case 3 (the payload is the res object):
axios.get(link)
.then((res) => { callback; return res });
Would really appreciate if anyone could please answer this question or give me pointers to materials that could clear my confusion. I did my best researching and have spent couple hours before I posted the question on SO. Thanks!
Your resolved value in the first two promises is undefined because you have a .then() handler that you don't return anything from. The return value of the .then() handler becomes the resolved value of the promise chain.
If you want link to be the resolved value of the promise and you're going to have your own .then() handler, then you have to return it.
Case 1:
axios.get(link).then(callback)
Here you're delegating your .then() handler to the callback function. Unless it returns the value it was passed to it (which apparently it doesn't), then the return value from your .then() handler is undefined and thus that's what the resolved value of the promise chain becomes.
Case 1 is equivalent to this:
axios.get(link).then(function(val) {
return callback(val);
});
So, the promise chain takes on whatever callback(val) returns as the resolved value.
Case 2:
axios.get(link).then(() => callback())
Here, we can clearly see that the return value from the .then() arrow function handler is the result of executing callback() which is apparently undefined so thus the promise chain takes on a resolved value of undefined.
You could fix that by doing this:
axios.get(link).then(() => {
callback()
return link;
});
Case 3:
axios.get(link).then((res) => { callback; return res });
Here's you're explicitly returning res so that becomes the resolved value of the promise chain. You're also not even calling callback(). I presume you meant to have () after it.
Don't mix plain callbacks in with promises
You also probably don't want to mix plain callbacks with promises and they are two different approaches to asynchronous notification and it's much better to use only one technique in a given section of code. Instead, turn the callback operation into one that returns a promise that is resolved when the callback would normally get called. Then, you can just chain promises.
Or, if you're trying to notify some caller about the completion of the operation, then have them just watch the returned promise with their own .then() handler on the returned promise.
Often I find myself writing beforeSave and afterSave using promises in this form:
beforeSavePromise: function (request) {
var recipe = request.object;
var promises = [
doFooIfNeeded(recipe),
doBarIfNeeded(recipe),
doQuuxIfNeeded(recipe)
];
return Parse.Promise.when(promises)
},
Each of these are conditional actions that perform an action only if a particular field or fields are dirty. So for example, doFooIfNeeded might look something like:
if (recipe.dirty('imageFile')) {
return /* some Promise that updates thumbnails of this image */;
} else {
return Parse.Promise.as(); // The no-op Promise. Do nothing!
}
My question is, is Parse.Promise.as() really the no-op Promise? or is new Parse.Promise() more correct?
With all "dirty" outcomes contributing a resolved promise to the aggregation, you can choose for each "clean" outcome to contribute in any of the following ways :
not to put anything in the array,
put a value in the array,
put a resolved promise in the array,
put a rejected promise in the array.
(1), (2) and (3) will guarantee that the aggregated promise resolves regardless of the clean/dirty outomes (except some unpredicted error).
(4) will cause the aggregared promise to resolve only if all outcomes are "dirty", or to reject as soon as any one "clean" outcome arises.
Realistically, the choice is between (2) and (4), depending on how you want the aggregated promise to behave. (1) would complicate the aggregation process, and (3) would be unnecessarily expensive.
It would seem appropriate for the aggregated promise to resolve when everything is either already "clean" or has been cleaned up, therefore I would suggest (2), in which case your foo()/bar()/quux() functions could be written as follows :
function foo() {
return recipe.dirty('imageFile') ? updates_thumbnails() : true; // doesn't have to be `true` or even truthy - could be almost anything except a rejected promise.
}
And aggregate the outcomes as in the question :
$.when([ foo(recipe), bar(recipe), quux(recipe) ]).then(function() {
//all thumbnails were successfully updated.
}).fail(function() {
//an unexpected error occurred in foo(), bar() or quux().
});
Parse.Promise.as() will technically give you a Promise with its state set to resolved. When you return this Promise, its callback will be triggered successfully. You can supply a value as an argument which basically triggers the callback with that value. According to the Parse guide on Promise creation, new Parse.Promise() creates a Promise that its states is neither set to resolved nor failed. This gives you the flexibility to mange its state manually as you wish.
Why can't I set a (custom user-defined) property of a Deferred object to a promise returned by that same Deferred object? I think it is possible because dojo.store.JsonRest does it:
var results = xhr("GET", {
url: this.target + (query || ""),
handleAs: "json",
headers: headers
});
results.total = results.then(function(){
var range = results.ioArgs.xhr.getResponseHeader("Content-Range");
return range && (range=range.match(/\/(.*)/)) && +range[1];
});
return QueryResults(results);
I have to do something very similar, but I chain on an extra deferred object because I need to transform my JSON input to the format QueryResults() expects. If I assign that promise to a property of my Deferred object, it results in undefined. However, if I assign the promise to a regular variable the assignment works. Unfortunately, QueryResults needs the property to be assigned.
I think I have boiled down the problem to a difference between the promises returned by xhr() and xhr().then(). Please check the console output of this jsFiddle.
What is the difference, and how can I work around it?
The straightforward reason why you can't change the property is that the promise object is frozen:
that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed. In essence the object is made effectively immutable.
Dojo documentation explains why the promise is frozen:
The .then() call returns a new promise that represents the result of the execution of the callback. The callbacks will never affect the original promise's value.
The reason why you can change the property of Deferred returned by xhr() is that
The dojo.Deferred is a type of promise that provides methods for fulfilling the promise with a successful result or an error.
Actually, the promise of Deferred is stored is Deferred's property Deferred.promise, which is also frozen and Deferred.then() just links to Deferred.promise.then().
I would not recommend it, but if you insist on changing the promise you can achieve it via lang.delegate():
my_deferred = lang.delegate(my_deferred);
I modified your jsFiddle a bit to clarify the aforementioned: http://jsfiddle.net/phusick/N3J7M/.