Skip to content

Conversation

@Sarath1018
Copy link
Contributor

@Sarath1018 Sarath1018 commented Dec 10, 2025

Add getById method to ChoiceSetService for retrieving choice set values
Add POST method support to pagination system (first service to use POST for pagination)
Add parseItemsFn to handle API responses that return items as JSON strings

API call: datafabric_/api/EntityService/entity//query_expansion
SDK method: sdk.entities.choicesets.getById()

refer this page for API response and SDK response: https://uipath.atlassian.net/wiki/spaces/~61b7366691c049006fa31d3c/pages/89979912726/getChoicesetValue+-+gets+the+value+of+a+single+CS

@Sarath1018 Sarath1018 force-pushed the sarath/getChoicesetValue branch from fe14606 to d063a89 Compare December 10, 2025 07:06
@Sarath1018 Sarath1018 force-pushed the sarath/getChoicesetValue branch from d063a89 to 0c862a6 Compare December 10, 2025 07:23
/** Human-readable display name */
displayName: string;
/** Numeric identifier */
numberId: number;
Copy link
Contributor Author

@Sarath1018 Sarath1018 Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about ordinal/index instead of numberId

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check this name in entity get records response, where a field is choiceset

@Sarath1018 Sarath1018 force-pushed the sarath/getChoicesetValue branch from a01eb00 to 0d007ad Compare December 10, 2025 14:41
CreatedBy: string;
UpdatedBy: string;
RecordOwner: string;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some if these fields are optional right? for eg RecordOwner

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made them optional, previously they are optional only in SDK response

@Sarath1018 Sarath1018 requested a review from swati354 December 13, 2025 17:49
/**
* Represents a single choice set value/record
*/
export interface ChoiceSetValue {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChoiceSetGetResponse ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to ChoiceSetValueGetResponse

Comment on lines +53 to +56
export type ChoiceSetGetByIdOptions = {
/** Level of entity expansion (default: 0) */
expansionLevel?: number;
} & PaginationOptions;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the underlying query_expansion api provide other options as well?

serviceAccess: this.createPaginationServiceAccess(),
getEndpoint: () => DATA_FABRIC_ENDPOINTS.CHOICESETS.GET_BY_ID(choicesetId),
transformFn: transformChoiceSetValue,
parseItemsFn: parseJsonArray<RawChoiceSetValue>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can the parseItemsFn method be part of the transformFn itself?

@swati354
Copy link
Collaborator

Is it going to be choicesetId or choiceSetId?
In entity files, it is choiceSet, in choiceset files it is choiceset

Comment on lines 100 to 104
const transformChoiceSetValue = (item: RawChoiceSetValue): ChoiceSetValue => {
// First convert PascalCase to camelCase, then rename time fields
const camelCased = pascalToCamelCaseKeys(item);
return transformData(camelCased, EntityMap) as unknown as ChoiceSetValue;
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we avoid the as unknown as

@Sarath1018 Sarath1018 changed the title Add getChoicesetValue API Add getChoicesetValue API [PLT-93574] Dec 16, 2025
* @example
* ```typescript
* // Get all values (non-paginated)
* const values = await sdk.entities.choicesets.getById('choiceset-uuid');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use <choicesetId> conventionfor params

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 65 to 67
* const values = await sdk.entities.choicesets.getById('choiceset-uuid', {
* expansionLevel: 1
* });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add what happen with expansionLevel

/**
* Raw ChoiceSet Value API Response (PascalCase from API)
*/
export interface RawChoiceSetValue {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RawChoiceSetValueGetResponse ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, done

/** Name of the choice set value */
name: string;
/** Human-readable display name */
displayName: string;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff between displayName and name? do we need both?

/** Human-readable display name */
displayName: string;
/** Numeric identifier */
numberId: number;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check this name in entity get records response, where a field is choiceset

updateTime: 'updatedTime',
sqlType: 'fieldDataType',
fieldDefinition: 'fieldMetaData'
fieldDefinition: 'fieldMetaData'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forwhich sdk method this is intended?

* Choice Set values endpoint pagination constants
* Note: The API returns items as a JSON string in 'jsonValue' field
*/
export const CHOICESET_VALUES_PAGINATION = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we reuse ENTITY_PAGINATION ?

additionalParams,
transformFn,
parseItemsFn,
method = 'GET',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have constant for 'GET'

const items = response.data?.[itemsField] || [];
// Make the API call based on method
let response: { data: any };
if (method === 'POST') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const for post

excludeFromPrefix?: string[];

/** HTTP method to use for the request (default: 'GET') */
method?: 'GET' | 'POST';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we have enum?

@Raina451
Copy link
Collaborator

check if we need an update here

@Raina451
Copy link
Collaborator

@Sarath1018 we need add scopes for new sdk methods you are adding in docs: https://uipath.github.io/uipath-typescript/oauth-scopes

@JReames
Copy link

JReames commented Jan 7, 2026

Summary

The root cause was a mismatch between the entity's data format (Integer) and the Choice Set's primary key format (GUID). By identifying the NumberId property in the choice set definition and mapping it alongside the GUID, we created a robust solution that handles both data types seamlessly. The "Status Unknown" error is resolved, and the solution is fully dynamic, requiring no hardcoded values.

SDK Improvement Proposal

To streamline this in future versions of the UiPath Apps SDK, we recommend the following changes to the uipath-typescript library.

1. Add ChoiceSetOption Interface

File: src/models/data-fabric/entities.types.ts

Define the interface to formalize the structure of choice set options, specifically exposing the previously hidden NumberId.

/**
 * Represents a single option within a Choice Set
 */
export interface ChoiceSetOption {
  /** Unqiue GUID identifier */
  id: string;
  /** Display name shown in UI */
  displayName: string;
  /** Internal system name */
  name: string;
  /** Numeric status code (Critical for legacy/integer based choice sets) */
  numberId?: number;
  /** Alternate value field */
  value?: string;
}

2. Implement getChoiceSet Method

File: src/services/data-fabric/entities.ts

Add a method to EntityService that fetches choice set options directly by ID or Name, handling the NumberId mapping logic internally.

  /**
   * Gets choice set options by ID
   * 
   * @param id - UUID of the choice set
   * @returns Promise resolving to an array of ChoiceSetOption
   */
  @track('Entities.GetChoiceSet')
  async getChoiceSet(id: string): Promise<ChoiceSetOption[]> {
    const response = await this.getRecordsById(id);
    const items = (response as any).items || (Array.isArray(response) ? response : []);
    
    // Map raw items to typed ChoiceSetOption
    return items.map((item: any) => ({
      id: item.id || item.Id,
      displayName: item.displayName || item.DisplayName || item.name || item.Name,
      name: item.name || item.Name,
      numberId: item.NumberId ?? item.numberId,
      value: item.value || item.Value
    }));
  }

3. Implement resolveDisplayValue Helper

File: src/services/data-fabric/entities.ts

Add a helper that takes an entity record and a field name, inspects the metadata to find the choice set, fetches it, and resolves the value.

  /**
   * Resolves the display value for a Choice Set field on a record
   * 
   * @param record - The entity record containing the value
   * @param fieldName - The name of the field to resolve (e.g., 'Status')
   * @param entityMetadata - The entity schema (required to find the ChoiceSet ID)
   */
  async resolveDisplayValue(record: EntityRecord, fieldName: string, entityMetadata: RawEntityGetResponse): Promise<string> {
    const value = record[fieldName];
    if (value === undefined || value === null) return '';

    // Find the field definition
    const field = entityMetadata.fields.find(f => f.name === fieldName);
    if (!field) return String(value);

    // Get Choice Set ID
    const choiceSetId = field.choiceSetId || field.referenceChoiceSet?.id;
    if (!choiceSetId) return String(value);

    // Fetch Options
    // optimization: cache this call
    const options = await this.getChoiceSet(choiceSetId);

    // Try to match by String ID (GUID) or Number ID
    const match = options.find(opt => 
      String(opt.id) === String(value) || 
      (opt.numberId !== undefined && opt.numberId === Number(value))
    );

    return match ? match.displayName : String(value);
  }

4. Expose Methods on Entity Model

File: src/models/data-fabric/entities.models.ts

Update createEntityMethods to expose resolveDisplayValue directly on the entity object for developer convenience.

// In createEntityMethods function:

    async resolveDisplayValue(record: EntityRecord, fieldName: string): Promise<string> {
      return service.resolveDisplayValue(record, fieldName, entityData);
    }

@Sarath1018 Sarath1018 force-pushed the sarath/getChoicesetValue branch from 927503d to 94ce698 Compare January 9, 2026 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants