Creating single instance of client NextJS 14

53 Views Asked by At

I'm working on a React application using Next.js and have implemented a singleton pattern for managing an instance of MdelloAdminClient. The client is supposed to be initialized during the user login process, and then used across different components in the application. However, I'm facing an issue where the client instance appears to be null when accessed after a seemingly successful initialization.

Issue Description:

I have a singleton class MdelloClientSingleton with an initialize method and a getClient method. The initialize method is called during the login process, and it seems to work as expected — the client is logged to the console successfully right after initialization. However, when I try to access the client instance later in a different part of the application using the getClient method, it returns null.

Here is my singleton class:

import { MdelloAdminClient } from '@noxtton/mdello-client-ts'

class MdelloClientSingleton {
  private static instance: MdelloAdminClient | null = null

  public static async initialize(
    email: string,
    password: string
  ): Promise<MdelloAdminClient> {
    if (!this.instance) {
      this.instance = await MdelloAdminClient.create({ email, password })
    }

    return this.instance
  }

  public static getClient(): MdelloAdminClient {
    if (!this.instance) {
      throw new Error(
        'MdelloAdminClient has not been initialized. Please log in first.'
      )
    }
    return this.instance
  }
}

export default MdelloClientSingleton

Since client needs username and password to successfully initialise, I'm initialiasing client during login, and when i try and log it i get successful client log:

const { mutate: signInMutation, isPending } = useMutation({
  mutationFn: async (data: { email: string; password: string }) => {
    try {
      const res = await signIn('credentials', {
        email: data.email,
        password: data.password,
        redirect: false,
      });

      if (res?.ok) {
        const client = await MdelloClientSingleton.initialize(data.email, data.password);
        console.log(client); // This logs the client correctly

        // Further logic...
      } else {
        // Handle invalid credentials
      }
    } catch (error) {
      // Handle error
    }
  },
});

but then when i try to use the same client elsewhere, like thi server component here:

import { ProjectDropdown } from './project-dropdown'
import MdelloClientSingleton from '~/lib/admin-client'

export async function ProjectDropdownWrapper() {
  const client = MdelloClientSingleton.getClient()
  const projects = await client.listProjects()

  return <ProjectDropdown projects={projects} />
}

im getting:

public static getClient(): MdelloAdminClient {
  18 |   if (!this.instance) {
> 19 |     throw new Error(
     |          ^
  20 |       'MdelloAdminClient has not been initialized. Please log in first.'
  21 |     )
  22 |   }

now I do not have experience in writing posts here and if I'm missing anything please kindly make a suggestion for me to make it easier to understand.

0

There are 0 best solutions below