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

What's the purpose of ChannelProvider in addition to the useChannel hook? #1786

Open
chdsbd opened this issue Jun 9, 2024 · 1 comment
Open
Assignees
Labels
documentation Improvements or additions to public interface documentation (API reference or readme).

Comments

@chdsbd
Copy link

chdsbd commented Jun 9, 2024

The requirement to use ChannelProvider in Ably-js v2 is kind of annoying because you need to ensure you couple each call to useChannel with a corresponding ChannelProvider.

What's the technical reason ChannelProvider is required? Could we pass all the required information into the hook?

┆Issue is synchronized with this Jira Task by Unito

@VeskeR
Copy link
Contributor

VeskeR commented Jun 13, 2024

Hi @chdsbd !

The ChannelProvider component was introduced to avoid issues with inconsistent channel configurations and potential errors arising from them. In ably-js v1, using the useChannel or usePresence hooks with the options parameter could lead to errors when using hooks with the same channel name but different options, or when attempting to dynamically change options for a channel. Here are some older issues related to this problem that I found quickly: #1570, #1477.

For example, code setups like this would fail in v1:

// App.js
export const App = () => {
  return (
    <AblyProvider client={client}>
      <ConnectedUsers />
      <LastMessage />
    </AblyProvider>
  )
}

// ConnectedUsers.js
export const ConnectedUsers = () => {
  // usePresence creates channel without options
  const { presenceData, updateStatus } = usePresence("my-channel");
  return (
    <div>
      {presenceData.map((msg, index) => <li key={index}>{msg.clientId}: {msg.data}</li>)}
    </div>
  )
}

// LastMessage.js
export const LastMessage = () => {
  const [lastMessage, setLastMessage] = useState();
  // `useChannel` here uses the same channel name but tries to set channel options, which would throw an error because this channel has already been created without options
  useChannel({ channelName: "my-channel", options: { params: { rewind: '1' } } }, (message) => {
    setLastMessage(message);
  });
  return (
    <div>
      {lastMessage}
    </div>
  )
}

Running this code would throw Error: Channels.get() cannot be used to set channel options that would cause the channel to reattach. Please, use RealtimeChannel.setOptions() instead. due to internal rules on how channels should communicate with backend Realtime services and handle channel option changes.

So, passing options directly in hooks would cause channels to reattach incorrectly or lead to errors based on the order of calls. The ChannelProvider centralizes the definition of channels and their options so they are managed correctly.

@VeskeR VeskeR self-assigned this Jun 13, 2024
@VeskeR VeskeR added the documentation Improvements or additions to public interface documentation (API reference or readme). label Jun 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to public interface documentation (API reference or readme).
Development

No branches or pull requests

2 participants