Vincit/Objection.js returns "cannot read property '$relation' of undefined" when using .withGraphFetched()

Viewed 611

I am currently setting up Objection.js with NestJS and am having trouble using any sort of graph fetch or save methods. Relevant models:

resource-group.model.ts

import { BaseModel } from './base.model';
import { Model } from 'objection';
import { ResourceGroupTypeModel } from './resource-group-type.model';
import { CollectionModel } from './collection.model';
import { AttributeModel } from './attribute.model';
import { ResourceModel } from './resource.model';

export class ResourceGroupModel extends BaseModel {
  static tableName = 'resource_group';

  typeId: number;
  title: string;
  groupId: string;
  collectionId?: number;
  defaultResourceId?: number;
  isDeleted: boolean;

  static relationMappings = {
    attributes: {
      modelClass: AttributeModel,
      relation: Model.ManyToManyRelation,
      join: {
        from: 'resource_group.id',
        through: {
          from: 'resourcegroup_attribute.resource_group_id',
          to: 'resourcegroup_attribute.attribute_id'
        },
        to: 'attribute.id',
      },
    },
  }
}

attribute.model.ts

import { BaseModel } from './base.model';
import { Model } from 'objection';

export class AttributeModel extends BaseModel {
  static tableName = 'attribute'

  name: string;
  value: string;
  isSystem: boolean;

  static relationMappings = {
    resourceGroups: {
      modelClass: `${__dirname}/resource-group.model.js`,
      relation: Model.ManyToManyRelation,
      join: {
        from: 'attribute.id',
        through: {
          from: 'resourcegroup_attribute.attribute_id',
          to: 'resourcegroup_attribute.resource_group_id',
        },
        to: 'resource_group.id',
      },
    },
  }
}

resource-group.service.ts

import { Injectable, Inject } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { EntityService } from '../abstract';
import { ResourceGroup } from '../entities';
import { Repository } from 'typeorm';
import { ModelClass } from 'objection';
import { ResourceGroupModel } from '../db/models/resource-group.model';

@Injectable()
export class ResourceGroupService extends EntityService<ResourceGroup> {
  constructor(
    @InjectRepository(ResourceGroup)
    protected readonly repository: Repository<ResourceGroup>,
    @Inject(ResourceGroupModel)
    protected readonly model: ModelClass<ResourceGroupModel>,
  ) {
    super(repository);
  }

  test() {
    return this.model
      .query()
      // .findById(25);                 // this line works fine

      .withGraphFetched(['attributes']) // these two lines do not
      .where({id: 25});
  }
}

Anybody have any ideas of what's going on? I've looked through the source code but it appears to be an issue in my code, maybe in one of my models.

1 Answers

So I was stuck on this for a while, turned out to be something super simple. In resource-group.service.ts we need to make a slight change.

    return this.model
      .query()
      .withGraphFetched(['attributes'])
      .where({id: 25});

needs to become

    return this.model
      .query()
      .withGraphFetched('[attributes]') // square brackets are inside the string itself
      .where({id: 25});

Classic case of code-blindness but couldn't find a single hit on Google for my error message. Hopefully this will help someone who really needs a cup of coffee in the future (:

Related