dannyelo
dannyelo
CCConvex Community
Created by dannyelo on 10/3/2024 in #support-community
Search Index by Two or More Fields
Hello, I'm trying to retrive a query using searchIndex. I need it to query documents by two or more fields. This is what I tried so far, but is only retriving results for legalName.
customers: defineTable({
organizationId: v.id('organizations'),
alias: v.string(),
legalName: v.optional(v.string()),
// ...rest of the fields...
})
.index('by_organizationId', ['organizationId'])
.searchIndex('search_legal_name', {
searchField: 'legalName',
filterFields: ['organizationId'],
})
.searchIndex('search_alias', {
searchField: 'alias',
filterFields: ['organizationId'],
}),
customers: defineTable({
organizationId: v.id('organizations'),
alias: v.string(),
legalName: v.optional(v.string()),
// ...rest of the fields...
})
.index('by_organizationId', ['organizationId'])
.searchIndex('search_legal_name', {
searchField: 'legalName',
filterFields: ['organizationId'],
})
.searchIndex('search_alias', {
searchField: 'alias',
filterFields: ['organizationId'],
}),
export const getCustomersSearch = query({
args: {
search: v.string(),
},
handler: async (ctx, args) => {
const currentOrganization = await getCurrentOrganization(ctx)
let customers: Doc<'customers'>[] = []

const byLegalName = await ctx.db
.query('customers')
.withSearchIndex('search_legal_name', (q) =>
q
.search('legalName', args.search)
.eq('organizationId', currentOrganization._id),
)
.take(10)

const byAlias = await ctx.db
.query('customers')
.withSearchIndex('search_alias', (q) =>
q
.search('alias', args.search)
.eq('organizationId', currentOrganization._id),
)
.take(10)

customers = [...byLegalName, ...byAlias]

return await Promise.all(
customers.map(async (customer) => transformCustomer(customer._id, ctx)),
)
},
})
export const getCustomersSearch = query({
args: {
search: v.string(),
},
handler: async (ctx, args) => {
const currentOrganization = await getCurrentOrganization(ctx)
let customers: Doc<'customers'>[] = []

const byLegalName = await ctx.db
.query('customers')
.withSearchIndex('search_legal_name', (q) =>
q
.search('legalName', args.search)
.eq('organizationId', currentOrganization._id),
)
.take(10)

const byAlias = await ctx.db
.query('customers')
.withSearchIndex('search_alias', (q) =>
q
.search('alias', args.search)
.eq('organizationId', currentOrganization._id),
)
.take(10)

customers = [...byLegalName, ...byAlias]

return await Promise.all(
customers.map(async (customer) => transformCustomer(customer._id, ctx)),
)
},
})
19 replies
CCConvex Community
Created by dannyelo on 10/1/2024 in #support-community
Type error: implicitly has type 'any' because it does not have a type annotation
No description
44 replies
CCConvex Community
Created by dannyelo on 9/26/2024 in #support-community
runAfter is not throwing an error on the client
Hello, can't understand why error is not throwing to the client. This is the pattern I'm trying to implement. I can see the Error 'Called getCurrentUser without authentication present' logged in convex, but I can't get it in the front end. I'm using Next.js. convex/customers.ts
export const upsertCustomer = mutation({
args: customerArgs,
handler: async (ctx, args) => {
const organization = await getCurrentOrganization(ctx)
return await upsertCustomerWithFacturapi(ctx, {
...args,
organizationId: organization._id,
})
},
})

async function upsertCustomerWithFacturapi(
ctx: MutationCtx,
args: CustomerArgs,
): Promise<any> {
try {
return await ctx.scheduler.runAfter(
0,
api.customers_usenode.upsertCustomerWithFacturapi,
{
...args,
},
)
} catch (error) {
return {
error: error instanceof Error ? error.message : String(error),
}
}
}
export const upsertCustomer = mutation({
args: customerArgs,
handler: async (ctx, args) => {
const organization = await getCurrentOrganization(ctx)
return await upsertCustomerWithFacturapi(ctx, {
...args,
organizationId: organization._id,
})
},
})

async function upsertCustomerWithFacturapi(
ctx: MutationCtx,
args: CustomerArgs,
): Promise<any> {
try {
return await ctx.scheduler.runAfter(
0,
api.customers_usenode.upsertCustomerWithFacturapi,
{
...args,
},
)
} catch (error) {
return {
error: error instanceof Error ? error.message : String(error),
}
}
}
convex/customers_usenode.ts
'use node'
export const upsertCustomerWithFacturapi = action({
args: customerArgs,
handler: async (ctx, args) => {
const { customerData, organizationId, customerId } = args

const facturapiCustomerData = {
// object...
}

try {
const facturapi = await getFacturapiLiveInstance({ ctx })
} catch (error) {
return {
error: error instanceof Error ? error.message : String(error),
}
}
},
})
'use node'
export const upsertCustomerWithFacturapi = action({
args: customerArgs,
handler: async (ctx, args) => {
const { customerData, organizationId, customerId } = args

const facturapiCustomerData = {
// object...
}

try {
const facturapi = await getFacturapiLiveInstance({ ctx })
} catch (error) {
return {
error: error instanceof Error ? error.message : String(error),
}
}
},
})
convex/facturapi_usenode.ts
'use node'
export const getFacturapiLiveInstance = async ({
ctx,
}: {
ctx: ActionCtx
}): Promise<Facturapi> => {
try {
const currentUserOrganization = await ctx.runQuery(
internal.organizations.getOrganizationFacturapiKeys,
)

const facturapi = new Facturapi()
return facturapi
} catch (error) {
throw new Error('Error getting Facturapi instance')
}
}
'use node'
export const getFacturapiLiveInstance = async ({
ctx,
}: {
ctx: ActionCtx
}): Promise<Facturapi> => {
try {
const currentUserOrganization = await ctx.runQuery(
internal.organizations.getOrganizationFacturapiKeys,
)

const facturapi = new Facturapi()
return facturapi
} catch (error) {
throw new Error('Error getting Facturapi instance')
}
}
121 replies
CCConvex Community
Created by dannyelo on 9/23/2024 in #support-community
Optimizing Function Calls by Avoiding Redundant Abstractions
The problem I’m facing is that I’m using an extra layer of abstraction in my code that doesn’t seem necessary. I have a function called getCurrentUserInternal, which is basically just a wrapper around another function called getCurrentUser. I’m using this wrapper to access user information inside another function, getFacturapiLiveInstance. The problem is that getCurrentUser accepts QueryCtx, and in the action I only have access to ActionCtx. Is there a better way? convex/users.ts
export const getCurrentUser = async (ctx: QueryCtx) => {
const identity = await ctx.auth.getUserIdentity()
if (!identity) {
throw new Error('Called getCurrentUser without authentication present')
}

const user = await ctx.db
.query('users')
.withIndex('by_token', (q) =>
q.eq('tokenIdentifier', identity.tokenIdentifier),
)
.unique()

if (!user) {
throw new Error('User not found')
}

return user
}

export const getCurrentUserInternal = internalQuery({
args: {},
handler: async (ctx) => {
return await getCurrentUser(ctx)
},
})
export const getCurrentUser = async (ctx: QueryCtx) => {
const identity = await ctx.auth.getUserIdentity()
if (!identity) {
throw new Error('Called getCurrentUser without authentication present')
}

const user = await ctx.db
.query('users')
.withIndex('by_token', (q) =>
q.eq('tokenIdentifier', identity.tokenIdentifier),
)
.unique()

if (!user) {
throw new Error('User not found')
}

return user
}

export const getCurrentUserInternal = internalQuery({
args: {},
handler: async (ctx) => {
return await getCurrentUser(ctx)
},
})
convex/facturapi_usenode.ts
'use node'

// ...imports

export const getFacturapiLiveInstance = async ({
organizationId,
ctx,
}: {
organizationId: Id<'organizations'>
ctx: ActionCtx
}): Promise<Facturapi> => {
await ctx.runQuery(internal.users.getCurrentUserInternal)
await getCurrentUser(ctx) -> // this ctx is an ActionCtx

// rest of the code...
}
'use node'

// ...imports

export const getFacturapiLiveInstance = async ({
organizationId,
ctx,
}: {
organizationId: Id<'organizations'>
ctx: ActionCtx
}): Promise<Facturapi> => {
await ctx.runQuery(internal.users.getCurrentUserInternal)
await getCurrentUser(ctx) -> // this ctx is an ActionCtx

// rest of the code...
}
6 replies
CCConvex Community
Created by dannyelo on 9/18/2024 in #support-community
Query Convex data from Next.js route.ts endpoint
Can I query data from Convex db in next.js route.ts endpoint? app/api/endpoint/route.ts
export async function GET(req: Request) {
// query convex data here...
}
export async function GET(req: Request) {
// query convex data here...
}
4 replies
CCConvex Community
Created by dannyelo on 9/17/2024 in #support-community
Access the action error message when fail
Hello, When I call an action that make a mutation to an external API, and the request fails, I get a Convex Error string, but I need to access the API response error message.
[CONVEX A(organizations_node:updateFacturapiCertificatesAction)] [Request ID: 14d31c10a571998b] Server Error Uncaught Error: El certificado no es un CSD. Asegúrate de no estar enviando una FIEL. at async handler (../convex/organizations_node.ts:230:6) Called by client
[CONVEX A(organizations_node:updateFacturapiCertificatesAction)] [Request ID: 14d31c10a571998b] Server Error Uncaught Error: El certificado no es un CSD. Asegúrate de no estar enviando una FIEL. at async handler (../convex/organizations_node.ts:230:6) Called by client
How can I access only the error string? In this case: El certificado no es un CSD. Asegúrate de no estar enviando una FIEL.
5 replies
CCConvex Community
Created by dannyelo on 9/16/2024 in #support-community
External API fetch advise
Hello, I'm using Convex folder for all my data-access layer now. I need to fetch some data from other APIs and they don't interact with Convex. I'm using Next.js. Is there any downside if I use an action in a 'use node' file for fetching data, or is better to use a next.js route instead?
13 replies
CCConvex Community
Created by dannyelo on 9/13/2024 in #support-community
Call internalAction in 'use node' environment, from a mutation
Hello, how can I call internalAction from a mutation, In the mutation ctx I don't have any option to do it. Is this possible?
3 replies
CCConvex Community
Created by dannyelo on 9/4/2024 in #support-community
Help using Convex Action
I'm trying to use an action because I'm calling external SDK and cryptr npm package. But I got an error, I can't find what is wrong. convex/facturapi.ts
'use node'

import Facturapi from 'facturapi' // external library
import { ActionCtx } from './_generated/server'
import { Id } from './_generated/dataModel'
import { internal } from './_generated/api'
const Cryptr = require('cryptr') // external library

const cryptr = new Cryptr(process.env.ENCRYPTION_SECRET || '123')

type FacturapiInstance = {
organizationId: Id<'organizations'>
ctx: ActionCtx
}

export const getFacturapiInstance = async ({
organizationId,
ctx,
}: FacturapiInstance): Promise<Facturapi> => {
const organization = await ctx.runQuery(
internal.internals.queries.getOrganization,
{
organizationId,
},
)
if (!organization?.facturapiTestSecret) {
throw new Error('Facturapi secret not found')
}

const decryptedKey = cryptr.decrypt(organization?.facturapiTestSecret)
const facturapi = new Facturapi(`${decryptedKey}`)

return facturapi
}
'use node'

import Facturapi from 'facturapi' // external library
import { ActionCtx } from './_generated/server'
import { Id } from './_generated/dataModel'
import { internal } from './_generated/api'
const Cryptr = require('cryptr') // external library

const cryptr = new Cryptr(process.env.ENCRYPTION_SECRET || '123')

type FacturapiInstance = {
organizationId: Id<'organizations'>
ctx: ActionCtx
}

export const getFacturapiInstance = async ({
organizationId,
ctx,
}: FacturapiInstance): Promise<Facturapi> => {
const organization = await ctx.runQuery(
internal.internals.queries.getOrganization,
{
organizationId,
},
)
if (!organization?.facturapiTestSecret) {
throw new Error('Facturapi secret not found')
}

const decryptedKey = cryptr.decrypt(organization?.facturapiTestSecret)
const facturapi = new Facturapi(`${decryptedKey}`)

return facturapi
}
convex/invoices.ts
'use node'

import { action } from './_generated/server'
import { getFacturapiInstance } from './facturapi'

export const createInvoice = action({
args: {
organizationId: v.optional(v.id('organizations')),
},
handler: async (ctx, args) => {
if (!args.organizationId) {
throw new Error('Org ID required')
}
try {
const facturapi = await getFacturapiInstance({
organizationId: args.organizationId,
ctx,
})

const invoice = {
... // invoice object
}

const createdInvoice = await facturapi.invoices.create(invoice)
return createdInvoice
} catch (error) {
throw new Error(`Error creating invoice: ${error}`)
}
},
})
'use node'

import { action } from './_generated/server'
import { getFacturapiInstance } from './facturapi'

export const createInvoice = action({
args: {
organizationId: v.optional(v.id('organizations')),
},
handler: async (ctx, args) => {
if (!args.organizationId) {
throw new Error('Org ID required')
}
try {
const facturapi = await getFacturapiInstance({
organizationId: args.organizationId,
ctx,
})

const invoice = {
... // invoice object
}

const createdInvoice = await facturapi.invoices.create(invoice)
return createdInvoice
} catch (error) {
throw new Error(`Error creating invoice: ${error}`)
}
},
})
Error
invoices:createInvoice failure
Uncaught Error: Error creating invoice: Error: Unsupported state or unable to authenticate data at handler (../convex/invoices.ts:155:4)
invoices:createInvoice failure
Uncaught Error: Error creating invoice: Error: Unsupported state or unable to authenticate data at handler (../convex/invoices.ts:155:4)
8 replies
CCConvex Community
Created by dannyelo on 9/3/2024 in #support-community
Encrypt organizations secrets
I'm using an external API, where I'm going to create a 1:1 relationship between the organizations in my database and the organizations created in the API. For each request in the external API, I need a secret key per organization for making requests. I need to store in my database the secret key for each organization, but I need to encrypt it. I was thinking of using Cryptr (npm), but reading the Convex documentation, I see that not all npm packages are accepted by convex. Any recommendations would be greatly appreciated.
5 replies
CCConvex Community
Created by dannyelo on 8/29/2024 in #support-community
[ERROR] Could not resolve "node:async_hooks"
Hello, I have this error when trying to run npx convex dev Any idea?
⠦ Preparing Convex functions...
✘ [ERROR] Could not resolve "node:async_hooks"

node_modules/@clerk/nextjs/dist/esm/server/clerkMiddleware.js:1:34:
1 │ import { AsyncLocalStorage } from "node:async_hooks";
╵ ~~~~~~~~~~~~~~~~~~

The package "node:async_hooks" wasn't found on the file system but is built into node. Are
you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove
this error.
⠦ Preparing Convex functions...
✘ [ERROR] Could not resolve "node:async_hooks"

node_modules/@clerk/nextjs/dist/esm/server/clerkMiddleware.js:1:34:
1 │ import { AsyncLocalStorage } from "node:async_hooks";
╵ ~~~~~~~~~~~~~~~~~~

The package "node:async_hooks" wasn't found on the file system but is built into node. Are
you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove
this error.
4 replies
CCConvex Community
Created by dannyelo on 8/27/2024 in #support-community
Cleanest way to handle optional filters
Hello, I need to filter orders table by status /orders route should get all orders /orders?status=pending should get orders with the status of 'pending' What should I pass to ignore the filter? I tried this and is not working.
export const getOrders = query({
args: {
organizationId: v.optional(v.id('organizations')),
status: v.optional(v.string()),
},
handler: async (ctx, args) => {
const orders = await ctx.db
.query('orders')
.filter((q) => q.eq(q.field('organizationId'), args.organizationId))
.filter((q) => {
if (!args.status) {
return null
}
return q.eq(q.field('status'), args.status)
})
.collect()

const mappedOrders = await Promise.all(
orders.map(async (order) => {
return await transformOrderForClient(order, ctx)
}),
)
return mappedOrders
},
})
export const getOrders = query({
args: {
organizationId: v.optional(v.id('organizations')),
status: v.optional(v.string()),
},
handler: async (ctx, args) => {
const orders = await ctx.db
.query('orders')
.filter((q) => q.eq(q.field('organizationId'), args.organizationId))
.filter((q) => {
if (!args.status) {
return null
}
return q.eq(q.field('status'), args.status)
})
.collect()

const mappedOrders = await Promise.all(
orders.map(async (order) => {
return await transformOrderForClient(order, ctx)
}),
)
return mappedOrders
},
})
11 replies
CCConvex Community
Created by dannyelo on 8/24/2024 in #support-community
Extracted function types
Hello! I extracted a function to map a query. But I can't find the correct types. I'm looking for the type order, orderLine, ctx and q. order and orderLine are raw records in the database.
const transformOrderForClient = async (order: any, ctx: any) => {
const orderLines = await ctx.db
.query('order_lines')
.filter((q: any) => q.eq(q.field('orderId'), order._id))
.collect()

const mappedOrderLines = await Promise.all(
orderLines.map(async (orderLine: any) => {
const product = await ctx.db.get(orderLine.productId)
console.log('product', orderLine)

return {
// ...
}
}),
)

const grandTotalAmount = orderLines.reduce((acc: any, orderLine: any) => {
return acc + orderLine?.price * orderLine?.quantity
}, 0)
const grandTotalQuantity = orderLines.reduce((acc: any, orderLine: any) => {
return acc + orderLine.quantity
}, 0)

return {
// ...
}
}
const transformOrderForClient = async (order: any, ctx: any) => {
const orderLines = await ctx.db
.query('order_lines')
.filter((q: any) => q.eq(q.field('orderId'), order._id))
.collect()

const mappedOrderLines = await Promise.all(
orderLines.map(async (orderLine: any) => {
const product = await ctx.db.get(orderLine.productId)
console.log('product', orderLine)

return {
// ...
}
}),
)

const grandTotalAmount = orderLines.reduce((acc: any, orderLine: any) => {
return acc + orderLine?.price * orderLine?.quantity
}, 0)
const grandTotalQuantity = orderLines.reduce((acc: any, orderLine: any) => {
return acc + orderLine.quantity
}, 0)

return {
// ...
}
}
3 replies
CCConvex Community
Created by dannyelo on 8/20/2024 in #support-community
Zod and Convex type error
Hello, I'm using Zod to validate my forms. When I pass the form data to a mutation function, I got a type error. The function expect some convex ids and the zod schema is a simple string. What is the fix here? Zod Schema
const OrderFormSchema = z.object({
salesChannelId: z.string(),
customerId: z.string(),
status: z.string(),
...
})
const OrderFormSchema = z.object({
salesChannelId: z.string(),
customerId: z.string(),
status: z.string(),
...
})
Expecting
args: {
salesChannelId: v.id('sales_channels'),
customerId: v.id('customers'),
status: v.string(),
...
},
args: {
salesChannelId: v.id('sales_channels'),
customerId: v.id('customers'),
status: v.string(),
...
},
Error
Types of property 'customerId' are incompatible.
Type 'string' is not assignable to type 'Id<"customers">'.
Types of property 'customerId' are incompatible.
Type 'string' is not assignable to type 'Id<"customers">'.
4 replies
CCConvex Community
Created by dannyelo on 8/16/2024 in #support-community
Best way to handle this ts error using useQuery()
Hello, I want to know what advise can you give me to handle this situation when using useQuery. Example code
const customers =
useQuery(api.sales_channels.getCustomers, {
organizationId: currentOrganization?._id,
}) || []
const customers =
useQuery(api.sales_channels.getCustomers, {
organizationId: currentOrganization?._id,
}) || []
TS Error in (organizationId):
Type 'Id<"organizations"> | undefined' is not assignable to type 'Id<"organizations">'.
Type 'undefined' is not assignable to type 'Id<"organizations">'.ts(2322)
(property) organizationId: Id<"organizations">
Type 'Id<"organizations"> | undefined' is not assignable to type 'Id<"organizations">'.
Type 'undefined' is not assignable to type 'Id<"organizations">'.ts(2322)
(property) organizationId: Id<"organizations">
3 replies
CCConvex Community
Created by dannyelo on 8/12/2024 in #support-community
Insert a record, then another record with the id of the first one in the same transaction
Hello, I have some tables orders and order_products This is the schema:
orders: defineTable({
organizationId: v.id('organizations'),
customerId: v.id('customers'),
salesChannelId: v.id('sales_channels'),
status: v.string(),
folio_number: v.number(),
}),
order_products: defineTable({
orderId: v.id('orders'),
productId: v.id('products'),
quantity: v.number(),
price: v.number(),
discount: v.number(),
taxes: v.array(v.id('taxes')),
})
orders: defineTable({
organizationId: v.id('organizations'),
customerId: v.id('customers'),
salesChannelId: v.id('sales_channels'),
status: v.string(),
folio_number: v.number(),
}),
order_products: defineTable({
orderId: v.id('orders'),
productId: v.id('products'),
quantity: v.number(),
price: v.number(),
discount: v.number(),
taxes: v.array(v.id('taxes')),
})
I'm trying to construct a create function but I'm not sure how to get the orderId first to assign it to all the order_products Is this the correct approach?
export const createOrder = mutation({
args: {
organizationId: v.id('organizations'),
salesChannelId: v.id('sales_channels'),
customerId: v.id('customers'),
products: v.array(
v.object({
productId: v.id('products'),
quantity: v.number(),
price: v.number(),
discount: v.number(),
taxes: v.array(v.id('taxes')),
})
),
},
handler: async (ctx, args) => {
const { organizationId, salesChannelId, customerId } = args
const orderId = await ctx.db.insert('orders', {
organizationId,
salesChannelId,
customerId,
folio_number: 1,
status: 'pending',
})

args.products.forEach(async (product) => {
await ctx.db.insert('order_products', {
orderId,
productId: product.productId,
quantity: product.quantity,
price: product.price,
discount: product.discount,
taxes: product.taxes || [],
})
})
},
})
export const createOrder = mutation({
args: {
organizationId: v.id('organizations'),
salesChannelId: v.id('sales_channels'),
customerId: v.id('customers'),
products: v.array(
v.object({
productId: v.id('products'),
quantity: v.number(),
price: v.number(),
discount: v.number(),
taxes: v.array(v.id('taxes')),
})
),
},
handler: async (ctx, args) => {
const { organizationId, salesChannelId, customerId } = args
const orderId = await ctx.db.insert('orders', {
organizationId,
salesChannelId,
customerId,
folio_number: 1,
status: 'pending',
})

args.products.forEach(async (product) => {
await ctx.db.insert('order_products', {
orderId,
productId: product.productId,
quantity: product.quantity,
price: product.price,
discount: product.discount,
taxes: product.taxes || [],
})
})
},
})
Thanks!
11 replies
CCConvex Community
Created by dannyelo on 8/9/2024 in #support-community
Query organizations that belong to one user
Hello, I'm trying to query multiple organizations a user is assigned. Here I share my code. Is this the best way to make this types of queries? Thanks! schema.ts
organizations: defineTable({
legal_name: v.string(),
support_email: v.string(),
phone: v.string(),
}),
organization_users: defineTable({
userId: v.string(), // clerk user id
organizationId: v.id("organizations"),
role: v.string(),
}),
organizations: defineTable({
legal_name: v.string(),
support_email: v.string(),
phone: v.string(),
}),
organization_users: defineTable({
userId: v.string(), // clerk user id
organizationId: v.id("organizations"),
role: v.string(),
}),
organizations.ts
export const getUserOrganizations = query({
args: {
userId: v.string(), // clerk user id
},
handler: async (ctx, args) => {
// Get user organizations ids
const userOrgs = await ctx.db
.query("organization_users")
.filter((q) => q.eq(q.field("userId"), args.userId))
.collect();
const organizationsIds = userOrgs.map((org) => org.organizationId);

const organizations = await ctx.db.query('organizations').filter((q) => q.) // I'm stuck here...
return organizations;
},
});
export const getUserOrganizations = query({
args: {
userId: v.string(), // clerk user id
},
handler: async (ctx, args) => {
// Get user organizations ids
const userOrgs = await ctx.db
.query("organization_users")
.filter((q) => q.eq(q.field("userId"), args.userId))
.collect();
const organizationsIds = userOrgs.map((org) => org.organizationId);

const organizations = await ctx.db.query('organizations').filter((q) => q.) // I'm stuck here...
return organizations;
},
});
3 replies
CCConvex Community
Created by dannyelo on 7/29/2024 in #support-community
.jpg images are uploading with 0 KB while .webp are OK
No description
1 replies
CCConvex Community
Created by dannyelo on 7/29/2024 in #support-community
Need help using the uploadstuff api
No description
43 replies
CCConvex Community
Created by dannyelo on 7/27/2024 in #support-community
v.string().isOptional property not working
Hello, I saw available the isOptional property in the v.string() But I have an error after I use it in the property name.
Type 'string' is not assignable to type 'Validator<any, OptionalProperty, any>'.ts(2322)
(property) color: "required"
Type 'string' is not assignable to type 'Validator<any, OptionalProperty, any>'.ts(2322)
(property) color: "required"
Any suggestion?
5 replies