@memberjunction/data-context v2.48.0
@memberjunction/data-context
The @memberjunction/data-context
library provides a comprehensive framework for managing data contexts in MemberJunction applications. It enables developers to define, load, and manipulate collections of related data items across different tiers of an application.
Overview
A Data Context in MemberJunction represents a collection of data items that can include:
- Views: Filtered and customized views of entity data
- Queries: Pre-defined SQL queries registered in the system
- Full Entities: Complete data sets from an entity
- Single Records: Individual entity records with optional related data
- SQL Statements: Direct SQL queries (server-side only)
Installation
npm install @memberjunction/data-context
Key Features
- Type-safe data context management: Full TypeScript support with proper typing
- Flexible data loading: Support for various data sources including views, queries, entities, and SQL
- Metadata-driven: Automatic loading of metadata from the MemberJunction system
- Transaction support: Save multiple data context items in a single transaction
- Cross-tier compatibility: Works across server and client tiers with appropriate implementations
- Data persistence: Optional saving of loaded data to the database
Usage
Basic Example
import { DataContext, DataContextItem } from '@memberjunction/data-context';
import { Metadata } from '@memberjunction/core';
// Create a new data context
const context = new DataContext();
// Load metadata and data for an existing data context
const dataContextID = 'your-data-context-id';
const loaded = await context.Load(
dataContextID,
dataSource, // Required for SQL type items (server-side only)
false, // forceRefresh
true, // loadRelatedDataOnSingleRecords
10, // maxRecordsPerRelationship
userInfo // contextUser
);
if (loaded) {
// Access the loaded data
context.Items.forEach(item => {
console.log(`Item: ${item.Description}`);
console.log(`Data rows: ${item.Data?.length || 0}`);
});
}
Creating Data Context Items
From a View
import { UserViewEntityExtended } from '@memberjunction/core-entities';
// Assuming you have a view entity loaded
const viewEntity: UserViewEntityExtended = await md.GetEntityObject<UserViewEntityExtended>('User Views');
await viewEntity.Load(viewID);
const viewItem = DataContextItem.FromViewEntity(viewEntity);
context.Items.push(viewItem);
From a Single Record
import { BaseEntity } from '@memberjunction/core';
// Assuming you have an entity record loaded
const record: BaseEntity = await md.GetEntityObject('Customers');
await record.Load(recordID);
const recordItem = DataContextItem.FromSingleRecord(record);
context.Items.push(recordItem);
From a Query
import { QueryInfo } from '@memberjunction/core';
// Get query info from metadata
const queryInfo = md.Queries.find(q => q.Name === 'My Query');
if (queryInfo) {
const queryItem = DataContextItem.FromQuery(queryInfo);
context.Items.push(queryItem);
}
From a Full Entity
import { EntityInfo } from '@memberjunction/core';
// Get entity info from metadata
const entityInfo = md.Entities.find(e => e.Name === 'Products');
if (entityInfo) {
const entityItem = DataContextItem.FromFullEntity(entityInfo);
context.Items.push(entityItem);
}
Loading Data for Items
// Load data for all items in the context
const dataLoaded = await context.LoadData(
dataSource, // Required for SQL type items
false, // forceRefresh
true, // loadRelatedDataOnSingleRecords
10 // maxRecordsPerRelationship
);
// Or load data for a specific item
const itemLoaded = await context.Items[0].LoadData(
dataSource,
false,
true,
10
);
Saving Data Context Items
// Save all items in the context to the database
const saved = await context.SaveItems(
userInfo, // contextUser
true // persistItemData - saves actual data, not just metadata
);
if (saved) {
console.log('Data context items saved successfully');
// Each item now has a DataContextItemID populated
}
Working with Data
// Validate that all items have data loaded
if (context.ValidateDataExists()) {
// Convert to a simple object for easier manipulation
const simpleData = context.ConvertToSimpleObject('item_', false);
// Result: { item_0: [...], item_1: [...], ... }
// Get type definition for the data structure
const typeDef = context.CreateSimpleObjectTypeDefinition('item_');
console.log(typeDef);
// Output: {item_0: []; // View: Customer List, From Entity: Customers\n...}
}
// Access individual item data
context.Items.forEach(item => {
if (item.DataLoaded && item.Data) {
console.log(`${item.Description}: ${item.Data.length} rows`);
// Process the data
item.Data.forEach(row => {
// Work with row data
});
} else if (item.DataLoadingError) {
console.error(`Error loading ${item.Description}: ${item.DataLoadingError}`);
}
});
Cloning Data Contexts
// Clone an existing data context
const clonedContext = await DataContext.Clone(
originalContext,
true, // includeData - copies the data along with metadata
userInfo // contextUser
);
if (clonedContext) {
console.log(`Cloned context ID: ${clonedContext.ID}`);
}
API Reference
DataContext Class
Properties
ID: string
- The unique identifier of the data contextDataContextEntity: DataContextEntity
- The metadata entity for the data contextItems: DataContextItem[]
- Array of data context items
Methods
async LoadMetadata(DataContextID: string, contextUser?: UserInfo, provider?: IMetadataProvider): Promise<boolean>
- Loads only the metadata for the data context and its items
async LoadData(dataSource: any, forceRefresh?: boolean, loadRelatedDataOnSingleRecords?: boolean, maxRecordsPerRelationship?: number, contextUser?: UserInfo): Promise<boolean>
- Loads data for all items in the context
async Load(DataContextID: string, dataSource: any, forceRefresh?: boolean, loadRelatedDataOnSingleRecords?: boolean, maxRecordsPerRelationship?: number, contextUser?: UserInfo): Promise<boolean>
- Loads both metadata and data in one operation
async SaveItems(contextUser?: UserInfo, persistItemData?: boolean): Promise<boolean>
- Saves all data context items to the database
AddDataContextItem(): DataContextItem
- Creates and adds a new item to the context
ValidateDataExists(ignoreFailedLoadItems?: boolean): boolean
- Checks if all items have data loaded
ConvertToSimpleObject(itemPrefix?: string, includeFailedLoadItems?: boolean): any
- Converts the context to a simple object structure
CreateSimpleObjectTypeDefinition(itemPrefix?: string, includeFailedLoadItems?: boolean): string
- Generates TypeScript type definition for the data structure
LoadDataFromObject(data: any[][]): boolean
- Loads pre-fetched data into the context
static async Clone(context: DataContext, includeData?: boolean, contextUser?: UserInfo): Promise<DataContext>
- Creates a deep copy of a data context
static async FromRawData(rawData: any): Promise<DataContext>
- Creates a context from raw data object
DataContextItem Class
Properties
Type: 'view' | 'query' | 'full_entity' | 'sql' | 'single_record'
- The type of data itemRecordID: string
- Primary key for single_record typesEntityID?: string
- Entity identifierViewID?: string
- View identifierQueryID?: string
- Query identifierRecordName: string
- Name of the view, query, or entitySQL?: string
- SQL statement for 'sql' typeEntityName?: string
- Name of the entityFields: DataContextFieldInfo[]
- Field metadataData: any[]
- The loaded dataDataLoaded: boolean
- Indicates if data has been loadedDataLoadingError?: string
- Error message if loading failedDescription: string
- Auto-generated descriptionAdditionalDescription?: string
- Optional custom description
Methods
async LoadData(dataSource: any, forceRefresh?: boolean, loadRelatedDataOnSingleRecords?: boolean, maxRecordsPerRelationship?: number, contextUser?: UserInfo): Promise<boolean>
- Loads data for this specific item
LoadDataFromObject(data: any[]): boolean
- Loads pre-fetched data into the item
ValidateDataExists(ignoreFailedLoad?: boolean): boolean
- Validates that data has been loaded
static FromViewEntity(viewEntity: UserViewEntityExtended): DataContextItem
static FromSingleRecord(singleRecord: BaseEntity): DataContextItem
static FromQuery(query: QueryInfo): DataContextItem
static FromFullEntity(entity: EntityInfo): DataContextItem
static FromRawItem(rawItem: any): DataContextItem
DataContextFieldInfo Class
class DataContextFieldInfo {
Name: string;
Type: string;
Description?: string;
}
Server-Side Considerations
For SQL type data context items, you'll need to use the server-side implementation from @memberjunction/data-context-server
which properly handles SQL execution with appropriate security and data source management.
Dependencies
@memberjunction/global
: Core global utilities and class factory@memberjunction/core-entities
: Entity definitions for MemberJunction@memberjunction/core
: Core MemberJunction functionality
Best Practices
- Always load metadata before data: Use
LoadMetadata()
beforeLoadData()
or simply useLoad()
which does both - Handle loading errors: Check
DataLoaded
andDataLoadingError
properties on items - Use appropriate data sources: SQL type items require server-side data sources
- Consider performance: Use
maxRecordsPerRelationship
to limit related data loading - Validate before use: Call
ValidateDataExists()
before processing data - Use transactions: When saving multiple items, they're automatically wrapped in a transaction
License
ISC
8 months ago
4 months ago
8 months ago
6 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
6 months ago
6 months ago
4 months ago
8 months ago
8 months ago
8 months ago
6 months ago
9 months ago
9 months ago
9 months ago
9 months ago
8 months ago
5 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
9 months ago
5 months ago
9 months ago
8 months ago
9 months ago
9 months ago
8 months ago
7 months ago
5 months ago
9 months ago
9 months ago
5 months ago
5 months ago
8 months ago
8 months ago
7 months ago
9 months ago
9 months ago
9 months ago
5 months ago
5 months ago
8 months ago
8 months ago
5 months ago
5 months ago
9 months ago
5 months ago
8 months ago
4 months ago
10 months ago
6 months ago
11 months ago
10 months ago
11 months ago
6 months ago
11 months ago
4 months ago
8 months ago
8 months ago
12 months ago
6 months ago
6 months ago
8 months ago
12 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago