Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular 17 & new Vite builder: When Angular app is built, @Entity metadata is lost #303

Open
SpeedoPasanen opened this issue Dec 7, 2023 · 5 comments

Comments

@SpeedoPasanen
Copy link

SpeedoPasanen commented Dec 7, 2023

Everything works while running ng serve but after ng build with either dev or prod conf, Remult can't find entity metadata and all Repository methods fail. Any ideas how to fix this?

I am running Remult in Bun as a separate project, so it's not compiled with the Angular compiler.

Error:

main.ts:5 ERROR Error: Menu2 is not a known entity, did you forget to set @Entity() or did you forget to add the '@' before the call to Entity?
    at getEntitySettings (getEntityRef.js:14:34)
    at createOldEntity (RepositoryImplementation.js:483:14)
    at new RepositoryImplementation (RepositoryImplementation.js:84:18)
    at Remult2.repo (context.js:53:33)
    at Object.find (remult-proxy.js:91:50)
    at new _AppComponent (app.component.ts:17:23)
    at NodeInjectorFactory.AppComponent_Factory [as factory] (app.component.ts:22:3)
    at getNodeInjectable (core.mjs:4261:38)
    at createRootComponent (core.mjs:15294:31)
    at ComponentFactory.create (core.mjs:15161:19)
@noam-honig
Copy link
Collaborator

Hi @SpeedoPasanen

I've tried it and I'm not getting the same error - here's the project I tested with:
https://github.com/remult/remult/tree/master/examples/angular-todo

It's angular 17 with the new vite project - can you check it out - and let me know the difference?

My guess is the "experimentalDecorators" flag missing from the tsconfig used by angular to build

Let me know -you can also reach me directly on our discord
https://discord.com/invite/GXHk7ZfuG5

@SpeedoPasanen
Copy link
Author

@noam-honig thanks for quick reply again. experimentalDecorators wasn't it, was already enabled.

I copied all entities from the Remult app to under the Angular app and imported them from there, and then everything works.

So seems when entities are imported from outside the Angular project structure, metadata is stripped when built with @angular-devkit/build-angular:application but not when served with@angular-devkit/build-angular:dev-server. Maybe some Angular optimization going on?

I want to keep backend and frontend apps separated so I will keep tinkering. If you have any quick bright ideas I welcome them =))

Fyi I have a root tsconfig.json where I define some paths, and is extended by all apps in this repo. Angular imports entities from @api/* :

{
  "compilerOptions": {
    "paths": {
      "@api/*": ["./apps/api/shared/*"],
      "@clientX/*": ["./apps/clientX/src/*"]
    }
  }
}

@SpeedoPasanen
Copy link
Author

SpeedoPasanen commented Dec 7, 2023

I traced it to getEntityRef.js being imported 2 times, so the Symbols for meta keys are not the same on the second time. As a workaround I tried replacing Symbol() with Symbol.for() and seems to work fine, but not sure if it's the best solution:

export const entityMember = Symbol('entityMember');
export const entityInfo = Symbol('entityInfo');
export const entityInfo_key = Symbol('entityInfo_key');

Replace with:

export const entityMember = Symbol.for('entityMember');
export const entityInfo = Symbol.for('entityInfo');
export const entityInfo_key = Symbol.for('entityInfo_key');

Edit: Nope this workaround didn't quite work, new error when trying to call repo.find :D

chunk-VCU4MUB3.js:65 ERROR TypeError: Cannot read properties of undefined (reading 'key')
    at getVal (RepositoryImplementation.js:784:34)
    at rowHelperImplementation.getId (RepositoryImplementation.js:789:12)
    at rowHelperImplementation.<anonymous> (RepositoryImplementation.js:943:20)
    at Generator.next (<anonymous>)

@SpeedoPasanen
Copy link
Author

This workaround worked:
Export remult in my API shared directory, to be imported in Angular app, therefore not importing remult twice as it seems is what happened:

// apps/api/shared/remult.ts
export * from 'remult';

Angular:

import { remult } from '@api/remult';

Nothing that can be on the Remult side of things to avoid doing this comes to my mind, but I'm not that smart so maybe you figure out something better :D

@yoni-rapoport
Copy link
Collaborator

I think it makes sense that Remult should only be loaded once.

Have you tried tools like pnpm or npm workspaces to get Remult installed once at the top-level node_modules?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants