Reputation: 35112
I got here:
buyTicketData?.pricingOptions
this error:
[tsl] ERROR in /Applications/MAMP/htdocs/wp-content/plugins/tikex/tikexModule/components/BuyTicket/PricingOptionInvoiceItemsFormFieldsCheckboxes.tsx(280,25)
TS2532: Object is possibly 'undefined'.
Why it matters if left side of ?
is undefined, ?
wraps it, not?
here are the types:
buyTicketData?: BuyTicketData;
export type BuyTicketData = {
pricingOptions?: PricingOptions;
}
export type PricingOptions = {
[optionId: string]: PricingOptionType;
};
export type PricingOptionType = {
invoiceItems?: InvoiceItems;
};
export type InvoiceItems = {
[invoiceItemId: string]: InvoiceItemData;
};
export type InvoiceItemData = {
defaultValue?: number;
};
This is the whole expression anyway
<select
value={
startPaymentIn?.invoiceItems?.[key] != undefined
? startPaymentIn?.invoiceItems?.[key] == 1
? "Igen"
: "Nem"
: startPaymentIn?.pricingOptionId &&
buyTicketData?.pricingOptions?.[ // <-- here
startPaymentIn!.pricingOptionId!
].invoiceItems[key]?.defaultValue != undefined
? startPaymentIn?.pricingOptionId &&
buyTicketData?.pricingOptions?.[
startPaymentIn!.pricingOptionId!
].invoiceItems[key]?.defaultValue == 1
? "Igen"
: "Nem"
: undefined
}
OK, find the solution:
value={
startPaymentIn?.invoiceItems?.[key] != undefined
? startPaymentIn?.invoiceItems?.[key] == 1
? "Igen"
: "Nem"
: buyTicketData?.pricingOptions?.[
startPaymentIn?.pricingOptionId ?? ""
]?.invoiceItems?.[key]?.defaultValue != undefined
? buyTicketData?.pricingOptions?.[
startPaymentIn?.pricingOptionId ?? ""
]?.invoiceItems?.[key]?.defaultValue == 1
? "Igen"
: "Nem"
: undefined
}
I just do not know why this ugly ?? ""
condition need.
Upvotes: 2
Views: 1173
Reputation: 15078
You missed one optional chaining operator for the possibly undefined invoiceItems
. The defaultValue
lookup should be like this:
buyTicketData?.pricingOptions?.[startPaymentIn!.pricingOptionId!]
.invoiceItems?.[key]?.defaultValue
The following minimal reproducible example illustrates this. Try it in Playground to see the errors.
export type BuyTicketData = {
pricingOptions?: PricingOptions;
}
export type PricingOptions = {
[optionId: string]: PricingOptionType;
};
export type PricingOptionType = {
invoiceItems?: InvoiceItems
}
export type InvoiceItems = {
[invoiceItemId: string]: InvoiceItemData
}
export type InvoiceItemData = {
defaultValue?: number
}
let startPaymentIn: PricingOptionType & { pricingOptionId?: string } = {}
function testContext (key: string, buyTicketData?: BuyTicketData) {
// incrementally testing your expression until we isolate the actual error
let w = buyTicketData?.pricingOptions
let x = buyTicketData?.pricingOptions?.[startPaymentIn!.pricingOptionId!]
let y = buyTicketData?.pricingOptions?.[startPaymentIn!.pricingOptionId!].invoiceItems
let z = buyTicketData?.pricingOptions?.[startPaymentIn!.pricingOptionId!].invoiceItems[key]
// ^^^ error on this last line
// the correct expression to get the `defaultValue`
const defaultValue =
buyTicketData?.pricingOptions?.[startPaymentIn!.pricingOptionId!].invoiceItems?.[key]?.defaultValue
return startPaymentIn?.invoiceItems?.[key] != undefined
? startPaymentIn?.invoiceItems?.[key] == 1
? "Igen"
: "Nem"
: startPaymentIn?.pricingOptionId &&
buyTicketData?.pricingOptions?.[
startPaymentIn!.pricingOptionId!
].invoiceItems?.[key]?.defaultValue != undefined
? startPaymentIn?.pricingOptionId &&
buyTicketData?.pricingOptions?.[
startPaymentIn!.pricingOptionId!
].invoiceItems?.[key]?.defaultValue == 1
? "Igen"
: "Nem"
: undefined
}
Upvotes: 0
Reputation: 7718
If a
is undefined
, a.b
throws exception while a?.b
resolves to undefined
. You still need to handle the undefined
.
buyTicketData?.pricingOptions?.[startPaymentIn?.pricingOptionId]
resolves to
buyTicketData?.pricingOptions?.[undefined]
if startPaymentIn
is undefined
. This would throw error as undefined
cannot be a key.
A better way is to do a null check before everything if this variable is essential, so that you don't need ?.
at all.
if(startPaymentIn)
{
//no need to use ?. on startPayment
}
Upvotes: 5