Skip to content

Draft for a new ajax API built on top of fetch()#4585

Merged
dtdesign merged 9 commits intomasterfrom
typescript-ajax-api
Nov 17, 2021
Merged

Draft for a new ajax API built on top of fetch()#4585
dtdesign merged 9 commits intomasterfrom
typescript-ajax-api

Conversation

@dtdesign
Copy link
Copy Markdown
Member

@dtdesign dtdesign commented Nov 14, 2021

The design of the existing AJAX API is quite old and dates back to the behavior of WCF.Action.Proxy. It lacks any support for asynchronous actions (Promises) and has a subpar control flow caused by the different methods to prepare (_ajaxSetup()), invoke and evaluate the result (_ajaxSuccess() and _ajaxFailure()). Especially modules serving multiple endpoints suffer from _ajaxSuccess() being a glorified switch to keep the code readable. The lack of proper types for the request and response make it hard to work with it.

At some point I have evaluated Axios as an alternative, but at the end of the day decided against it. It adds a lot of bells and whistles, but its major selling point are the compatibility with ancient browsers as well as some nice helper features. We already maintain a working implementation on top of XMLHttpRequest, so we are familiar with the requirements and have proven to be able to maintain our own wrapper around it. From my perspective, Axios is a nice library, but adds another dependency that we do not strictly need.

Usage of the library in this draft:

type ResponseMakeSnafucated = {
  foo: {
    bar: number;
  };
  message: string;
};

class MyModule {
  constructor(buttonId: string) {
    const button = document.getElementById(buttonId);
    button?.addEventListener("click", (event) => void this.onClick(event));
  }

  async onClick(event: MouseEvent) {
    event.preventDefault();

    const data: ResponseMakeSnafucated = await Api.dboAction("makeSnafucated", "wcf\\data\\foo\\FooAction").dispatch();
    if (data.foo.bar > 0) {
      console.log(data.message);
    }
  }
}

Comment thread ts/WoltLabSuite/Core/Api.ts Outdated
Comment thread ts/WoltLabSuite/Core/Api.ts Outdated
Comment thread ts/WoltLabSuite/Core/Api.ts Outdated
Comment thread ts/WoltLabSuite/Core/Api.ts Outdated
Comment thread ts/WoltLabSuite/Core/Api.ts Outdated
Comment thread ts/WoltLabSuite/Core/Api.ts Outdated
Comment thread ts/WoltLabSuite/Core/Api.ts Outdated
Copy link
Copy Markdown
Member

@TimWolla TimWolla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The public API of this module LGTM now. The remaining comments are just about “code style” within this module (and missing doc comments).

Comment thread ts/WoltLabSuite/Core/Api.ts Outdated
Comment thread ts/WoltLabSuite/Core/Api.ts Outdated
@dtdesign dtdesign marked this pull request as ready for review November 16, 2021 14:56
dtdesign added a commit to WoltLab/docs.woltlab.com that referenced this pull request Nov 16, 2021
@dtdesign dtdesign requested a review from TimWolla November 16, 2021 16:25
@dtdesign
Copy link
Copy Markdown
Member Author

@TimWolla Please verify the latest changes and compare it against the documentation in case there are any discrepancies.

@TimWolla
Copy link
Copy Markdown
Member

@TimWolla Please verify the latest changes and compare it against the documentation in case there are any discrepancies.

LGTM. I tested the first example in the documentation (against UserProfileAction::getUserProfile()) with the following HTML:

<button id="testbutton">Test</button>
<div id="latestFoo"></div>
<script>
require(['WoltLabSuite/Core/MyModule'], (MyModule) => {
  new MyModule.default(1, "bar", "testbutton");
});
</script>

@dtdesign dtdesign merged commit 364b09f into master Nov 17, 2021
@dtdesign dtdesign deleted the typescript-ajax-api branch November 17, 2021 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants