Skip to content

Commit

Permalink
fix(angular-ngrx-component-store-odata-table): kept metadata inside t…
Browse files Browse the repository at this point in the history
…he service class
  • Loading branch information
JBBianchi committed Jan 10, 2024
1 parent a758e63 commit 3d29439
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export class GraphQLMetadataService {
protected readonly http = inject(HttpClient);
/** The logger instance */
protected readonly logger: ILogger = this.namedLoggingServiceFactory.create('GraphQLMetadataService');
/** The GraphQL schema */
protected schema: GraphQLSchema | null;

/**
* Gathers the schema from the provided service
Expand All @@ -33,7 +35,8 @@ export class GraphQLMetadataService {
});
return logHttpRequest(this.logger, this.errorObserver, this.http.get<string>(schemaUrl), httpRequestInfo).pipe(
map((schemaDefinition: string) => {
return buildSchema(new Source(schemaDefinition));
this.schema = buildSchema(new Source(schemaDefinition));
return this.schema;
}),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -791,9 +791,7 @@ describe('OData Metadata Service', () => {
service
.getMetadata(testEndpoint)
.pipe(
switchMap((metadata) =>
service.getEntityTypeByQualifiedName(metadata, 'BlazorWasm7Mssql.Models.Northwind.NorthwindProduct'),
),
switchMap((_) => service.getEntityTypeByQualifiedName('BlazorWasm7Mssql.Models.Northwind.NorthwindProduct')),
)
.subscribe({
next: (entityType: EntityType) => {
Expand All @@ -818,7 +816,7 @@ describe('OData Metadata Service', () => {
.map(([key]) => key);
service
.getMetadata(testEndpoint)
.pipe(switchMap((metadata) => service.getColumnDefinitions(metadata, 'NorthwindProducts')))
.pipe(switchMap((_) => service.getColumnDefinitions('NorthwindProducts')))
.subscribe({
next: (definitions: ColumnDefinition[]) => {
expect(definitions).not.toBeNull();
Expand All @@ -835,7 +833,7 @@ describe('OData Metadata Service', () => {
it('should throw empty for an unknown entity', (done) => {
service
.getMetadata(testEndpoint)
.pipe(switchMap((metadata) => service.getColumnDefinitions(metadata, 'foobar')))
.pipe(switchMap((_) => service.getColumnDefinitions('foobar')))
.subscribe({
next: (definitions: ColumnDefinition[]) => {
expect(definitions).toBeNull();
Expand All @@ -860,11 +858,8 @@ describe('OData Metadata Service', () => {
service
.getMetadata(testEndpoint)
.pipe(
switchMap((metadata) =>
service.getColumnDefinitionsForQualifiedName(
metadata,
'BlazorWasm7Mssql.Models.Northwind.NorthwindProduct',
),
switchMap((_) =>
service.getColumnDefinitionsForQualifiedName('BlazorWasm7Mssql.Models.Northwind.NorthwindProduct'),
),
)
.subscribe({
Expand All @@ -883,7 +878,7 @@ describe('OData Metadata Service', () => {
it('should throw for an unknown entity', (done) => {
service
.getMetadata(testEndpoint)
.pipe(switchMap((metadata) => service.getColumnDefinitionsForQualifiedName(metadata, 'foobar')))
.pipe(switchMap((_) => service.getColumnDefinitionsForQualifiedName('foobar')))
.subscribe({
next: (definitions: ColumnDefinition[]) => {
expect(definitions).toBeNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ILogger } from '@neuroglia/logging';
import { NamedLoggingServiceFactory } from '@neuroglia/angular-logging';
import { HttpErrorObserverService, HttpRequestInfo, logHttpRequest } from '@neuroglia/angular-rest-core';
import { EMPTY, Observable, of } from 'rxjs';
import { expand, map, reduce, switchMap } from 'rxjs/operators';
import { expand, map, reduce, switchMap, tap } from 'rxjs/operators';
import { ODataPrimitiveTypeEnum } from './models';
import * as ODataMetadataSchema from './models/odata-metadata';
import { ColumnDefinition } from '@neuroglia/angular-ngrx-component-store-queryable-table';
Expand All @@ -22,6 +22,8 @@ export class ODataMetadataService {
protected readonly http = inject(HttpClient);
/** The logger instance */
protected readonly logger: ILogger = this.namedLoggingServiceFactory.create('ODataMetadataService');
/** The metadata */
protected metadata: ODataMetadataSchema.Metadata | null;

/**
* Gathers the metadata from the provided service
Expand All @@ -41,6 +43,10 @@ export class ODataMetadataService {
this.errorObserver,
this.http.get<ODataMetadataSchema.Metadata>(url),
httpRequestInfo,
).pipe(
tap((metadata) => {
this.metadata = metadata;
}),
);
}

Expand All @@ -50,16 +56,15 @@ export class ODataMetadataService {
* @param qualifiedName
* @returns
*/
getEntityTypeByQualifiedName(
metadata: ODataMetadataSchema.Metadata,
qualifiedName: string,
): Observable<ODataMetadataSchema.EntityType> {
return of(this.getElementByQualifiedName(metadata, qualifiedName) as ODataMetadataSchema.EntityType);
getEntityTypeByQualifiedName(qualifiedName: string): Observable<ODataMetadataSchema.EntityType> {
if (!this.metadata) {
throw new Error(`Metadata must be initialized with 'getMetadata'`);
}
return of(this.getElementByQualifiedName(qualifiedName) as ODataMetadataSchema.EntityType);
}

/**
* Gets the entity type description for the provided entity name
* @param metadata
* @param target
* @returns
Expand All @@ -72,18 +77,20 @@ export class ODataMetadataService {

/**
* Gets the column definitions for the provided entity name
* @param metadata
* @param target
* @returns
*/
getColumnDefinitions(metadata: ODataMetadataSchema.Metadata, target: string): Observable<ColumnDefinition[]> {
return this.getEntityQualifiedName(metadata, target).pipe(
switchMap((qualifiedName) => this.getColumnDefinitionInfo(metadata, qualifiedName)),
getColumnDefinitions(target: string): Observable<ColumnDefinition[]> {
if (!this.metadata) {
throw new Error(`Metadata must be initialized with 'getMetadata'`);
}
return this.getEntityQualifiedName(target).pipe(
switchMap((qualifiedName) => this.getColumnDefinitionInfo(qualifiedName)),
expand((info) => {
if (!info) {
return EMPTY;
}
return this.getColumnDefinitionInfo(metadata, info.baseType);
return this.getColumnDefinitionInfo(info.baseType);
}),
reduce((acc: ColumnDefinition[], info: ColumnDefinitionInfo) => {
return [...info.columnDefinitions, ...acc];
Expand All @@ -93,20 +100,19 @@ export class ODataMetadataService {

/**
* Gets the column definitions for the provided full qualified entity name
* @param metadata
* @param target
* @returns
*/
getColumnDefinitionsForQualifiedName(
metadata: ODataMetadataSchema.Metadata,
qualifiedName: string,
): Observable<ColumnDefinition[]> {
return this.getColumnDefinitionInfo(metadata, qualifiedName).pipe(
getColumnDefinitionsForQualifiedName(qualifiedName: string): Observable<ColumnDefinition[]> {
if (!this.metadata) {
throw new Error(`Metadata must be initialized with 'getMetadata'`);
}
return this.getColumnDefinitionInfo(qualifiedName).pipe(
expand((info) => {
if (!info) {
return EMPTY;
}
return this.getColumnDefinitionInfo(metadata, info.baseType);
return this.getColumnDefinitionInfo(info.baseType);
}),
reduce((acc: ColumnDefinition[], info: ColumnDefinitionInfo) => {
return [...info.columnDefinitions, ...acc];
Expand All @@ -116,16 +122,18 @@ export class ODataMetadataService {

/**
* Gets the fully qualified name of the provided entity
* @param metadata
* @param target
* @returns
*/
protected getEntityQualifiedName(metadata: ODataMetadataSchema.Metadata, target: string): Observable<string> {
if (!metadata.$EntityContainer) {
protected getEntityQualifiedName(target: string): Observable<string> {
if (!this.metadata) {
throw new Error(`Metadata must be initialized with 'getMetadata'`);
}
if (!this.metadata.$EntityContainer) {
this.logger.error(`The property $EntityContainer is missing on the metadata.`);
throw new Error(`The property $EntityContainer is missing on the metadata.`);
}
const entityType = get(get(metadata, metadata.$EntityContainer), target)?.$Type as string;
const entityType = get(get(this.metadata, this.metadata.$EntityContainer), target)?.$Type as string;
if (!entityType) {
this.logger.error(`Enable to find a metadata container for '${target}'.`);
throw new Error(`Enable to find a metadata container for '${target}'.`);
Expand All @@ -139,12 +147,12 @@ export class ODataMetadataService {
* @param target
* @returns
*/
protected getColumnDefinitionInfo(
metadata: ODataMetadataSchema.Metadata,
qualifiedName?: string,
): Observable<ColumnDefinitionInfo> {
protected getColumnDefinitionInfo(qualifiedName?: string): Observable<ColumnDefinitionInfo> {
if (!this.metadata) {
throw new Error(`Metadata must be initialized with 'getMetadata'`);
}
if (!qualifiedName) return EMPTY;
return this.getEntityTypeByQualifiedName(metadata, qualifiedName).pipe(
return this.getEntityTypeByQualifiedName(qualifiedName).pipe(
map(
(entityType) =>
({
Expand Down Expand Up @@ -192,7 +200,7 @@ export class ODataMetadataService {
columnDefinition.isFilterable = !isCollection && !isNavigationProperty;
}
} else if (!isNavigationProperty) {
const underlyingEntity = this.getElementByQualifiedName(metadata, type);
const underlyingEntity = this.getElementByQualifiedName(type);
if (underlyingEntity.$Kind === 'EnumType') {
columnDefinition.isVisible = !isCollection && !isNavigationProperty;
columnDefinition.isSortable = !isCollection && !isNavigationProperty;
Expand All @@ -217,13 +225,15 @@ export class ODataMetadataService {
* @returns
*/
protected getElementByQualifiedName(
metadata: ODataMetadataSchema.Metadata,
qualifiedName: string,
): ODataMetadataSchema.EntityType | ODataMetadataSchema.EnumType {
if (!this.metadata) {
throw new Error(`Metadata must be initialized with 'getMetadata'`);
}
const pathParts = qualifiedName.split('.');
const type = pathParts.splice(-1)[0];
const namespace = pathParts.join('.');
return metadata[namespace][type];
return this.metadata[namespace][type];
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ export class ODataTableStore<
)
: this.odataMetadataService.getMetadata(initialState.serviceUrl!).pipe(
takeUntil(this.destroy$),
switchMap((metadata: ODataMetadataSchema.Metadata) =>
switchMap((_: ODataMetadataSchema.Metadata) =>
!initialState.targetType
? this.odataMetadataService.getColumnDefinitions(metadata, initialState.target!)
: this.odataMetadataService.getColumnDefinitionsForQualifiedName(metadata, initialState.targetType),
? this.odataMetadataService.getColumnDefinitions(initialState.target!)
: this.odataMetadataService.getColumnDefinitionsForQualifiedName(initialState.targetType),
),
map((definitions: ColumnDefinition[]) => {
const token = this.keycloak?.getKeycloakInstance()?.tokenParsed;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

export * from './lib/angular-ngrx-component-store-odata-table.module';
export * from './lib/odata-metadata.service';
export * from './lib/odata-metadata-service-url-token';

Check failure on line 7 in projects/neuroglia/angular-ngrx-component-store-odata-table/src/public-api.ts

View workflow job for this annotation

GitHub Actions / pipeline (angular-ngrx-component-store-odata-table) / build / build

Cannot find module './lib/odata-metadata-service-url-token' or its corresponding type declarations.
export * from './lib/odata-table.store';

export * from './lib/models';

0 comments on commit 3d29439

Please sign in to comment.