Issue with realm and related collection

I have a person that has a related collection of “tags”. Each person can have multiple tags.

I’ve found the relationship CRUD section of the docs, but it skips the part that says how to actually write the code to connect two documents.

Here is a simplified version of my People schema.

export class People extends Realm.Object<People> {
  _id!: string;
  name: string;
  email?: string;
  tags?: Realm.List<Tags>;
  org_id!: string;

  static schema: Realm.ObjectSchema = {
    primaryKey: '_id',
    name: 'people',
    properties: {
      _id: {
        type: 'string',
        default: () => new Realm.BSON.ObjectID().toHexString(),
      },
      name: 'string',
      email: 'string?',
      createdAt: { type: 'date', default: () => new Date() },
      tags: 'tags[]',
      org_id: 'string',
    },
  };
}

And here is my Tags model

export class Tags extends Realm.Object<Tags> {
  _id!: string;
  name: string;
  org_id: string;

  static schema: Realm.ObjectSchema = {
    primaryKey: '_id',
    name: 'tags',
    properties: {
      _id: {
        type: 'string',
      },
      name: 'string',
      is_active: { type: 'bool', default: true },
      org_id: 'string',
    },
  };
}

Here is my code for adding a new person with one tag.

const person = realm.write(() => {
        return new People(realm, {
          email,
          name,
          org_id: org._id,
          tags: [{ name: '2021', _id: `${org._id}-2021` }],
        });
      });

I get the error "Exception in HostFunction: Attempting to create an object of type ‘tags’ with an existing primary key value ‘‘id123-2021’’

This is happening because realm is trying to create this same tag that already exists in the DB. Instead of creating it I need to connect the two. How do I do that?

Cross posted here as well

Hey @Joshua_Bechard - Welcome to the community.

Wondering if the examples on the following forum post help : Mobile Bytes #6: What are Realm Relationships?

Just to clarify as well, could you advise which SDK version you are using?

Regards,
Jason

The linked post has Java examples, but no JavaScript examples. I think without a concrete JavaScript example it will be difficult to understand how these documents are linked together. I did find a workaround and posted my answer on the stackoverflow article.

Here is that answer.
Realm objects can be mutated inside the realm.write function directly. So in this case the way I was able to connect tags with people is like this.

    const person = realm.write(() => {
        const realmPerson = new People(realm, {
          email,
          name,
          org_id: org._id,
        });
        
        person.tags = [{ _id: `${org._id}-2021` }];
        return realmPerson;
    });

And since the _id is the primary key field Realm just knows these objects are linked and now if I later call person.tags, I actually get the whole array of tags with all the object properties, not just the _id field.

2 Likes

Hello @Joshua_Bechard ,

Thank you for being part of our community, and helping fellow members with your suggestions :handshake:

I will try to add JavaScript examples to the article as well.

For your above question, the team recommends avoiding constructors when you have a list of Realm objects.

realm.write(() => {
  const tmpId = `org-${_id}-2021`;
  let tag = realm.objectByPrimaryKey<Tag>(Tag, tmpId);
  if (!tag) {
    tag = new Tag(realm, { name: '2021', _id: tmpId });
  }  
  return people = new People(realm, {
    email,
    name,
    org_id: org._id,
    tags: [tag]
  });
});

The above code will check if the tag has already been created by looking it up by primary key. If it hasn’t, it will create it.

I hope the provided information is helpful.

Cheers, :performing_arts:
Henna

3 Likes

Henna,

Thank you!

This is great. It would be really helpful for these kinds of examples to exist in the docs as well. It isn’t clear from the docs that the function realm.objectByPrimaryKey even exists. At least I couldn’t find it anywhere in the React Native docs.

I did some digging, did you mean objectForPrimaryKey?
https://www.mongodb.com/docs/realm-sdks/js/latest/Realm.html#objectForPrimaryKey

Thanks again

2 Likes

Great Catch @Joshua_Bechard, this is indeed objectForPrimaryKey.

Cheers,
henna

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.