hmoog / xmlhttprequest-ts

XMLHttpRequest-ts is a typescript wrapper for the built-in http client to emulate the browser XMLHttpRequest object and allow isomorphic code that runs in the browser and in node.js. This can be used with JS designed for browsers to improve reuse of code and allow the use of existing libraries. Ready for AOT and treeshaking in combination with Angular and other modern typescript frameworks.
MIT License
2 stars 3 forks source link

Should use core typescript types. #1

Open EvanCarroll opened 5 years ago

EvanCarroll commented 5 years ago

You state here,

XMLHttpRequest-ts is a typescript wrapper for the built-in http client to emulate the browser XMLHttpRequest object and allow isomorphic code that runs in the browser and in node.js. This can be used with JS designed for browsers to improve reuse of code and allow the use of existing libraries. Ready for AOT and treeshaking

The problem with this module is that you're not implementing the core interface provided by TypeScript. This makes it difficult to use this module with third party tools in a strongly typed fashion. It would be much better if you created an implementation that used the core types in typescript https://github.com/Microsoft/TypeScript/blob/master/lib/lib.dom.d.ts#L16798

If you'll notice this module lacks the full implementation,

Type 'XMLHttpRequest' is missing the following properties from type 'XMLHttpRequest': responseType, responseURL, upload, overrideMimeType, onprogress

This means you get an error.

https://github.com/hmoog/xmlhttprequest-ts/blob/master/src/XMLHttpRequest.ts

https://github.com/ReactiveX/rxjs/issues/4455

EvanCarroll commented 5 years ago

Hold off on this for a second. I think I see what's happening. There are two conflicting sources for XMLHttpRequest the MDN and w3c,

https://github.com/Microsoft/TypeScript/issues/29310

EvanCarroll commented 5 years ago

Ok, I see what's happening now. Your XMLHttpRequest implementation is just missing stuff. These types you're providing at not from the w3c, or whatwg, and they're not on MDN. That's either because of bugs in the implementation or because you're just doing your own ad-hoc thing,

The WhatWG/w3c version has the Interface specified here,

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequestEventTarget : EventTarget {
  // event handlers
  attribute EventHandler onloadstart;
  attribute EventHandler onprogress;
  attribute EventHandler onabort;
  attribute EventHandler onerror;
  attribute EventHandler onload;
  attribute EventHandler ontimeout;
  attribute EventHandler onloadend;
};

[Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequestUpload : XMLHttpRequestEventTarget {
};

enum XMLHttpRequestResponseType {
  "",
  "arraybuffer",
  "blob",
  "document",
  "json",
  "text"
};

[Constructor,
 Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequest : XMLHttpRequestEventTarget {
  // event handler
  attribute EventHandler onreadystatechange;

  // states
  const unsigned short UNSENT = 0;
  const unsigned short OPENED = 1;
  const unsigned short HEADERS_RECEIVED = 2;
  const unsigned short LOADING = 3;
  const unsigned short DONE = 4;
  readonly attribute unsigned short readyState;

  // request
  void open(ByteString method, USVString url);
  void open(ByteString method, USVString url, boolean async, optional USVString? username = null, optional USVString? password = null);
  void setRequestHeader(ByteString name, ByteString value);
           attribute unsigned long timeout;
           attribute boolean withCredentials;
  [SameObject] readonly attribute XMLHttpRequestUpload upload;
  void send(optional (Document or BodyInit)? body = null);
  void abort();

  // response
  readonly attribute USVString responseURL;
  readonly attribute unsigned short status;
  readonly attribute ByteString statusText;
  ByteString? getResponseHeader(ByteString name);
  ByteString getAllResponseHeaders();
  void overrideMimeType(DOMString mime);
           attribute XMLHttpRequestResponseType responseType;
  readonly attribute any response;
  readonly attribute USVString responseText;
  [Exposed=Window] readonly attribute Document? responseXML;
};

For a good polyfill you should be using the native TypeScript types linked above in @types/dom which specify all that stuff. And you should be implementing all that stuff. The problem here is that in your implmentation you're missing thinks like responseURL without which this module won't work for things that demand the w3c XMLHttpRequest types.

yingdi11 commented 3 years ago

@EvanCarroll ,what is the alternative here?

EvanCarroll commented 3 years ago

@yingdi11 this project is marketed as "isomorphic code that runs in the browser and in node.js." This method of doing it is a bit dated. XMLHttpRequest is deprecated afaik, so making it run in the server is rather silly.

The right way to do this today is to use the standardized Fetch API. You can get access to that with node-fetch so using that project is the right way to go.

EvanCarroll commented 3 years ago

@yingdi11 https://github.com/hmoog/xmlhttprequest-ts/issues/6

yingdi11 commented 3 years ago

@EvanCarroll Thanks. Didn't see the comment in time. Used below code:

const promise = axios.get('https://api.polygon.io/vX/reference/tickers/AAPL?date=2021-10-05&apiKey=?');
const observable = from(promise);
observable.subscribe(data => console.log((data as any)['data']))