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

[query] add a beforeSubscribe hook #135

Open
bennypowers opened this issue Apr 2, 2021 · 3 comments
Open

[query] add a beforeSubscribe hook #135

bennypowers opened this issue Apr 2, 2021 · 3 comments
Labels
enhancement New feature or request

Comments

@bennypowers
Copy link
Member

bennypowers commented Apr 2, 2021

Case

User wants to set variables or perform another side effect before the element first subscribes

Example

import { authClient } from '../my-auth-client'; // some JS SDK for user auth

class ProductElement extends ApolloQuery<typeof ProductQuery> {
  query = ProductQuery;

  override shouldSubscribe(): boolean {
    const { searchParams } = new URL(location.href);
    // we could abuse `shouldSubscribe` to inject `this.variables = { ... }` here
    return !!searchParams.has('product');
  }

  override async beforeSubscribe(): Promise<void> {
    // but instead, it's better to make our side-effecting hook explicit
    // plus which, this can be async
    const { searchParams } = new URL(location.href);
    this.variables = {
      input: {
        productId: searchParams.get('product'),
        apiKey: await authClient.getUser().apiKey,
      },
    };
  }
}

Proposed implementation

Add an optional member to ApolloQueryInterface and ApolloSubscriptionInterface

async beforeSubscribe()?: Promise<void>;

and wait on it in ApolloQueryMixin and ApolloSubscriptionMixin:

+       await this.beforeSubscribe?.();
        this.observableQuery = this.watchQuery(options);
+       await this.beforeSubscribe?.();
        this.observableSubscription =
          this.observable?.subscribe({

Questions

  1. ApolloQuery#subscribe is currently synchronous and returns a subscription. Is this a breaking change requiring a major version? (ApolloSubscription#subscribe doesn't return anything so that's not an issue there)
  2. Should beforeSubscribe take any parameters? if so, which? for class components, everything's available on this, but for haunted and hybrids, maybe it should take variables?
@bennypowers bennypowers added the enhancement New feature or request label Apr 2, 2021
@bennypowers
Copy link
Member Author

Jeroen on Polymer slack notes:

coming from Angular, having subscribe() return a promise that you have to await feels wrong
in Angular, subscribe() always returns an Observable

@bennypowers
Copy link
Member Author

Could avoid the breaking change by, instead of making subscribe async, make the private callers async, and have them wait on beforeSubscribe.

that would however mean that users who call subscribe() directly won't get the side effects of beforeSubscribe

I wonder if zen observable provides it's own hook I could use here?

@bennypowers bennypowers added this to To Do in lit 2 Apr 22, 2021
@bennypowers bennypowers moved this from To Do to In Progrress in lit 2 Apr 22, 2021
@bennypowers
Copy link
Member Author

This turns out to be harder than it looks:

  • I can return a subscription from subscribe() which first converts the promise from beforeSubscribe() to an Observable, then when it resolves, creates the ObservableQuery instance, but existing code expects observableQuery to already exist
  • I can await the promise in the private documentChanged and variablesChanged methods, but that's awkward too, as many of my tests (and, it stands to reason, real world code) relies on the observableQuery being synchronously created.
  • ObservableQuery has an onSubscribe method, but it's private. an Ideal solution here would be to hook in to ObservableQuery

@bennypowers bennypowers moved this from In Progrress to To Do in lit 2 Apr 22, 2021
@bennypowers bennypowers removed this from To Do in lit 2 Jul 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant