Search code examples
typescripttypeormeager-loadingnode.js-typeorm

Meaning of using 'eager:true' option in TypeORM


I've been using TypeORM and I've got some problem when pushing data as follows:

  • User.ts (Entity)
    @OneToMany(type => Post, post => post.user)
    posts: Post[]
    
  • Post.ts (Entity)
    @ManyToOne(type => User, user => user.posts)
    user: User
    

And when I tried to do Create Post like this:

  • createPost.ts
    
    // Some Codes...
    
    // Save Post
    const post =  Post.create({
      title: title,
      content: content
    })
    await post.save()
    
    // Update User
    const user = await User.findOne({ uid: ctx.uid })
    user.posts.push(post)  // ****************** PROBLEM ******************
    await user.save()
    

As I marked PROBLEM above, when I requested this, I got Cannot call method 'push of undefined error.

But luckily I could've solved this by just adding following option at User.ts file:

@OneToMany(type => Post, post => post.user, {
  // -------------- added --------------
  eager: true
  // -----------------------------------
})
posts: Post[]

And I'd like to know why this works... I've read the typeorm document about Eager, and it says

Eager relations only work when you use find* methods. If you use QueryBuilder eager relations are disabled and have to use leftJoinAndSelect to load the relation. Eager relations can only be used on one side of the relationship, using eager: true on both sides of relationship is disallowed.

But I'm not sure what the last sentence means.

eager: true on both sides of relationship is disallowed.

So, I've disallowed the relation between User and Post, and the file now can understand user.posts is defined?

Could somebody please help me with this...?


Solution

  • As explained in the Eager Loading Documentaion You can set the eager: true on one side of the relationship only. That means you have define the relationship like below.

    in User.ts

    @OneToMany(type => Post, post => post.user, { eager: true })
    posts: Post[]
    

    and in Post.ts

    @ManyToOne(type => User, user => user.posts)
    user: User
    

    And in here if you use await User.findOne({ uid: ctx.uid }) in functions that will load Post relationship automatically. This does not mean you cannot use the vice versa relationship. From Post to User relationship you can load the relationship still using leftJoinAndSelect.