http-client icon indicating copy to clipboard operation
http-client copied to clipboard

Canceling requests with TypeScript

Open heruan opened this issue 9 years ago • 19 comments

Since the cancel/abort function is added runtime to the Promise<HttpResponseMessage> returned by .send() in http-client.js, the TypeScript compiler doesn't know about its existence.

heruan avatar Feb 05 '16 09:02 heruan

I have a PR ready for this... except the build chain won't support it properly.

We need generics support to declare interface CancellablePromise<T> extends Promise<T>. This is one of the latest change in babel-dts-generator but of course we can't use it because aurelia-http-client still uses Babel 5.8 but babel-dts-generator master is on 6.0 now.

jods4 avatar Mar 02 '16 00:03 jods4

We hope to move to 6.x soon. We've been contributing to the dts generator a lot trying to get it updating to the new Babel version. I think we're really close. @cmichaelgraham can you comment on that?

EisenbergEffect avatar Mar 02 '16 02:03 EisenbergEffect

@jods4 babel-dts-generator has been updated to support generics. as part of this, it also has been updated to the new babel6 plugin architecture.

the first aurelia repo to test against is metadata - a problem has been identified where class member's code comments were not being successfully included in the generated .d.ts file.

failing tests were created and the issues resolved, but during the code review, a refactoring was requested (a good suggestion).

i will try to get this added to the PR so we can proceed.

cmichaelgraham avatar Mar 02 '16 10:03 cmichaelgraham

@cmichaelgraham It looks like this is still a bug in the d.ts generator. Can you address it?

EisenbergEffect avatar Jul 04 '16 14:07 EisenbergEffect

i'll have a look :smile:

cmichaelgraham avatar Jul 05 '16 15:07 cmichaelgraham

@cmichaelgraham Was this ever addressed?

EisenbergEffect avatar Jul 24 '16 13:07 EisenbergEffect

need to test with the latest... will do that tonight... (i think we should be ok with the required generics)

cmichaelgraham avatar Jul 24 '16 13:07 cmichaelgraham

@heruan - can you submit the PR so i can test with the latest babel-dts-generator?

ping @EisenbergEffect

cmichaelgraham avatar Jul 24 '16 14:07 cmichaelgraham

@jods4 had a PR ready, let's hear from him!

heruan avatar Jul 26 '16 08:07 heruan

thanks @heruan :smile: @jods4 - can you submit a PR?

cmichaelgraham avatar Jul 26 '16 08:07 cmichaelgraham

Hey guys, sorry that's so old now I'm really not sure where I made this anymore :D

BTW instead of inheritance, since then we got intersection types, so an alternative could be to type the function as Promise<T> & { abort(): void }

jods4 avatar Jul 26 '16 08:07 jods4

To piggyback on @jods4's comment, you can solve this problem in your own codebase by just declaring the following type:

type CancellablePromise<T> = Promise<T> & { cancel(): void }

I think this should be added more formally to the http-client type definitions though.

michaelbull avatar Nov 14 '17 16:11 michaelbull

BTW, maybe that's worth opening another issue but whatwg has finally decided what is the standard way to abort a fetch. They said adding abort on Promise is not working well as soon as you chain them, so they opted for a different design based on a fetch controller. Maybe it's worth revising the design of http-client as well (of course abort could be left on the returned promise for back compat, but maybe not exposed in the .d.ts).

jods4 avatar Nov 14 '17 21:11 jods4

@jods4 do you have the link to the supporting documentation from whatwg? Would be useful going forward in this discussion, thanks.

michaelbull avatar Nov 15 '17 09:11 michaelbull

@michaelbull whatwg discussions and specs are dry as hell.

Have a look at this introductory article from Google: https://developers.google.com/web/updates/2017/09/abortable-fetch

Or look at the docs in MDN: https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort

This has landed in all 3 major browsers.

jods4 avatar Nov 15 '17 09:11 jods4

I first patched .d.ts type with addition Promise<T> & { abort(): void } Second, I replace native promise with bluebird promise : http://bluebirdjs.com/docs/getting-started.html Thrid I add a small wrapper on httpclient send() method return promise :: I follow the bluebird doc : http://bluebirdjs.com/docs/api/cancellation.html#cancellation :

function makeCancellableHttpClientPromise(httpClientPromise) {
 return new Promise(function(resolve, reject, onCancel) {
        // Note the onCancel argument only exists if cancellation has been enabled!
        onCancel(function() {
            //use abort to avoid confusion with bluebird cancel() method
            httpClientPromise.abort();
        });
        httpClientPromise.then(resolve, reject);
    });
}

It works fine !

npelletm avatar Nov 24 '17 08:11 npelletm

@BBosman maybe you could take a look at this one? and the one linked?

Alexander-Taran avatar Jan 07 '19 10:01 Alexander-Taran

Had a quick look, but I'm running into limitations of the current babel-dts-generator based toolchain.

Attempt 1:

export type CancellablePromise1<T> = Promise<T> & {
  cancel: () => void;
  abort: () => void;
};

Results in TypeAlias not supported warnings during build and the .d.ts file being truncated from that point.

Attempt 2:

interface CancellablePromise<T> extends Promise<T> {
  cancel: () => void;
  abort: () => void;
}

Results in the build crashing with an node.toCode is not a function error. It's choking on the extends.

Attempt 3:

interface Cancellable<T> {
  cancel: () => void;
  abort: () => void;
}

And then using Cancellable&Promise<HttpResponseMessage> as a return type results in a crashed built with an Unsupported type annotation type: IntersectionTypeAnnotation error.

So before we/I can fix this I think we need some enhancements in babel-dts-generator to make this scenario possible within our current toolchain. I'm open to suggestions or alternatives though.

BBosman avatar Jan 07 '19 20:01 BBosman

@BBosman alternative could be to migrate this one to TS? but that can be too much of a task for a working thing

Alexander-Taran avatar Jan 07 '19 21:01 Alexander-Taran