next.jsdrizzle-orm

updateProfile function does not update the


I'm working on an application that interacts with a PostgreSQL with drizzle-orm, and I'm having trouble updating a user's message count in their profile. The updateProfile function is supposed to increment the messageCount field, but it doesn't seem to be updating as expected.

export async function getProfile(userId: string): Promise<Array<Profile>> {
  try {
    return await db.select().from(profile).where(eq(profile.userId, userId));
  } catch (error) {
    console.error("Failed to get the profile from database");
    throw error;
  }
}

export async function updateProfile(userId: string, updates: Partial<Profile>) {
  try {
    return await db.update(profile).set(updates).where(eq(profile.userId, userId));
  } catch (error) {
    console.error("Failed to update the profile");
    throw error;
  }
}

export const profile = pgTable("Profile", {
  id: uuid('id').primaryKey().notNull().defaultRandom(),
  userId: uuid('userId')
    .unique()
    .references(() => user.id, { onDelete: "cascade" }),
  trialDuration: integer("trialDuration").default(1 * 60), // seconds
  trialEndTime: timestamp("trialEndTime"),
  messageCount: integer("messageCount").notNull().default(0),
  createdAt: timestamp('createdAt').defaultNow(),
});

export type Profile = InferSelectModel<typeof profile>;

const [profile] = await getProfile(session.user.id)
let messageCount = profile.messageCount;

if (messageCount < MAX_MESSAGES) {
  console.log("Old profile: ", profile);
  console.log("Test", session.user.id)
  const newProfile = await updateProfile(session.user.id, { messageCount: messageCount++})
  console.log("New profile: ", profile);
} 

What I have done:

  1. I logged the argument updates from the updateProfile, the output was { messageCount: 0}, always, so no increment.
  2. I logged the value of prevCount before the update to ensure it's correct.
  3. I tried using prevCount + 1 directly in the updateProfile call, but that didn't work either.

Output:

Old profile:  {
  id: '60862459-56b3-4279-a872-c406e870b873',
  userId: 'a6b9ca00-2935-4b06-bd80-35e81b89ef3c',
  trialDuration: 60,
  trialEndTime: null,
  messageCount: 0,
  createdAt: 2025-04-06T05:52:54.838Z
}
Test a6b9ca00-2935-4b06-bd80-35e81b89ef3c
New profile:  {
  id: '60862459-56b3-4279-a872-c406e870b873',
  userId: 'a6b9ca00-2935-4b06-bd80-35e81b89ef3c',
  trialDuration: 60,
  trialEndTime: null,
  messageCount: 0,
  createdAt: 2025-04-06T05:52:54.838Z
}

UPDATE

It works if I pass in the profile as argument

  const [profile] = await getProfile(session.user.id);
  console.log(profile);
  
  if (profile.messageCount < MAX_MESSAGES) {
    profile.messageCount++;
    await updateProfile(session.user.id, profile);
  } 

But this is not what I want, I want to update the values I specify.


Solution

  • This happens because you have used the postfix increment operator (messageCount++).

    It returns the original value first, then incirements the variable afterward. When this runs, it sends { messageCount: 0 } to the database. The variable messageCount does increment to 1 in code, but only after the database update has already been sent with the original value. This is why the logs always show {messageCount: 0} despite trying to incremenet.

    Instead of more complex solution with object copying, could use prefix increment

    // Prefix ++ returns the value AFTER incrementing
    await updateProfile(session.user.id, { messageCount: ++messageCount })
    

    or directly calculate the new value

    await updateProfile(session.user.id, { messageCount: messageCount + 1 })