Hi there, i would like to know how to use subscrip...
# graphql-nexus
l
Hi there, i would like to know how to use subscription in nexus to subscribe two users to their channel (chat), (actually when a new channel is created every users receive it in frontend and thats not good) here is my subscription and mutation where i use it. thanks for your help
Copy code
export const ChannelSubscription = subscriptionField('channel', {
  type: 'Channel',
  subscribe(_root, _args, ctx) {
    return ctx.pubsub.asyncIterator('channel')
  },
  resolve(payload) {
    return payload
  },
})

  t.field('createChannel', {
      type: 'Channel',
      nullable: true,
      args: {
        receiverId: stringArg({ nullable: false }),
      },
      resolve: async (_parent, { receiverId }, ctx) => {
        const userId = getUserId(ctx)
        const channel = await ctx.prisma.channel.create({
          data: {
            users: {
              connect: [{ id: userId }, { id: receiverId }],
            },
            visibles: {
              create: [{ toUserId: userId }],
            },
          },
        })
        ctx.pubsub.publish('channel', channel)
        return channel
      },
    })
w
You can define a custom resolver that returns a scoped result rather than the item that triggered the asyncIterator. Something like:
Copy code
...
  subscribe(_root, _args, ctx) {
    return ctx.pubsub.asyncIterator('channel')
  },
  resolve(_root, _args, ctx) {
    const userId = getUserId(ctx)
    return ctx.db.channel.findMany({ where: { visibles: {toUserId: userId} } });
  }
You can also, of course, just return the latest one, or conditionally return the parent if it’s userId matches the authenticated user
When you return “payload”, that’s really just the parent or root parameter, but you can also use it like any other resolver.
I recently learned that it’s generally not good practice to subscribe to data sets, but rather to data updates. So the subscription tells you when something is added, removed, or updated within any given set, but not return the whole set every time something is added, removed, or updated. In this use case, it seems like that principle would suggest you could use the mutation result to update your frontend channel rather than a subscription, but maybe subscribe to changes in users or visibility for any given channel (or something like that). If you want to refresh whole data-sets, GraphQL recommends polling, which many GraphQL libraries handle out of the box.
l
hey thanks a lot @Will Fischer so if i understand you correctly you mean its better to subscribe to update than create ? it could work for channel but for message i'm not sure
w
That’s a good point. I mostly meant for this specific case (since the creator is the only one who would be updated with the subscription) Looking a little more closely, I’m a little confused about the code you pasted in. It seems like the
t.field
section is part of your subscriptionfield, but should probably a mutation extension type. Is that just an artifact of how you pasted it in?
For messages, subscribing to newly created messages would make perfect sense.