getNotes
Retrieve the note for a specific chapter and user.
The unique identifier of the Bible chapter
The unique identifier of the user whose note to retrieve
The note object for the chapter, or null if no note exists
Chapter identifier the note belongs to
The text content of the note
Timestamp when note was created
This function returns only the first note matching the chapter and user. Each user can have one note per chapter.
import { useQuery } from "convex/react";
import { api } from "@/convex/_generated/api";
function ChapterNote({ chapterId }: { chapterId: string }) {
const note = useQuery(api.notes.getNotes, {
chapterId,
userId: "user_123"
});
if (!note) {
return <div>No note for this chapter yet.</div>;
}
return (
<div>
<h3>My Notes</h3>
<p>{note.content}</p>
</div>
);
}
createNote
Create a new note for a Bible chapter.
The unique identifier of the Bible chapter
The text content of the note
The unique identifier of the user creating the note
The unique identifier of the newly created note
import { useMutation } from "convex/react";
import { api } from "@/convex/_generated/api";
import { useState } from "react";
function CreateNote({ chapterId }: { chapterId: string }) {
const [content, setContent] = useState("");
const createNote = useMutation(api.notes.createNote);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const noteId = await createNote({
chapterId,
content,
userId: "user_123"
});
console.log("Created note:", noteId);
setContent("");
};
return (
<form onSubmit={handleSubmit}>
<textarea
value={content}
onChange={(e) => setContent(e.target.value)}
placeholder="Write your notes about this chapter..."
rows={4}
/>
<button type="submit">Save Note</button>
</form>
);
}
updateNote
Update an existing note’s content.
The unique identifier of the note to update
The new text content for the note
The user ID requesting the update to verify ownership
Returns null on successful update
This function validates that the requesting user owns the note before allowing the update.
import { useMutation } from "convex/react";
import { api } from "@/convex/_generated/api";
import { Id } from "@/convex/_generated/dataModel";
import { useState } from "react";
function EditNote({
noteId,
initialContent
}: {
noteId: Id<"notes">;
initialContent: string;
}) {
const [content, setContent] = useState(initialContent);
const updateNote = useMutation(api.notes.updateNote);
const [saving, setSaving] = useState(false);
const handleUpdate = async () => {
setSaving(true);
try {
await updateNote({
id: noteId,
content,
userId: "user_123"
});
} finally {
setSaving(false);
}
};
return (
<div>
<textarea
value={content}
onChange={(e) => setContent(e.target.value)}
rows={4}
/>
<button onClick={handleUpdate} disabled={saving}>
{saving ? "Saving..." : "Update Note"}
</button>
</div>
);
}
Consider implementing auto-save functionality with debouncing to improve user experience when editing notes.