shet_tayyy
shet_tayyy

Reputation: 5755

How to reuse properties from a schema/class in a different schema?

Consider the following example:

Base.ts

import Realm from 'realm';

export type BaseId = Realm.BSON.ObjectId;

export interface BaseEntity {
    id?: BaseId;
    createdAt: string;
    updatedAt: string;
    syncDetails: SyncDetails;
}

export class BaseEntitySchema {
    _id!: Realm.BSON.ObjectId;

    createdAt!: Date;

    updatedAt!: Date;

    static schema: Realm.ObjectSchema = {
        name: 'BaseEntity',
        properties: {
            _id: 'objectId',
            createdAt: 'date',
            updatedAt: 'date',
        },
        primaryKey: '_id',
    };
}

Now, I want to create a new schema with the properties available in the above snippet.

System.ts

import Realm from 'realm';
import { BaseEntity, BaseEntitySchema } from 'shared/offline-realm/schemas/base';

export interface System extends BaseEntity {
    name: string;
    serialNumber: string;
    locationId: string;
    corporationId: string;
}

export class SystemSchema extends Realm.Object<SystemSchema> {
    name!: string;

    serialNumber!: string;

    locationId!: string;

    corporationId!: string;

    static schema: Realm.ObjectSchema = {
        name: 'System',
        properties: {
            ...BaseEntitySchema.schema.properties,
            name: 'string',
            serialNumber: 'string',
            locationId: 'string',
            corporationId: 'string',
        },
        primaryKey: '_id',
    };
}

I want the BaseEntity values to be available in SystemSchema by maybe inheriting/extending.

    _id!: Realm.BSON.ObjectId;

    createdAt!: Date;

    updatedAt!: Date;

I do not want to explicitly add it. I would rather like to extend it as I have multiple schemas which require the same properties and I would like TypeScript to recognise these values when I try to access it.

I tried doing something like:

export class BaseEntitySchema extends Realm.Object<BaseEntitySchema> {}

and then:

export class SystemSchema extends BaseEntitySchema

But Realm's useQuery would crash saying Unexpected arguments passed to useQuery when doing something like useQuery(SystemSchema)

BaseEntitySchema is a base schema which isn't being used like a collection.

At present, I have to keep repeating the property values in each schema like so:

export class SystemSchema extends Realm.Object<SystemSchema> {
    name!: string;

    serialNumber!: string;

    locationId!: string;

    corporationId!: string;

    _id!: Realm.BSON.ObjectId;

    createdAt!: Date;

    updatedAt!: Date;

    static schema: Realm.ObjectSchema = {
        name: 'System',
        properties: {
            ...BaseEntitySchema.schema.properties,
            name: 'string',
            serialNumber: 'string',
            locationId: 'string',
            corporationId: 'string',
        },
        primaryKey: '_id',
    };
}

Are there any better ways to handle this issue?

Upvotes: 0

Views: 40

Answers (1)

Meet Bhalodi
Meet Bhalodi

Reputation: 76

You want BaseEntity values to inherit. so you can create a separate interface for it and create a modification like below to create extended schema

export interface BaseEntity {
    _id?: BaseId;
    createdAt: Date;
    updatedAt: Date;
}

export const BaseSchema = {
    _id: 'objectId',
    createdAt: 'date',
    updatedAt: 'date',
};

export function extendSchema<T extends BaseEntity>(name: string, properties: Realm.ObjectSchema['properties']) {
    return class extends Realm.Object<T> {
        _id!: Realm.BSON.ObjectId;
        createdAt!: Date;
        updatedAt!: Date;

        static schema: Realm.ObjectSchema = {
            name,
            properties: {
                ...BaseSchema,
                ...properties,
            },
            primaryKey: '_id',
        };
    };
}

Upvotes: 1

Related Questions