Mathias
Mathias
CCConvex Community
Created by Mathias on 8/20/2024 in #support-community
How to upload images using Convex storage? (Solved)
I figured it out and added some compression too.
const useUploadFn = () => {
const generateUploadUrl = useMutation(api.files.generateUploadUrl)
const getStorageUrl = useMutation(api.files.getStorageUrl)

const options = {
maxSizeMB: 1,
maxWidthOrHeight: 1920,
useWebWorker: true,
}

const onUpload = async (file: File) => {
const compressionToastId = toast.loading("Compressing image...")

const compressedFile = await imageCompression(file, options)

toast.dismiss(compressionToastId)

const promise = generateUploadUrl().then((postUrl) => {
return fetch(postUrl, {
method: "POST",
headers: {
"Content-Type": compressedFile?.type || "application/octet-stream",
},
body: compressedFile,
})
})

return new Promise((resolve, reject) => {
toast.promise(
promise.then(async (res) => {
if (res.status === 200) {
const { storageId } = await res.json()

const getUrl = await getStorageUrl({ storageId })

resolve(getUrl)
} else {
throw new Error("Error adding image. Please try again.")
}
}),
{
loading: "Adding image...",
success: "Image added successfully.",
error: (e) => {
reject(e)
return e.message
},
}
)
})
}
const useUploadFn = () => {
const generateUploadUrl = useMutation(api.files.generateUploadUrl)
const getStorageUrl = useMutation(api.files.getStorageUrl)

const options = {
maxSizeMB: 1,
maxWidthOrHeight: 1920,
useWebWorker: true,
}

const onUpload = async (file: File) => {
const compressionToastId = toast.loading("Compressing image...")

const compressedFile = await imageCompression(file, options)

toast.dismiss(compressionToastId)

const promise = generateUploadUrl().then((postUrl) => {
return fetch(postUrl, {
method: "POST",
headers: {
"Content-Type": compressedFile?.type || "application/octet-stream",
},
body: compressedFile,
})
})

return new Promise((resolve, reject) => {
toast.promise(
promise.then(async (res) => {
if (res.status === 200) {
const { storageId } = await res.json()

const getUrl = await getStorageUrl({ storageId })

resolve(getUrl)
} else {
throw new Error("Error adding image. Please try again.")
}
}),
{
loading: "Adding image...",
success: "Image added successfully.",
error: (e) => {
reject(e)
return e.message
},
}
)
})
}
2 replies
CCConvex Community
Created by Mathias on 8/17/2024 in #support-community
How to fix Uncaught Error: Not authenticated?
Brilliant, thanks @erquhart
3 replies
CCConvex Community
Created by Mathias on 8/17/2024 in #support-community
How to use skip in my useStableQuery?
Haha, thanks @lee ! Can you tell me if the approach is the correct one, except for the null vs undefined part?
4 replies
CCConvex Community
Created by Mathias on 7/9/2024 in #support-community
Queries and best practices: How to query multiple tables and return object?
@ballingt I see that you are mentioning QueryCtx. Where are those coming from? I noticed when I'm creating helper functions, that my types no longer follow along.
7 replies
CCConvex Community
Created by Mathias on 7/9/2024 in #support-community
Queries and best practices: How to query multiple tables and return object?
Hi @ballingt Thank you for putting so much time into my questions. It definitely helped getting me back on track. Much appreciated! I will try to write smaller helper function to sort my code more nicely, and perhaps it provides a better overview along the way.
7 replies
CCConvex Community
Created by Mathias on 6/11/2024 in #support-community
How to fix Uncaught Error: Not found
I ended up doing it in the client. I added the convex-helpers and listened to isPending. Thanks for the help 🙂
6 replies
CCConvex Community
Created by Mathias on 6/11/2024 in #support-community
How to fix Uncaught Error: Not found
Thank you for going through this @Michal Srb . I'm already storing the user in the database, but not explicitly how the documentation describes it. I have a create user mutation that I use if the getUser doesn't return any one.
export const getUser = query({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity()

if (!identity) {
throw new Error("Not authenticated")
}

const userId = identity.subject

const user = ctx.db
.query("users")
.withIndex("by_user", (q) => q.eq("userId", userId))
.first()

return user
},
})
export const getUser = query({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity()

if (!identity) {
throw new Error("Not authenticated")
}

const userId = identity.subject

const user = ctx.db
.query("users")
.withIndex("by_user", (q) => q.eq("userId", userId))
.first()

return user
},
})
This is my application layout where it goes wrong with the teams getTeams query:
export default function ApplicationLayout({
children,
}: {
children: React.ReactNode
}) {
const pathname = usePathname()
const user = useStableQueryOverMounts(`user`, api.users.getUser)
const teams = useStableQueryOverMounts("teams", api.teams.getTeams)

const setActiveTeam = useMutation(api.users.setActiveTeam)

const { setOpen } = useCreateTeamOpen()

if (user === null) {
return <CreateUser />
}

// Implement permissions
const permissions: any = []

const activeTeam = teams?.find((team) => team?._id === user?.activeTeam)

return (<>some</>)
}
export default function ApplicationLayout({
children,
}: {
children: React.ReactNode
}) {
const pathname = usePathname()
const user = useStableQueryOverMounts(`user`, api.users.getUser)
const teams = useStableQueryOverMounts("teams", api.teams.getTeams)

const setActiveTeam = useMutation(api.users.setActiveTeam)

const { setOpen } = useCreateTeamOpen()

if (user === null) {
return <CreateUser />
}

// Implement permissions
const permissions: any = []

const activeTeam = teams?.find((team) => team?._id === user?.activeTeam)

return (<>some</>)
}
Not sure what I'm doing wrong with getTeams, as of queries works just fine.
6 replies
CCConvex Community
Created by Mathias on 5/4/2024 in #support-community
How to prevent re-rendering using useMutation?
Thanks but unfortunately I'm not allowed. I will try a different ways of selecting and see what happens, Thank you for the great help so far and the troubleshooting ideas.
11 replies
CCConvex Community
Created by Mathias on 5/4/2024 in #support-community
How to prevent re-rendering using useMutation?
Thanks. It is the ColumnSelector component that causes the unmount. Within the same sheet component I also update the editor, and that is no issue.
11 replies
CCConvex Community
Created by Mathias on 5/4/2024 in #support-community
How to prevent re-rendering using useMutation?
@Michal Srb Do you have any other suggestions? I can force it to open again after change, but it does not provide a good user experience.
11 replies
CCConvex Community
Created by Mathias on 5/4/2024 in #support-community
How to prevent re-rendering using useMutation?
Thanks for taking a look, and for the troubleshooting steps. I can confirm that changing the data from Convex dashboard closed sheet / re-rendered page. I can also confirm that the value x of the Test function changed every time I changed the data.
11 replies
CCConvex Community
Created by Mathias on 5/4/2024 in #support-community
How to prevent re-rendering using useMutation?
Here are the files. Structure: 1. BoardIdPage (MainPage) - Column (Component) a: Card (Componet) - CardOptions (Component) 1: ColumnSelector (Isolated to this component) I tried moving ColumnSelector two steps above to Card component, and same behaviour happened. Everytime I use the Selector it re-renders the page. If I do comment out the moveTask (within ColumnSelector), the UI works as it should but then the data does not mutate (as expected).
11 replies
CCConvex Community
Created by Mathias on 5/4/2024 in #support-community
How to prevent re-rendering using useMutation?
Hi @Michal Srb, thanks for showing the interest. I will start with the behaviour here
11 replies
CCConvex Community
Created by filipstefansson on 12/15/2023 in #support-community
useQuery local cache
@Michal Srb Thank you for the provided useStableQueryOverMounts example, and sorry for just jumping in there. I have a question, as I'm trying to implement it in my app. I'm doing a to do app, where as I will have different boardIds. Should I include the boardId in the key, or is it enough like this:
const getBoard = useStableQueryOverMounts(
"getBoard",
api.boards.getTasksGroupedByColumns,
{
boardId: params.boardId,
}
)
const getBoard = useStableQueryOverMounts(
"getBoard",
api.boards.getTasksGroupedByColumns,
{
boardId: params.boardId,
}
)
17 replies
CCConvex Community
Created by Mathias on 3/26/2024 in #support-community
How to group tasks by their column?
@erquhart Thank you very much! It was much simpler than I thought. Good stuff!
5 replies
CCConvex Community
Created by Mathias on 3/10/2024 in #support-community
How to query and filter with multiple arguments?
@sshader You are brilliant. Thank you!
3 replies
CCConvex Community
Created by Mathias on 3/9/2024 in #general
Hi, has anyone played around with users
@trace You are awesome. Thanks!
3 replies