Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async @dispatch methods #534

Open
1 task done
Buslowicz opened this issue Jul 3, 2018 · 1 comment
Open
1 task done

Async @dispatch methods #534

Buslowicz opened this issue Jul 3, 2018 · 1 comment

Comments

@Buslowicz
Copy link
Contributor

Buslowicz commented Jul 3, 2018

This is a...

  • feature request

It would be really handy if methods decorated with @dispatch() decorator could be async methods (return a Promise). It would allow to use RxJS pipelines (with .toPromise()), or use various dialogs or after effects and whatever one would imagine.
The implementation would be pretty trivial and wouldn't touch the actual dispatcher, just the decorator. The result would be checked for being a promise (simple instanceof could be used, however to make it compatible with bluebird and similar, a more complex check should be used). If it's not a promise, continue with what is done at the moment, otherwise execute current behavior inside the .then callback.
If you guys have not much time to take care of that task, I could do it myself and make a PR, just want to know what you think of that and eventually agree on the specs.
My proposal would only modify the wrapped function and is as follows (untested, if you spot an error do let me know, I will test it before PR though):

    function isPromise(object: any): object is Promise<any> {
      return typeof object === 'object' && typeof object.then === 'function' && typeof object.catch === 'function' && typeof object.finally === 'function';
    }

    const wrapped = function(this: any, ...args: any[]) {
      const result = originalMethod.apply(this, args);

      const dispatchAction = (finalResult: any) => {
        if (result === false) {
          return;
        }
        const store = getBaseStore(this) || NgRedux.instance;
        if (store) {
          store.dispatch(finalResult);
        }
      };

      if (isPromise(result)) {
        result.then(dispatchAction);
      } else {
        dispatchAction(result);
      }
      return result;
    };

And the usage:

  @dispatch() async methodA() {
    const someData = await this.getAsyncData();
    return { type: "SOME ACTION", payload: someData };
  }
  @dispatch() methodB() {
    return new Promise((resolve) => setTimeout(resolve, 1000, { type: "PING" }));
  }
  // etc...

So, any thoughts on that?

@Buslowicz
Copy link
Contributor Author

I'd appreciate any feedback on this, should I PR it? Or would it not even be merged? Is this concept good enough, or should I make it different? Seriously the 3 weeks of total silence on this issue makes me believe this project is more dead than alive and pushes me towards competitors like ngrx. I am sure I am not the only one feeling so...

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

No branches or pull requests

1 participant