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:
updateProfile
, the output was { messageCount: 0}
, always, so no increment.prevCount
before the update to ensure it's correct.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
}
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.
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 })