how do i get nested email field from another model...
# orm-help
a
how do i get nested email field from another model & get a flat output bcz
email
is 3 levels deep?
License
Product
User
email
but i want to query
prisma.license.findMany()
& get
email
directly.
Copy code
export const getLicenses = async (): Promise<
  Array<License & Pick<User, 'email'>> | null | undefined
> => {
  const userSelect = Prisma.validator<Prisma.ProductSelect>()({
    user: {
      select: {
        email: true,
      },
    },
  })

  const productSelect = Prisma.validator<Prisma.LicenseSelect>()({
    product: {
      include: userSelect,
    },
  })

  const licenses = await prisma.license.findMany({
    orderBy: {
      createdAt: 'desc',
    },
    include: productSelect,
  })

  const result = licenses.map((license) => {
    const email = license.product?.user.email

    if (email) {
      return {
        ...license,
        email,
      }
    }
  })

  return result
}
i get error on the last line
return result
saying:
Copy code
Type '({ email: string; id: string; name: string; total: number; used: number; productId: string | null; createdAt: Date; product: (Product & { user: { email: string | null; }; }) | null; } | undefined)[]' is not assignable to type '(License & Pick<User, "email">)[]'.
  Type '{ email: string; id: string; name: string; total: number; used: number; productId: string | null; createdAt: Date; product: (Product & { user: { email: string | null; }; }) | null; } | undefined' is not assignable to type 'License & Pick<User, "email">'.
    Type 'undefined' is not assignable to type 'License & Pick<User, "email">'.
      Type 'undefined' is not assignable to type 'License'.ts(2322)
can't find a way to solve it? here's the full question → https://stackoverflow.com/questions/73289404/get-a-nested-email-field-that-is-part-of-another-model-in-prisma & minimal repro → https://github.com/deadcoder0904/prisma-nested-query-email
1
m
Akshay. I responded. Let me know if you need clarification or help implementing Array.reduce in place of Array.map - which is what's causing your problem.
https://codesandbox.io/s/nifty-surf-s8vcg6?file=/src/index.ts Here you'll note that eslint is even complaining with the map ("expected to return a value at the end of arrow function")
I think once you solve that problem, you'll be able to flatten your objects like you want (you can actually just do it in the reduce - instead of pushing the whole object, you'll push your created object - that's the map part of the filter/map implementation using reduce). This is a good start. Ping me if you are still stuck after replacing Array.map with Array.reduce.
On another note, if you write your filter section of reduce like this (simplified example):
Copy code
if (email) {
  ... do your stuff
};
then you can drop a debug point inside your conditional block and then you'll see exactly what data you have available to you to generate your objects:
Copy code
if (email) {
  acc.push({
    id: ...,
    email: ...,
    ....
  });
};
a
hey michael, i found the solution. no need to reduce it. i just had to remove the
if
. solution → https://stackoverflow.com/a/73292903/6141587
m
The reason is the same - you had undefined sneaking into your array when you didn't define a return for the !email case." That's what your TS error was indicating. I thought your use case was that you only wanted to return elements that did have an email - in which case you would want filter/map or reduce. But I guess not.
a
no, the function name is
getLicenses
so i wanted all licenses bcz sometimes there is no email connection as i'm using admin ui to create licenses
thanks though 😃