> ## Documentation Index
> Fetch the complete documentation index at: https://learn.social.plus/llms.txt
> Use this file to discover all available pages before exploring further.

# Join and Leave Channels

> Add the current user to a chat channel, remove them from a channel, and observe current membership state with the current SDK APIs.

Use join and leave operations when the current user needs to enter or exit an existing channel. Joining does not create a missing channel, and conversation channels are already membership-managed by the SDK, so calling join or leave on a conversation channel can fail on platforms that enforce that restriction.

## Platform Surface

| Operation          | TypeScript                                  | iOS                                                         | Android                                   | Flutter                                   |
| ------------------ | ------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------- | ----------------------------------------- |
| Join channel       | `ChannelRepository.joinChannel(channelId)`  | `channelRepository.joinChannel(channelId:)`                 | `joinChannel(channelId)`                  | `joinChannel(channelId)`                  |
| Leave channel      | `ChannelRepository.leaveChannel(channelId)` | `channelRepository.leaveChannel(channelId:)`                | `leaveChannel(channelId)`                 | `leaveChannel(channelId)`                 |
| Join result        | `Promise<boolean>`                          | `AmityChannel`                                              | `Single<AmityChannel>`                    | `Future`                                  |
| Leave result       | `Promise<boolean>`                          | `Void`                                                      | `Completable`                             | `Future`                                  |
| Current membership | `channel.myMembership(callback)`            | `channel.currentUserMembership` or `channel.myMembership()` | `membership(channelId).getMyMembership()` | `membership(channelId).getMyMembership()` |

## Parameters

| Operation        | Parameter             | Required | Description                                                                        |
| ---------------- | --------------------- | -------- | ---------------------------------------------------------------------------------- |
| Join channel     | `channelId`           | Yes      | Existing channel ID that the current user should join.                             |
| Leave channel    | `channelId`           | Yes      | Channel ID that the current user should leave.                                     |
| Check membership | `channelId`           | Yes      | Channel ID whose current-user membership should be inspected.                      |
| Check membership | Channel object        | Depends  | TypeScript and iOS can also read membership state from an observed channel object. |
| Check membership | Observer / disposable | Depends  | Required by live APIs when observing channel or membership changes.                |

## Join A Channel

Join adds the current user as a member of an existing channel. On iOS, joining an already joined channel returns the existing channel. On TypeScript, the API returns `true` when the returned membership is `member`.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { ChannelRepository } from '@amityco/ts-sdk';

  const didJoin = await ChannelRepository.joinChannel(channelId);

  if (didJoin) {
    showSuccessMessage(channelId);
  }
  ```

  ```swift iOS theme={null}
  let joinedChannel = try await channelRepository.joinChannel(channelId: channelId)

  showSuccessMessage(joinedChannel.channelId)
  ```

  ```kotlin Android theme={null}
  val disposable = AmityChatClient.newChannelRepository()
      .joinChannel(channelId = channelId)
      .subscribe(
          { joinedChannel -> showSuccessMessage(joinedChannel.getChannelId()) },
          { error -> handleGeneralError(error) },
      )
  ```

  ```dart Flutter theme={null}
  final channelRepository = AmityChatClient.newChannelRepository();

  await channelRepository.joinChannel(channelId);
  ```
</CodeGroup>

## Leave A Channel

Leave removes the current user's membership from the channel. After leaving, stop routing the user into the channel UI and refresh any channel list or unread-count state that depends on membership.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { ChannelRepository } from '@amityco/ts-sdk';

  const didLeave = await ChannelRepository.leaveChannel(channelId);

  if (didLeave) {
    showSuccessMessage(channelId);
  }
  ```

  ```swift iOS theme={null}
  try await channelRepository.leaveChannel(channelId: channelId)

  showSuccessMessage(channelId)
  ```

  ```kotlin Android theme={null}
  val disposable = AmityChatClient.newChannelRepository()
      .leaveChannel(channelId = channelId)
      .subscribe(
          { showSuccessMessage(channelId) },
          { error -> handleGeneralError(error) },
      )
  ```

  ```dart Flutter theme={null}
  final channelRepository = AmityChatClient.newChannelRepository();

  await channelRepository.leaveChannel(channelId);
  ```
</CodeGroup>

## Check Current Membership

Use current membership state to hide composer controls, redirect banned users, or distinguish a channel that is only visible from one the user has joined.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const unsubscribe = channel.myMembership(({ data: membership, error }) => {
    if (error) handleError(error);

    if (membership?.membership === 'banned') {
      updateUI(membership);
    }
  });

  unsubscribe();
  ```

  ```swift iOS theme={null}
  var token: AmityNotificationToken?

  token = channelRepository.getChannel(channelId).observe { liveObject, error in
      if let error {
          handleError(error)
          return
      }

      guard let channel = liveObject.snapshot else { return }

      switch channel.currentUserMembership {
      case .member:
          showSuccessMessage("member")
      case .banned:
          showSuccessMessage("banned")
      case .none:
          showSuccessMessage("none")
      @unknown default:
          break
      }
  }
  ```

  ```kotlin Android theme={null}
  val disposable = AmityChatClient.newChannelRepository()
      .membership(channelId = channelId)
      .getMyMembership()
      .subscribe(
          { membership ->
              when (membership.getMembershipType()) {
                  AmityMembershipType.MEMBER -> showSuccessMessage("member")
                  AmityMembershipType.BANNED -> showSuccessMessage("banned")
                  AmityMembershipType.NONE -> showSuccessMessage("none")
              }
          },
          { error -> handleGeneralError(error) },
      )
  ```

  ```dart Flutter theme={null}
  final membership = await AmityChatClient.newChannelRepository()
      .membership(channelId)
      .getMyMembership();

  final isBanned = membership.isBanned == true;
  ```
</CodeGroup>

## Related Topics

<CardGroup cols={2}>
  <Card title="Query Members" href="./query-members" icon="users">
    Retrieve and filter channel members.
  </Card>

  <Card title="Preview Members" href="./preview-members" icon="user-round-search">
    Render lightweight participant previews where the SDK exposes them.
  </Card>

  <Card title="Get Channels" href="../channels/get-channel" icon="info">
    Load channel objects before routing users into a chat screen.
  </Card>

  <Card title="Ban Management" href="../channels/governance/ban-management" icon="user-slash">
    Handle moderation states that affect membership.
  </Card>
</CardGroup>
