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.
A Data Context in MemberJunction represents a collection of data items that can include:
npm install @memberjunction/data-context
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}`);
});
}
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);
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);
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);
}
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);
}
// 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
);
// 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
}
// 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}`);
}
});
// 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}`);
}
ID: string - The unique identifier of the data contextDataContextEntity: DataContextEntity - The metadata entity for the data contextItems: DataContextItem[] - Array of data context itemsasync LoadMetadata(DataContextID: string, contextUser?: UserInfo, provider?: IMetadataProvider): Promise<boolean>
async LoadData(dataSource: any, forceRefresh?: boolean, loadRelatedDataOnSingleRecords?: boolean, maxRecordsPerRelationship?: number, contextUser?: UserInfo): Promise<boolean>
async Load(DataContextID: string, dataSource: any, forceRefresh?: boolean, loadRelatedDataOnSingleRecords?: boolean, maxRecordsPerRelationship?: number, contextUser?: UserInfo): Promise<boolean>
async SaveItems(contextUser?: UserInfo, persistItemData?: boolean): Promise<boolean>
AddDataContextItem(): DataContextItem
ValidateDataExists(ignoreFailedLoadItems?: boolean): boolean
ConvertToSimpleObject(itemPrefix?: string, includeFailedLoadItems?: boolean): any
CreateSimpleObjectTypeDefinition(itemPrefix?: string, includeFailedLoadItems?: boolean): string
LoadDataFromObject(data: any[][]): boolean
static async Clone(context: DataContext, includeData?: boolean, contextUser?: UserInfo): Promise<DataContext>
static async FromRawData(rawData: any): Promise<DataContext>
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 descriptionasync LoadData(dataSource: any, forceRefresh?: boolean, loadRelatedDataOnSingleRecords?: boolean, maxRecordsPerRelationship?: number, contextUser?: UserInfo): Promise<boolean>
LoadDataFromObject(data: any[]): boolean
ValidateDataExists(ignoreFailedLoad?: boolean): boolean
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
class DataContextFieldInfo {
Name: string;
Type: string;
Description?: string;
}
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.
@memberjunction/global: Core global utilities and class factory@memberjunction/core-entities: Entity definitions for MemberJunction@memberjunction/core: Core MemberJunction functionalityLoadMetadata() before LoadData() or simply use Load() which does bothDataLoaded and DataLoadingError properties on itemsmaxRecordsPerRelationship to limit related data loadingValidateDataExists() before processing dataISC