Ponsakthi Anand
Ponsakthi Anand

Reputation: 345

TypeError: Cannot read properties of undefined (reading 'server') while calling socket.io in nextjs

I am trying to implement real-time notifications in a Next.js application using Socket.IO. My goal is to emit notification counts from the server and display them in the client. However, I’m running into issues where res.socket or res.socket.server is undefined when I try to initialize the Socket.IO server.

Here’s my setup:

api/socket/route.js

import { Server } from 'socket.io';
import { NextResponse } from 'next/server';

function SocketHandler(req, res) {
  console.log('rrrrrrrr', NextResponse.socket);
  if (!NextResponse.socket?.server?.io) {
    console.log('Initializing Socket.IO server...');

    const io = new Server(NextResponse.socket.server, {
      path: '/api/socket.io',
      cors: {
        origin: '*', // Adjust for production
        methods: ['GET', 'POST'],
      },
    });

    return NextResponse.socket.server.io = io;
  }

  return NextResponse.json({ message: "It's wrong buddy!" });
}

export { SocketHandler as GET };

api/notifications/route.js

export default async function handler(req, res) {
  if (req.method === 'GET') {
    try {
      // Mock data: Replace with your database call
      const notifications = [
        { id: 1, message: 'New user signed up!' },
        { id: 2, message: 'New order received!' },
      ];

      // Emit the notification count via Socket.IO
      const io = res.socket.server.io;
      if (io) {
        io.emit('notification-count', { count: notifications.length });
      }

      res.status(200).json(notifications);
    } catch (error) {
      console.error('Error fetching notifications:', error);
      res.status(500).json({ message: 'Internal server error' });
    }
  } else {
    res.status(405).json({ message: 'Method not allowed' });
  }
}

component/NotificationCount.js

    "use client";
import { useEffect, useState } from 'react';
import { io } from 'socket.io-client';

export default function NotificationCount() {
  const [notificationCount, setNotificationCount] = useState(0);

  useEffect(() => {
    // Initialize Socket.IO client
    const socket = io({ path: '/api/socket' });

    // Listen for notification count updates
    socket.on('notification-count', (data) => {
      setNotificationCount(data.count);
    });

    // Clean up the connection
    return () => {
      socket.disconnect();
    };
  }, []);

  return (
    <div>
      <h2>Notifications</h2>
      <p>New Notifications: {notificationCount}</p>
    </div>
  );
}

app/profile/page.tsx

    import { Breadcrumbs } from '@/components/breadcrumbs';
import { CreateProfileOne } from '@/components/forms/user-profile-stepper/create-profile';
import PageContainer from '@/components/layout/page-container';
import NotificationCount from '@/components/NotificationCount';

const breadcrumbItems = [
  { title: 'Dashboard', link: '/dashboard' },
  { title: 'Profile', link: '/dashboard/profile' }
];
export default function page() {
  return (
    <PageContainer scrollable={true}>
      <div className="space-y-4">
        <Breadcrumbs items={breadcrumbItems} />
        <CreateProfileOne categories={[]} initialData={null} />
        <NotificationCount />
      </div>
    </PageContainer>
  );
}

The Problem: When I hit the api/notifications route or try to initialize Socket.IO, I get the following error: TypeError: Cannot read properties of undefined (reading 'server')

and NextResponse.socket returns 'undefined'

error screenshots below enter image description here

enter image description here

Upvotes: 0

Views: 16

Answers (0)

Related Questions