3. Complete method — GetNdaListFetcher.ts
I have kept the mapping in one place to make future changes straightforward.
interface NdaAttribute {
ndaItemId: string;
name: string;
value: string;
ndaConfigOption?: {
name: string;
code: string;
description: string;
};
}
const fieldMappings = [
{
field: "voa_plotsize",
ndaItemId: "0a9e206d-b7b4-5d33-8408-7d5fa63d9bed",
name: "Plot Size"
},
{
field: "voa_rooms",
ndaItemId: "42893cb8-b3ce-dd57-b8c9-889c30e1fbed",
name: "Rooms"
},
{
field: "voa_level",
ndaItemId: "447d93ad-a66e-ff96-7152-be491ebfc5ec",
name: "Level"
},
{
field: "_voa_heatingcodeid_value",
ndaItemId: "50539220-1d91-7c8c-5db2-cd738ebd8f43",
name: "Heating"
},
{
field: "_voa_housegroupid_value",
ndaItemId: "72c20b60-ce3b-e044-7243-dcf23deb08f2",
name: "Group"
},
{
field: "_voa_conservatorytypeid_value",
ndaItemId: "81ff6d97-e5d9-86b7-53c3-8636b831ebb7",
name: "Conservatory Type"
},
{
field: "voa_bedrooms",
ndaItemId: "84f5d46c-691d-d9ce-bff9-78b9f9726694",
name: "Bedrooms"
},
{
field: "voa_conservatoryarea",
ndaItemId: "b113f2be-e9a5-fb44-38a5-b582477d441f",
name: "Conservatory Area"
},
{
field: "_voa_agecode_value",
ndaItemId: "b2de447a-440d-7c4f-f592-4af9b1714621",
name: "Age Code"
},
{
field: "voa_baths",
ndaItemId: "b61520a7-dbf1-a8ae-6240-4d9861e9ee9a",
name: "Bathrooms"
},
{
field: "_voa_parkingcodeid_value",
ndaItemId: "c6387014-a505-bb10-c0e6-993022b2d408",
name: "Parking"
},
{
field: "voa_floors",
ndaItemId: "c68e24c6-b081-1e6a-35e6-6030624d72e0",
name: "Floors"
},
{
field: "voa_area",
ndaItemId: "eaabc07e-276f-956c-3800-3c3858a147c6",
name: "Area of Dwelling"
},
{
field: "_voa_housetypecodegrouplinkid_value",
ndaItemId: "feeae5ad-a5b3-20e5-998b-55c699bc0a89",
name: "Type"
}
];
export async function getNdaAttributes(
entityType: string,
recordId: string,
webAPI: ComponentFramework.WebApi
): Promise<NdaAttribute[]> {
// Reserved for future entity-specific logic
void entityType;
const id = recordId.replace(/[{}]/g, "");
const guidRegex =
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!guidRegex.test(id)) {
throw new Error("Invalid customer submitted information ID");
}
// Build the select fields from the mapping
const selectFields = fieldMappings
.map(item => item.field)
.join(",");
const query =
`?$select=${selectFields}` +
`&$filter=voa_customersubmittedinformationid eq ${id}` +
`&$top=1`;
const result = await webAPI.retrieveMultipleRecords(
"voa_customersubmittedinformation",
query
);
if (!result.entities.length) {
return [];
}
const record = result.entities[0] as Record<string, any>;
const attributes: NdaAttribute[] = fieldMappings.map(item => {
const isLookup =
item.field.startsWith("_") &&
item.field.endsWith("_value");
const rawValue = record[item.field];
// Read the lookup display text
const formattedValue =
record[
`${item.field}@OData.Community.Display.V1.FormattedValue`
];
let value = "";
if (isLookup) {
if (rawValue != null && rawValue !== "" &&
(typeof formattedValue !== "string" ||
!formattedValue.trim() ||
guidRegex.test(formattedValue.trim()))) {
throw new Error(
`Lookup display text unavailable: ${item.field}`
);
}
value = typeof formattedValue === "string"
? formattedValue.trim()
: "";
} else {
value = rawValue == null ? "" : String(rawValue);
}
const attribute: NdaAttribute = {
ndaItemId: item.ndaItemId,
name: item.name,
value
};
// Only lookups have ndaConfigOption
if (isLookup && value) {
const hyphenIndex = value.indexOf("-");
const code = hyphenIndex >= 0
? value.substring(0, hyphenIndex).trim()
: value;
const description = hyphenIndex >= 0
? value.substring(hyphenIndex + 1).trim()
: value;
attribute.ndaConfigOption = {
name: value,
code,
description
};
}
return attribute;
});
// Reason Code is not part of the query
attributes.push({
ndaItemId: "e7c6b1e4-e8ba-d742-4464-0e2d9345a050",
name: "Reason Code",
value: "V - Validated",
ndaConfigOption: {
name: "V - Validated",
code: "V",
description: "Validated"
}
});
return attributes;
}
4. Calling the method
From your PCF control:
const ndaAttributes = await getNdaAttributes(
entityType,
"aea1419d-d0ce-f111-a05c-6045bd0b3072",
context.webAPI
);
console.log("Dynamic NDA Attributes:", ndaAttributes);entityType is accepted but deliberately not used yet, as requested. The record ID comes from the query in your screenshot; replace it when you have the current record’s ID.
import pyspark.sql.functions as F
spark = ... # initialization
df = spark.table("a").where(F.col("country") == "abc")
df_unique = df.distinct()
users_without_kids = df_unique.where(F.col("kid_count") == 0)
obser = Observation()
observed_df = users_without_kids.observe(observation, F.count(F.lit(1)).alias("row_count"))
observed_df.writeTo("b")
print(observation.get["row_count"]) Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.
