fotoflo
fotoflo
Explore posts from servers
TTCTheo's Typesafe Cult
Created by fotoflo on 5/9/2024 in #questions
TRPC not returning immediately on error
Simple:
export const sitemapRouter = router({
getSitemap: protectedProcedure
.query(async ({ ctx, input }) => {
throw new Error("testing throwing errors");
})
export const sitemapRouter = router({
getSitemap: protectedProcedure
.query(async ({ ctx, input }) => {
throw new Error("testing throwing errors");
})
Component:
const {
sitemapUri,
setSitemapUri,
sitemapUrls,
sitemapIsLoading,
sitemapIsError,
sitemapError,
sitemapStatus,
sitemapUrlForm,
submitHandler,
} = useSitemaps();

return (
{sitemapError && <div>error: {sitemapError.message}</div>}
{sitemapIsError && <div>Iserror: {sitemapError.message}</div>}
{sitemapStatus && <div>Status: {sitemapStatus}</div>}
)

useSitemaps:
const {
sitemapUri,
setSitemapUri,
sitemapUrls,
sitemapIsLoading,
sitemapIsError,
sitemapError,
sitemapStatus,
sitemapUrlForm,
submitHandler,
} = useSitemaps();

return (
{sitemapError && <div>error: {sitemapError.message}</div>}
{sitemapIsError && <div>Iserror: {sitemapError.message}</div>}
{sitemapStatus && <div>Status: {sitemapStatus}</div>}
)

useSitemaps:
ts export function useSitemaps() { const { data: sitemapUrls, isLoading: sitemapIsLoading, isError: sitemapIsError, error: sitemapError, status: sitemapStatus, } = trpc.sitemaps.getSitemap.useQuery( { url: sitemapUri, } );
return { sitemapUri, setSitemapUri, sitemapUrls, sitemapIsLoading, sitemapIsError, sitemapUrlForm, submitHandler, sitemapError, sitemapStatus, }; } ```
5 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 5/8/2024 in #questions
NextJs not picking up my ENV vars - no changes made
Very strange - haven't touched this part of the code, or done any new npm installs or anything... but after restarting my workstation, im getting the Invalid Env Vars error... I've just added an var called ENV_FILENAME (with the file name of the ENV File it's in) to all the env's on my system and added
if (_serverEnv.success) {
console.log(
`✅ Valid environment variables on server - ${_serverEnv.ENV_FILENAME}`
);
}
if (_serverEnv.success) {
console.log(
`✅ Valid environment variables on server - ${_serverEnv.ENV_FILENAME}`
);
}
the ENV_FILENAME (which i've defined at the top of each env file) is coming back undefined also I've also added this custom thing to my next.config.mjs
console.log(`
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!
!! WELCOME TO T3
!!
!! Node Version: ${process.version} (use 18!)
!! Database: ${db}
!! ENV: ${env.ENV_FILENAME}
!! Your Developer Handle: ${env.DEVELOPER_HANDLE}
!! HOST: ${env.NEXT_PUBLIC_HOST}
!! NGROK: https://${env.NGROK_DOMAIN}
!!
!! Happy Coding!
!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
`);
console.log(`
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!
!! WELCOME TO T3
!!
!! Node Version: ${process.version} (use 18!)
!! Database: ${db}
!! ENV: ${env.ENV_FILENAME}
!! Your Developer Handle: ${env.DEVELOPER_HANDLE}
!! HOST: ${env.NEXT_PUBLIC_HOST}
!! NGROK: https://${env.NGROK_DOMAIN}
!!
!! Happy Coding!
!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
`);
and oddly that renders correctly, with .env.local
7 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 4/29/2024 in #questions
Optimistic Updates with TRPC Hook
I've made a hook with TRPC and am trying to create optimistic updates.. simplified below
export function useComments(urlId: string) {
const [comments, setComments] = useState([] as urlComments[]);
const [error, setError] = useState(null);
const trpcContext = trpc.useContext();


// works
const { data, isLoading, isError } = trpc.comments.getComments.useQuery(
urlId,
{
onSuccess: (data) => {
setComments(data);
},
}
);

// this is where the optimistic update happens
const commentMutation = trpc.comments.createComment.useMutation({
onMutate: async (newComment) => {
const previousComments = [...comments];
const optimisticComment = {
...newComment,
id: `temp-${Date.now()}`,
type: "TEMP",
};

setComments((oldComments) => [optimisticComment, ...previousComments]);

/// above line didnt work, below also no workie

trpcContext.timelines.getTimeline.setData("undefined", (data) => {
return [optimisticComment, ...previousComments];
});

return { previousComments }; // Return the snapshot for potential rollback
},
....
});

const addComment = (commentData) => {
commentMutation.mutate({ urlId, ...commentData });
};

return {
comments,
addComment,
error,
isLoading,
isError,
};
}
export function useComments(urlId: string) {
const [comments, setComments] = useState([] as urlComments[]);
const [error, setError] = useState(null);
const trpcContext = trpc.useContext();


// works
const { data, isLoading, isError } = trpc.comments.getComments.useQuery(
urlId,
{
onSuccess: (data) => {
setComments(data);
},
}
);

// this is where the optimistic update happens
const commentMutation = trpc.comments.createComment.useMutation({
onMutate: async (newComment) => {
const previousComments = [...comments];
const optimisticComment = {
...newComment,
id: `temp-${Date.now()}`,
type: "TEMP",
};

setComments((oldComments) => [optimisticComment, ...previousComments]);

/// above line didnt work, below also no workie

trpcContext.timelines.getTimeline.setData("undefined", (data) => {
return [optimisticComment, ...previousComments];
});

return { previousComments }; // Return the snapshot for potential rollback
},
....
});

const addComment = (commentData) => {
commentMutation.mutate({ urlId, ...commentData });
};

return {
comments,
addComment,
error,
isLoading,
isError,
};
}
and then i consume it here:
export default function Comments({
}: Props): JSX.Element {
const { comments } = useComments(id);

// RERENDER NOT HAPPENING!!
console.log({comments});

return (
<>
{comments &&
comments.map((item) => (
<Item item={item} />
))}
<>
);
}
export default function Comments({
}: Props): JSX.Element {
const { comments } = useComments(id);

// RERENDER NOT HAPPENING!!
console.log({comments});

return (
<>
{comments &&
comments.map((item) => (
<Item item={item} />
))}
<>
);
}
7 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 3/26/2024 in #questions
Firing a client-side event when the user signs in
Hi guys, I want to fire an event when a user signs in on the client side. Currently i can do it for new users cause they land on a welcome page. When a user signs in normally I increment user.logins on the server side and take them to their dashboard. Is there a good way to know if it's a new sign so i can fire a client side event?
2 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 3/9/2024 in #questions
slow trpc query seems to be delaying render of non-dependant components
I have a simple Page component:
const Page: NextPage = () => {
const { data: urlRecord } = trpc.urls.getByUrn.useQuery("string");
return (
<div record={urlRecord}>
<ComponentOne record={urlRecord} />
<ComponentTwo record={urlRecord} />
<ComponentThree record={urlRecord} />
</div>
);
};
const Page: NextPage = () => {
const { data: urlRecord } = trpc.urls.getByUrn.useQuery("string");
return (
<div record={urlRecord}>
<ComponentOne record={urlRecord} />
<ComponentTwo record={urlRecord} />
<ComponentThree record={urlRecord} />
</div>
);
};
All three sub Components have tRPC queries in them, they return a loader if isLoading. The urlRecord returns quickly (10ms), <ComponentOne> and <ComponentTwo>'s queries return in under 100ms, but <ComponentThree>'s query make take a few seconds ore more. the page loads quickly and the loaders are seen until the slowest query (CompnentThree) returns its data. Then all of the components render with data at once. Why is this? is it possible to get the components to all render when they';re ready?
8 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 10/29/2023 in #questions
Where to put / how to cache frequently used user info?
hi guys, i think i made a big mistake - i put a lot of logic in my session callback to build a nice session.user object that has a lot of the things i need to reference all the time on it. It all worked fine until i pushed to Vercel - now it's crazy slow.... So where does this kind of information typically go? My current session: https://pastebin.pl/view/d2329da1
13 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 9/12/2023 in #questions
trouble with Vercel deploy (no errors)
No description
4 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 4/1/2023 in #questions
Simple long polling with tRPC
I'm sending an email with a useMutation with MailJet. MailJet's API returns success, even when the email is queued, sending may still fail. They have another API to get the status of the email. I've created a backend function with Quirrel to keep hitting that API until i have a status that's not pending, and then put that status in my DB. Now I want to long-poll my db in the useMutation's onSuccess to check the email status. In order to do that, i create a function in the onSuccess that invalidate's the whole collection's data every second until i get the status. I'd much rather just check the ID of the item with like a Get API repeated and then invalidate everything when it changes... is there a way to do that with tRPC? Also, This sounds overly complex.
5 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 3/26/2023 in #questions
zod-prisma-types and prisma-zod-generator BOTH fail to generate
Just installed both zod-prisma-types and prisma-zod-generator
$ prisma db push

Running generate... (Use --skip-generate to skip the generators)
Error: Generator at zod-prisma-types could not start:

/bin/sh: zod-prisma-types: command not found
$ prisma db push

Running generate... (Use --skip-generate to skip the generators)
Error: Generator at zod-prisma-types could not start:

/bin/sh: zod-prisma-types: command not found
and removing that one and subbing in prisma-zod-generator i get:
Running generate... (Use --skip-generate to skip the generators)
Error: Generator at prisma-zod-generator could not start:

/bin/sh: prisma-zod-generator: command not found
Running generate... (Use --skip-generate to skip the generators)
Error: Generator at prisma-zod-generator could not start:

/bin/sh: prisma-zod-generator: command not found
have a feeling this has to do with my t3 install anyone have any idea how to debug?
13 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 3/21/2023 in #questions
chrome-launcher wont launch
It's kind of outside t3 scope but im hoping i can get some help here - the error is happening in my t3 app I'm using node to run lighthouse and chrome launcher wont launch in my dev env (mac monterey), with a t3 app It seems like there's something wrong with the dependency - (but typescript compiles) I think maybe it cant find chrome? But google chrome at /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome which google-chrome returns not found
import ChromeLauncher from "chrome-launcher";

const chromeOptions = {
chromeFlags: ["--headless", "--disable-gpu"],
};

async function launchChrome() {
try {
const chrome = await ChromeLauncher.launch(chromeOptions);
console.log("chrome running!");
return chrome;
} catch (e) {
console.log("**** Chrome failed to launch", e);
debugger; // always land here.
throw e;
}
}
import ChromeLauncher from "chrome-launcher";

const chromeOptions = {
chromeFlags: ["--headless", "--disable-gpu"],
};

async function launchChrome() {
try {
const chrome = await ChromeLauncher.launch(chromeOptions);
console.log("chrome running!");
return chrome;
} catch (e) {
console.log("**** Chrome failed to launch", e);
debugger; // always land here.
throw e;
}
}
error:
**** Chrome failed to launch TypeError: Cannot read properties of undefined (reading 'launch')
at launchChrome (webpack-internal:///(api)/./src/server/reporting/lighthouseRunner.ts:35:84)
**** Chrome failed to launch TypeError: Cannot read properties of undefined (reading 'launch')
at launchChrome (webpack-internal:///(api)/./src/server/reporting/lighthouseRunner.ts:35:84)
I tried: - Adding this to my env CHROME_PATH="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"
- Adding and removing chrome-launcher from package.json dependancies, deleting node_modules and reinstalling all "chrome-launcher": "^0.15.1",
- Making a symlink from Google\ Chrome to google-chrome (it wouldn't run from the terminal) - Copying Google\ Chrome to google-chrome, now it's in the path and launches with a warning (below) but chrome-launcher still doesnt launch ``` $ google-chrome [41560:259:0321/104228.826676:ERROR:keychain_password_mac.mm(103)] Keychain lookup failed: Error Domain=NSOSStatusErrorDomain Code=-25293 "errKCAuthFailed / errSecAuthFailed: / Authorization/Authentication failed." (-25293) Opening in existing browser session.
2 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 3/17/2023 in #questions
Help with (new) monorepo tsconfig
Ive just started merging two codebases into a monorepo basically i have FM and reporting we have a /tsconfig.json (in FM) and a /reporting/tsconfig.json after merging all the /reporting tests passed, but then after updating the prisma.schema in /prisma/prisma.schema the reporting tests started to fail both of these tsconfigs had
"paths": {
"src/*": ["./src/*"],
}
"paths": {
"src/*": ["./src/*"],
}
and a prisma client importing "src/prisma" i've now moved /reporting/src to reporting/code and done a replace all on "src/" to "code/" and then changed all the "code/prisma" references to "src/prisma" so that we should be referencing FM's prisma client but the paths in tsconifg are not resolving the way i expect...
47 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 3/14/2023 in #questions
Two repos one Prisma. Lets Merge.
Good morning guys. I just started merging two repos into a Monorepo and have no idea what im doing :-). Would love some help. I have two repos, FM and LH. FM is t3-app and LH is basically pure ts-node. They share a prisma instance. I just copied the whole LH into FM as a subdirectory. Nothing changed in the FM git status. Should i delete the .git from the LH repo to see updates into the FM repo? And delete the /FM/LH/prisma directory? Since i want /FM/prisma to be canonical?
Also now i have two jest configs, two ts configs, two package.json's, two node_modules and two sets of env...
6 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 2/20/2023 in #questions
should i just make a REST api for that?
9 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 2/14/2023 in #questions
Inviting a teammate with nextAuth
Hi guys, in [...nextAuth], the email provider is working nicely:
EmailProvider({
sendVerificationRequest(params: SendVerificationRequestParams) {
const { identifier: email, url, expires } = params;
const newParams = { ...mailjetParams, email, url };
newParams.email = params.identifier;
sendEmailWithMailjet(newParams as SendWithMailjetProps);
},
}),
EmailProvider({
sendVerificationRequest(params: SendVerificationRequestParams) {
const { identifier: email, url, expires } = params;
const newParams = { ...mailjetParams, email, url };
newParams.email = params.identifier;
sendEmailWithMailjet(newParams as SendWithMailjetProps);
},
}),
Now i want to add invite team members functionality. How can I trigger this from the server side?
50 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 2/7/2023 in #questions
nextAuth - Add to the user model
https://next-auth.js.org/adapters/models Hello, I'd like to add modify the user before it comes into the session callback in [..nextauth]
callbacks: {
async session({ session, user }) {
if (session.user) {
session.user.id = user.id;
}
callbacks: {
async session({ session, user }) {
if (session.user) {
session.user.id = user.id;
}
I found this but the authorize method never gets called: https://stackoverflow.com/questions/71185287/pass-more-data-to-session-in-next-auth is it a bad idea to overoptimze this and i should just make an extra prisma call here?
24 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 2/7/2023 in #questions
Noob Question Many-to-Many in prisma after nextAuth
Hello all! I'm trying to create my first many-to-many relationship in Prisma. schema:
model User {
id String @id @default(cuid())
teams usersInTeams[]
}

model Team {
id String @id @default(cuid())
name String @unique
slug String @unique
users usersInTeams[]
}

model usersInTeams {
userId String @db.VarChar(64)
teamId String @db.VarChar(64)
user User @relation(fields: [userId], references: [id])
team Team @relation(fields: [teamId], references: [id])
role String @default("USER")

@@id([userId, teamId])
}
model User {
id String @id @default(cuid())
teams usersInTeams[]
}

model Team {
id String @id @default(cuid())
name String @unique
slug String @unique
users usersInTeams[]
}

model usersInTeams {
userId String @db.VarChar(64)
teamId String @db.VarChar(64)
user User @relation(fields: [userId], references: [id])
team Team @relation(fields: [teamId], references: [id])
role String @default("USER")

@@id([userId, teamId])
}
export async function createTeam({ teamName, ownerId }: CreateTeamProps) {
try {
const team = await prisma.team.create({
data: {
name: teamName,
users: {
connect: [
{
userId_teamId: // the only type in intellesense, but it depends on a created team?
},
],
},
},
});

return team;
} catch (error) {
console.error(error);
return null;
}
}
export async function createTeam({ teamName, ownerId }: CreateTeamProps) {
try {
const team = await prisma.team.create({
data: {
name: teamName,
users: {
connect: [
{
userId_teamId: // the only type in intellesense, but it depends on a created team?
},
],
},
},
});

return team;
} catch (error) {
console.error(error);
return null;
}
}
but i cant for the life of me figure out how to write the createTeam() function - this is as close as i've gotten...
39 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 2/5/2023 in #questions
Moving a repo inside a repo!
Hi guys, I have two projects that i want to merge: 1. A nodejs scraper 2. A Next project They both share a single prisma schema... - The node js scraper was a bit legacy but has been rewritten with prisma! - the next project plans to read data from the scraper, so wants to share a single prisma instance I was planing to do this: 1. Merge the prisma schema (done) - db pull from the scraper into the next project, resulting in a schma with both users, and the data they want access to, yay! 2. Merge the files (structure outline below) I managed to do this successfully (the scraper and the next project run) , but it behaves like /scraper is is in the .gitignore of /nextProject - is this the reccomended way to do it? - can i have just one .git, tsconfig, env and package.json or will everything get messed up (dependancies get heavy, etc) Thank you!
/nextProject
.git
.env
.tsconfig
package.json
prisma.schema
/src. - all the usual stuff
/scraper
.git
.env
.tsconfig
.git
package.json
// NO PRISMA SCHEMA
/nextProject
.git
.env
.tsconfig
package.json
prisma.schema
/src. - all the usual stuff
/scraper
.git
.env
.tsconfig
.git
package.json
// NO PRISMA SCHEMA
103 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 2/4/2023 in #questions
trpc first callH
109 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 1/26/2023 in #questions
the best way to back up a prisma/mysql database?
https://www.prisma.io/dataguide/managing-databases/backup-considerations Prisma does a great job explaining all we should consider when setting up a backup strategy, however it looks like the prisma export command was deperecated and there's no off the shelf solution for backing up... from prisma. I guess i should look for solutions built for mysql? are there standard solutions? I dont like mysqldumb i mean dump
22 replies
TTCTheo's Typesafe Cult
Created by fotoflo on 1/25/2023 in #questions
tsconfig and import statements
All my tests (of the modules) are using import statements... However once i put an import statement in the index.ts i get this error:
$ ts-node index.ts
(node:32890) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
-> import runBatch from "src/runBatch";
$ ts-node index.ts
(node:32890) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
-> import runBatch from "src/runBatch";
Relivant lines in tsconfig.ts:
"target": "ES2020",
"lib": ["ES2020"],
"module": "ES2020",
"target": "ES2020",
"lib": ["ES2020"],
"module": "ES2020",
77 replies