question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot assign object to lazy relation (expects promise)

See original GitHub issue

Issue type:

(I’m really not sure if this is an issue with the library, documentation, or just my understanding)

[ x ] question [ x ] bug report [ ] feature request [ x ] documentation issue

Database system/driver:

[ ] cordova [ ] mongodb [ ] mssql [ ] mysql / mariadb [ ] oracle [ x ] postgres [ ] sqlite [ ] sqljs [ ] react-native

TypeORM version:

[ x ] latest [ ] @next [ ] 0.x.x (or put your version here)

Steps to reproduce or a small repository showing the problem:

Entities

@Entity()
export class Role {

  @ManyToOne(type => Store, store => store.roles)
  store: Promise<Store>;
}

@Entity()
export class Store {

  @OneToMany(type => Role, role => role.store)
  roles: Promise<Role[]>;
}

This code fails because the types expect store to be a promise

  const r = roleRepository.create();
  r.store = await storeRepository.findOne();
  await roleRepository.save(r);

This code fails because the implementation expects an object (not a promise)

  const r = roleRepository.create();
  r.store = storeRepository.findOne();
  await roleRepository.save(r);

This code works, but is clearly ugly / hacky

  const r = roleRepository.create();
  r.store = <any>(await storeRepository.findOne());
  await roleRepository.save(r);

What is the correct way to achieve this?

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:9
  • Comments:11 (3 by maintainers)

github_iconTop GitHub Comments

9reactions
itslennycommented, Jun 5, 2018

Another way to achieve this is to change the entity to…

@Entity()
export class Role {

  @ManyToOne(type => Store, store => store.roles)
  store: Promise<Store> | Store;
}

However, this isn’t explained in the documentation anywhere. The section about this says to just use store: Promise<Store> which would never work for assigning values as far as I can tell.

This solution seems dirty too. It allows me to bypass the compile time type check and do things that will break at run time due to invalid type (i.e. I could still pass a promise to role.store or try to read it as an object when querying).

Update:

After trying this I realized that with the entity typed like this If I do role.store it is undefined.

Unless I’m missing something this is a fatal flaw with the design of lazy relations which makes it entirely unusable.

4reactions
davidfrtalacommented, Mar 15, 2020

Hello I’m experiencing this issue. My code

// "type" here is async/awaited, so it's no longer a promise
const type = await typeRepo.findOneOrFail(typeId)

const entity = notificationRepo.create({
  name,
  eventId,
  type: Promise.resolve(type),
})

return notificationRepo.save(entity)

If I print an entity I get this, which is wrong and fails upon save

Notification {
  name: 'FooBar',
  eventId: 'ABC1',
  __type__: NotificationType {} 
}

Only workaround is manualy set property, like this

const entity = notificationRepo.create({
  ...
})

entity.type = Promise.resolve(type),

return notificationRepo.save(entity)

entity printed

Notification {
  name: 'FooBar',
  eventId: 'ABC1',
  __promise_type__:
   Promise {
     NotificationType {
     id: 1,
     prefix: 'ABC' 
    } 
  }
}

It’s working, but it’s it’s too ugly…

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why i cannot assign new key value in nested array object that ...
Strange how you mutate the state, maybe try the following: addBase64Function(values = []) { //always return a promise, even if values is ...
Read more >
Promise - JavaScript - MDN Web Docs
The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
Read more >
R Language Definition
Promise objects are part of R's lazy evaluation mechanism. They contain three slots: a value, an expression, and an environment. When a function...
Read more >
Router tutorial: tour of heroes - Angular
In this tutorial, you build upon a basic router configuration to explore features such as child routes, route parameters, lazy load NgModules, guard...
Read more >
Don't let Entity Framework call the shots - Fear of Oblivion
If there is one thing you take away from this post, it is that EF is there to map data from the database...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found