W
Wasp-lang•5mo ago
JLegendz

New user fields not recognized

I'm attempting to add some attributes to my user entity that have a relation to other entity attributes.
entity User {=psl
id Int @id @default(autoincrement())
createdAt DateTime @default(now())

email String? @unique
username String? @unique
lastActiveTimestamp DateTime @default(now())
isAdmin Boolean @default(false)

stripeId String?
checkoutSessionId String?
subscriptionTier String?
subscriptionStatus String?
sendEmail Boolean @default(false)
datePaid DateTime?
credits Int @default(3)

gptResponses GptResponse[]
contactFormMessages ContactFormMessage[]
tasks Task[]
files File[]

subscriptions Listing[] @relation("UserSubscriptions")
listings Listing[]
advertisements Advertisement[]
claims Advertisement[] @relation("UserClaims")

psl=}
entity User {=psl
id Int @id @default(autoincrement())
createdAt DateTime @default(now())

email String? @unique
username String? @unique
lastActiveTimestamp DateTime @default(now())
isAdmin Boolean @default(false)

stripeId String?
checkoutSessionId String?
subscriptionTier String?
subscriptionStatus String?
sendEmail Boolean @default(false)
datePaid DateTime?
credits Int @default(3)

gptResponses GptResponse[]
contactFormMessages ContactFormMessage[]
tasks Task[]
files File[]

subscriptions Listing[] @relation("UserSubscriptions")
listings Listing[]
advertisements Advertisement[]
claims Advertisement[] @relation("UserClaims")

psl=}
subscriptions and claims are the new addition I'm adding. On one of my pages where I'm already reading user.credits, I'm also trying to read user.subscriptions, but I get the following error: [ Wasp ] ext-src/client/app/ListingDetailsPage.tsx(61,25): error TS2551: Property 'subscriptions' does not exist on type 'AuthUser'. Did you mean 'subscriptionTier'?
20 Replies
kapa.ai
kapa.ai•5mo ago
Hi @JLegendz. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- It seems like you're trying to access the subscriptions field on the AuthUser type, but it's not recognized. This could be due to a couple of reasons: 1. The subscriptions field is not being recognized by Wasp. There have been instances where some fields aren't recognized/compiled by Wasp depending on where they are within the entity object. A user reported a similar issue on Github (https://github.com/wasp-lang/wasp/issues/805) where they didn't notice some properties in Prisma Studio until they moved them to the top of the Entity object. After doing so, they finally got the migrate DB message. You could try moving the subscriptions field to a different location in your User entity and see if that helps. 2. The AuthUser type might not include the subscriptions field. The AuthUser type is a simplified version of the User entity used for authentication and it might not include all the fields of the User entity. You can check the Wasp documentation (https://wasp-lang.dev/docs/auth/entities#auth-entity-) for more details on how the Auth entity is connected to the User entity. If none of the above solutions work, it might be a good idea to raise an issue on the Wasp Github page or ask for help in the Wasp Discord community. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @JLegendz, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
JLegendz
JLegendz•5mo ago
@kapa.ai Where can I update the AuthUser to include the rest of the fields from my User entity?
kapa.ai
kapa.ai•5mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- The AuthUser type is a simplified version of the User entity used for authentication and it might not include all the fields of the User entity. However, the AuthUser type is not directly editable by the developer. It is managed by Wasp and it includes only the basic fields necessary for authentication. If you need to access additional fields from the User entity, you would typically do this by fetching the user from the database using the id from the AuthUser object. This would give you a User object that includes all the fields defined in your User entity. For more information on how the User entity is connected to the rest of the auth system, you can check the Wasp documentation (https://wasp-lang.dev/docs/auth/entities#auth-entity-). If you need further assistance, consider reaching out to the Wasp community on their Discord server or GitHub page. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @JLegendz, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
JLegendz
JLegendz•5mo ago
@kapa.ai can you give me a coded example of how I would access those additional fields?
kapa.ai
kapa.ai•5mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Sure, here's a general example of how you might fetch a user from the database using the id from the AuthUser object. This example assumes you're using Prisma as your database client, which is the default in Wasp.
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

// Assume `authUser` is your authenticated user object
const authUser = { id: 1, username: 'example' }

// Fetch the full user object from the database
const fullUser = await prisma.user.findUnique({
where: {
id: authUser.id
},
include: {
subscriptions: true, // Include related subscriptions
claims: true, // Include related claims
}
})

console.log(fullUser.subscriptions)
console.log(fullUser.claims)
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

// Assume `authUser` is your authenticated user object
const authUser = { id: 1, username: 'example' }

// Fetch the full user object from the database
const fullUser = await prisma.user.findUnique({
where: {
id: authUser.id
},
include: {
subscriptions: true, // Include related subscriptions
claims: true, // Include related claims
}
})

console.log(fullUser.subscriptions)
console.log(fullUser.claims)
In this example, fullUser is a User object that includes all the fields defined in your User entity, including the subscriptions and claims fields. You can then access these fields directly on the fullUser object. Please note that this is a general example and you might need to adjust it to fit your specific use case and environment. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @JLegendz, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
JLegendz
JLegendz•5mo ago
@kapa.ai I created the following query, but subscriptions still isn't available: export const getUserById: GetUserById<void, User> = async (_args, context) => { if (!context.user) { throw new HttpError(401); } return context.entities.User.findUnique({ where: { id: context.user.id, }, include: { subscriptions: true, claims: true, } }) } I'm seeing the same data as before, that doesn't include any subscriptions or claims properties. error TS2551: Property 'subscriptions' does not exist on type 'GetResult<{ id: number; createdAt: Date; email: string; username: string; lastActiveTimestamp: Date; isAdmin: boolean; stripeId: string; checkoutSessionId: string; subscriptionTier: string; subscriptionStatus: string; sendEmail: boolean; datePaid: Date; credits: number; }, unknown> & {}'. Did you mean 'subscriptionTier'?
kapa.ai
kapa.ai•5mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- The error message suggests that the subscriptions and claims fields are not recognized on the User type. This could be due to the fact that the User type defined in your Wasp code does not include these fields. In Wasp, the types for your entities are automatically generated based on your entity definitions. If you've added new fields to an entity, you need to make sure that these fields are also included in the entity's type definition. Here's how you can update your User entity to include the subscriptions and claims fields:
entity User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
email String? @unique
username String? @unique
lastActiveTimestamp DateTime @default(now())
isAdmin Boolean @default(false)
stripeId String?
checkoutSessionId String?
subscriptionTier String?
subscriptionStatus String?
sendEmail Boolean @default(false)
datePaid DateTime?
credits Int @default(3)
gptResponses GptResponse[]
contactFormMessages ContactFormMessage[]
tasks Task[]
files File[]
subscriptions Subscription[] @relation("UserSubscriptions")
listings Listing[]
advertisements Advertisement[]
claims Advertisement[] @relation("UserClaims")
}
entity User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
email String? @unique
username String? @unique
lastActiveTimestamp DateTime @default(now())
isAdmin Boolean @default(false)
stripeId String?
checkoutSessionId String?
subscriptionTier String?
subscriptionStatus String?
sendEmail Boolean @default(false)
datePaid DateTime?
credits Int @default(3)
gptResponses GptResponse[]
contactFormMessages ContactFormMessage[]
tasks Task[]
files File[]
subscriptions Subscription[] @relation("UserSubscriptions")
listings Listing[]
advertisements Advertisement[]
claims Advertisement[] @relation("UserClaims")
}
In this example, I've assumed that Subscription and Advertisement are the types of the subscriptions and claims fields, respectively. You should replace these with the actual types of these fields in your application. After updating your entity definition, you should be able to access the subscriptions and claims fields in your query:
export const getUserById: GetUserById<void, User> = async (_args, context) => {
if (!context.user) {
throw new HttpError(401);
}

return context.entities.User.findUnique({
where: {
id: context.user.id,
},
include: {
subscriptions: true,
claims: true,
}
})
}
export const getUserById: GetUserById<void, User> = async (_args, context) => {
if (!context.user) {
throw new HttpError(401);
}

return context.entities.User.findUnique({
where: {
id: context.user.id,
},
include: {
subscriptions: true,
claims: true,
}
})
}
If you're still having trouble, it might be a good idea to ask for help in the Wasp community on their Discord server or GitHub page. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @JLegendz, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
JLegendz
JLegendz•5mo ago
@kapa.ai no, subscriptions is just the name of an array of listings that the user is subscribed to. It is correctly described as subscriptions Listing[] @relation("UserSubscriptions")
kapa.ai
kapa.ai•5mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- I see, so subscriptions is a relation field that represents a list of Listing entities that the user is subscribed to. The error you're seeing suggests that the subscriptions field is not recognized on the User type. This could be due to the fact that the User type defined in your Wasp code does not include these fields. In Wasp, the types for your entities are automatically generated based on your entity definitions. If you've added new fields to an entity, you need to make sure that these fields are also included in the entity's type definition. Here's how you can update your User entity to include the subscriptions field:
entity User {{
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
email String? @unique
username String? @unique
lastActiveTimestamp DateTime @default(now())
isAdmin Boolean @default(false)
stripeId String?
checkoutSessionId String?
subscriptionTier String?
subscriptionStatus String?
sendEmail Boolean @default(false)
datePaid DateTime?
credits Int @default(3)
gptResponses GptResponse[]
contactFormMessages ContactFormMessage[]
tasks Task[]
files File[]
subscriptions Listing[] @relation("UserSubscriptions")
listings Listing[]
advertisements Advertisement[]
claims Advertisement[] @relation("UserClaims")
}}
entity User {{
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
email String? @unique
username String? @unique
lastActiveTimestamp DateTime @default(now())
isAdmin Boolean @default(false)
stripeId String?
checkoutSessionId String?
subscriptionTier String?
subscriptionStatus String?
sendEmail Boolean @default(false)
datePaid DateTime?
credits Int @default(3)
gptResponses GptResponse[]
contactFormMessages ContactFormMessage[]
tasks Task[]
files File[]
subscriptions Listing[] @relation("UserSubscriptions")
listings Listing[]
advertisements Advertisement[]
claims Advertisement[] @relation("UserClaims")
}}
After updating your entity definition, you should be able to access the subscriptions field in your query:
export const getUserById: GetUserById<void, User> = async (_args, context) => {{
if (!context.user) {{
throw new HttpError(401);
}}

return context.entities.User.findUnique({{
where: {{
id: context.user.id,
}},
include: {{
subscriptions: true,
claims: true,
}}
}})
}}
export const getUserById: GetUserById<void, User> = async (_args, context) => {{
if (!context.user) {{
throw new HttpError(401);
}}

return context.entities.User.findUnique({{
where: {{
id: context.user.id,
}},
include: {{
subscriptions: true,
claims: true,
}}
}})
}}
If you're still having trouble, it might be a good idea to ask for help in the Wasp community on their Discord server or GitHub page. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @JLegendz, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
JLegendz
JLegendz•5mo ago
@kapa.ai this whole approach doesn't seem to be working. Prisma Studio shows my data there. But I still can't access it from my user object. Any other ideas?
kapa.ai
kapa.ai•5mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- I'm sorry to hear that you're still having trouble accessing the subscriptions field from your User object. Currently, Wasp provides a simplified user object to the page's React component when authRequired is set to true. This user object contains only the basic fields necessary for authentication, and it might not include all the fields of the User entity. There is an open Github issue (https://github.com/wasp-lang/wasp/issues/1554) discussing the possibility of allowing a custom query for fetching the user, which would then be used to fetch the user (instead of using default User.find). This would allow you to enrich the user object with more information, such as the subscriptions field, without needing to make additional queries in your React component. However, this feature has not been implemented yet. For now, you might need to make an additional query in your React component to fetch the full User object, including the subscriptions field, from the database. Here's a general example of how you might do this:
import { useQuery } from '@apollo/client'
import { GET_USER } from './queries' // Replace with your actual query

export const MyComponent = ({ user }) => {
const { data, loading, error } = useQuery(GET_USER, {
variables: { id: user.id },
})

if (loading) return 'Loading...'
if (error) return `Error! ${error.message}`

// Now you have access to the full user object, including the subscriptions field
console.log(data.user.subscriptions)

// ...
}
import { useQuery } from '@apollo/client'
import { GET_USER } from './queries' // Replace with your actual query

export const MyComponent = ({ user }) => {
const { data, loading, error } = useQuery(GET_USER, {
variables: { id: user.id },
})

if (loading) return 'Loading...'
if (error) return `Error! ${error.message}`

// Now you have access to the full user object, including the subscriptions field
console.log(data.user.subscriptions)

// ...
}
In this example, GET_USER would be a GraphQL query that fetches a user by their id, including the subscriptions field. You would need to replace this with your actual query. I hope this helps! If you have any further questions, don't hesitate to ask. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @JLegendz, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
JLegendz
JLegendz•5mo ago
What worked, was the following. 1. Import type User from 'wasp/entities' 2. Create and import getUserById from 'wasp/client/operations'. I pasted it somewhere above. 3. Pass { user }: { user: User } as a prop to my page. 4. I followed the most recent suggestion from the ai and added the following to my component.
const { data: thisUser} = useQuery(getUserById, {
variables: {id: user.id}
})

console.log(thisUser.subscriptions.map(subscription => subscription.listingName))
const { data: thisUser} = useQuery(getUserById, {
variables: {id: user.id}
})

console.log(thisUser.subscriptions.map(subscription => subscription.listingName))
This worked to finally pull that data from my user.
martinsos
martinsos•5mo ago
@sodic can you pls give this a look?
Filip
Filip•5mo ago
Sure, I'll handle this 🙂 @JLegendz I'll be with you first thing tomorrow (not at home right now). Hope it can wait 🤞
JLegendz
JLegendz•5mo ago
No worries. I was about to get it working. I think it was mainly #3 in my post.
Filip
Filip•5mo ago
Hey @JLegendz, I've read through the entire thing First, the AuthUser approach - yes, this would be ideal. But, as Kappa said, we don't yet support adding extra stuff to the AuthUser. So, with the current state of Wasp, the custom Query is the way to go. After taking a look at your custom query (getUserById), I have some questions. From what I understood, you got it working. This is a little surprising becuase, if you're using the query you pasted above, I'd expect it to: - Work in runtime. - Report type errors in the IDE (user has no property subscriptions, as you've previously mentioned) If this is indeed the case, that's happening because you've annotated the Query with GetUserById<void, User>, which overrides the true type your query returns (User with extra stuff, such as subscriptions and claims) with a supertype (just User). In other words, the query truly does return the object with everything you need, but the GetUserById<void, User> annotation tells TypeScript that the query returns a User (which doesn't contain those things). This is a TS thing, not really Wasp specific, but we keep getting this question all the time and I'm not sure why Kappa hasn't picked it up yet: @JLegendz please take a look at these messages for context. These guys had the same problem as you: - https://discord.com/channels/686873244791210014/1186410195732140073/1186603845418237952 - https://discord.com/channels/686873244791210014/1233163179140321362/1233355665339318313 I'd normally repeat the entire thing for less experienced users, but I believe you'll have no trouble mapping this to your specific case. Still, if you need me to go deeper into it, I"d be happy to! Always love discussion TS weirdness 🙂
martinsos
martinsos•5mo ago
@sodic if we keep getting this question often, do you have any ideas how we might help people figure it out on their own? Is there a way we can improve our API, or add sometihng to the docs?
Filip
Filip•5mo ago
We have an issue for it. I don't know the exact number, check one of the linked message Here it is: https://github.com/wasp-lang/wasp/issues/1920 Hey @JLegendz, any further questions here? Did you get it working?
martinsos
martinsos•5mo ago
Awesome, thanks!
JLegendz
JLegendz•5mo ago
I was able to get it working. Thank you all. I’m at work atm, but I’ll look over the responses here in more detail when I get off.
Want results from more Discord servers?
Add your server