# useLearningTask hook The `useLearningTask` hook is a custom React hook that provides functionality for fetching and managing learning task data in the advanced to-do application. It enriches basic task data with user information, media content, and metadata. This hook uses patterns for handling different media types and binary content, showcasing error handling with `Result` types and resource management for blob URLs. It integrates seamlessly with the application's ontology while providing a clean interface for components. [View the `useLearningTask` reference code.](../uselearningtask-tsx/index.md) ## Key functions * Uses React's `useCallback` for memoizing functions to prevent unnecessary re-renders * Leverages SWR's (stale-while-revalidate) caching with custom revalidation options to optimize performance * Implements blob URL management for binary media content * Provides smart media type detection from MIME types * Handles multiple content delivery mechanisms (embedded and linked) * Uses Result types for robust error handling * Efficiently retrieves user data with batch requests through `useAdmin` ## `useLearningTask` structure ### Interface definition ```typescript interface LearningTaskEnriched { osdkLearningTask: osdkLearningTask.OsdkInstance; mediaUrl: string; createdBy: User; assignedTo: User; mediaType: SupportedMediaType; } ``` This interface combines the SDK's learning task instance with user objects, a URL for the media content, and the detected media type to create a comprehensive data structure for components. ### Data fetching The `useLearningTask` hook uses SWR data fetching capabilities with a custom fetcher function that does the following: 1. Queries for the specific learning task using `fetchOneWithErrors` for robust error handling 2. Processes media content based on the task configuration: * If `mediaReference` exists, fetches binary content and creates a blob URL * If `contentUrl` exists, uses it as an external link * Handles cases where no media is available 3. Determines the media type using MIME type detection 4. Fetches user details for the task's creator and assignee through a batch request 5. Combines all data into the `LearningTaskEnriched` structure ```typescript const fetcher = useCallback(async () => { const learningTaskResult = await client(osdkLearningTask).fetchOneWithErrors(task.osdkTask.$primaryKey as string); // Error handling and data processing // ... return learningTaskEnriched; }, [client, task.osdkTask.$primaryKey, getBatchUserDetails]); ``` ### Media type detection The hook includes a helper function for determining media types from MIME types: ```typescript const getMediaTypeFromMimeType = (mimeType: string): SupportedMediaType => { if (/application\/pdf/.test(mimeType)) { return SupportedMediaType.PDF; } else if (/image\/(jpeg|png|gif)/.test(mimeType)) { return SupportedMediaType.IMAGE; } // ...other type detection }; ``` This utility uses regular expressions to match MIME types against common media formats, providing a consistent way to categorize different types of learning content. ### Return value The `useLearningTask` hook returns an object with the following structure: ```typescript { learningTask: LearningTaskEnriched | undefined; // The enriched learning task (undefined if not loaded) isLoading: boolean; // True during initial data loading isValidating: boolean; // True during background revalidation isError: any; // Error object if the request failed metadata: ObjectMetadata | undefined; // Metadata about the learning task object type } ``` ## Implementation ### Media type enumeration The `useLearningTask` hook defines a string literal union type for different types of media: ```typescript export const SupportedMediaType = { PDF: "PDF", IMAGE: "IMAGE", LINK: "LINK", VIDEO: "VIDEO", NONE: "NONE" } as const; export type SupportedMediaType = typeof SupportedMediaType[keyof typeof SupportedMediaType]; ``` ### Result type pattern The hook uses the `Result` type from the OSDK for error handling: ```typescript const learningTaskResult: Result> = await client(osdkLearningTask).fetchOneWithErrors(task.osdkTask.$primaryKey as string); if (learningTaskResult.error) { throw new Error(learningTaskResult.error.message); } const learningTask = learningTaskResult.value; ``` This pattern does the following: 1. Captures both success and error states in a single return value 2. Enables explicit error checking before accessing data 3. Provides structured error information for better error handling 4. Creates a more robust approach than traditional try/catch ### Blob URL management The hook manages blob URLs for media content: ```typescript const response = await learningTask.mediaReference.fetchContents(); const blob: Blob | undefined = await response.blob(); const mediaUrl = blob ? URL.createObjectURL(blob) : ""; ``` This pattern does the following: 1. Fetches binary content as a Response object 2. Converts the response to a blob 3. Creates a temporary URL for the blob to be used in media elements 4. Properly handles edge cases where the blob might be undefined ## External packages The following external packages can be used with the `useLearningTask` hook. ### useSWR **Purpose:** Data fetching, caching, and state management **Benefits:** * Provides an elegant way to fetch and cache learning task data * Handles loading and error states automatically * Offers built-in revalidation strategies * Optimizes performance with configurable revalidation settings * Reduces network requests with intelligent caching ### @osdk/client & @osdk/react **Purpose:** Ontology SDK client for interacting with a backend data service **Benefits:** * Provides type-safe interfaces for data models * Enables structured data queries with Result types for proper error handling * Supports media content retrieval and metadata access * Offers utilities to fetch object type metadata * Exposes hooks like `useOsdkClient` for accessing the client instance ### @advanced-to-do-application/sdk **Purpose:** Application-specific SDK with predefined data types **Benefits:** * Contains the data model specific to learning tasks (`osdkLearningTask`) * Provides typed access to learning task properties and media references * Enables consistent type enforcement across the application * Supports the application's ontology model ### @osdk/foundry.admin **Purpose:** Foundry Admin SDK for user data types **Benefits:** * Provides the `User` type used for the `createdBy` and `assignedTo` fields * Ensures user data is typed consistently with the Foundry Admin API ## Usage example ```tsx import useLearningTask, { SupportedMediaType } from '../dataServices/useLearningTask'; import type { ITask } from '../dataServices/useTasks'; function LearningTaskViewer({ task }: { task: ITask }) { const { learningTask, isLoading, isError, metadata } = useLearningTask(task); if (isLoading) return
Loading learning materials...
; if (isError) return
Error loading content: {isError.message}
; if (!learningTask) return
No learning content available
; // Render different media types appropriately const renderMedia = () => { switch (learningTask.mediaType) { case SupportedMediaType.PDF: return (