I love your project. The approach seems to be very similar to the JAVA one. And i like that.
One domain model that make "one source of truth". Then i have splitted my TS class model definition in a specific node project (the library) to make it available from:
a type-graphql server
AND
an Angular app.
The library project AND the type-graphql server depend of type-graphql.
When i launch the server, i have something like that:
Error: Cannot determine type for MyType:attr
Am i doing it wrong ? Because... it seems that type-graphql is enable to see the transpiled anotation. Thank you for any help or advice you can provide.
There's no need to use TypeGraphQL in Angular App. To fetch data from GraphQL server you write dedicated GraphQL queries. Then you can use apollo-codegen to generate interfaces describing the data that server return for this queries and you should use them in your component as the data type, not the model class.
@fromnowhereuser Can you tell me for what do you use TypeGraphQL model definitions in your Angular app?
I can make it work across multiple packages/projects but I haven't seen a valid use case yet.
Closing as v0.11.2 has support for multi project/modules.
@fromnowhereuser Please feel free to reopen this issue if you still have a problem with this.
@19majkel94 i dont need graphql form the angular project. But i want the class definitions. I use them a lot in the angular project.
Angular Project ======\
=====> Models project =====> Typegraphql (for annotations)
Typegraphql project ======/
But it doesnt work. Do i did it wrong ?
Seems like you don't have reflect-metadata imported in your Angular app or your tsconfig.json doesn't have "emitDecoratorMetadata": true, options set. So when decorators are evaluated, they throw errors like Cannot determine type for MyType:attr.
I would have to create a dummy decorators that could be used in browser, like TypeORM:
https://github.com/typeorm/typeorm/blob/master/extra/typeorm-model-shim.js
i dont have any problem in my angular App. Again, i dont use typegraphql in my angular app, i just need the class.
My problem is when i want to start the typegraphql project. If i define the annotated class in a lib, the app wont start:
Error: Cannot determine type for MyType#name !
But if i define the annotated class directly in the typegraphql project its ok. But i need to use the entity in another project ( the angular one).
I'm really sorry if the explanation was not clear...
Please create a repository with minimal example code that reproduce the issue, so I could run it and find where the problem is 馃槈
Here the sample project:
https://github.com/fromnowhereuser/back
Just go to models2
npm install
tsc && npm link
and go to back
npm install
npm link models2
tsc && ./build/app.js
As I said:
0.11.2 has support for multi project/modules
This is the first issue with your repo - lease upgrade your dependencies version as you have mismatch between projects.
Second, RTFM!
https://github.com/19majkel94/type-graphql#typescript-configuration
Without emitDecoratorMetadata there's no type metadata so you get Error: Cannot determine type for MyType:attr.
After fixing you issues, the transpiled code looks like this:
__decorate([
type_graphql_1.Field(type => type_graphql_1.ID),
__metadata("design:type", Number)
], XAItem.prototype, "id", void 0);
__decorate([
type_graphql_1.Field(),
__metadata("design:type", String)
], XAItem.prototype, "name", void 0);
__decorate([
type_graphql_1.Field(),
__metadata("design:type", String)
], XAItem.prototype, "desc", void 0);
XAItem = __decorate([
type_graphql_1.InterfaceType({ description: "" }),
__metadata("design:paramtypes", [])
], XAItem);
Third, you can't mix interfaces and inheritance:
@ObjectType({ implements: XAItem, description: "" })
export class User extends XAItem {}
GraphQL has no support for extending in schema, so you can't express this kind of relation. You need to switch XAItem to a normal ObjectType class and use inheritance (not recommended) or makes class User implements XAItem and implement the public fields.
Also, you can't use classes as interfaces and have constructors defined:
@InterfaceType({ description: "" })
export abstract class XAItem {
constructor() {
this.name = '';
this.id = 0;
this.desc = 'undef';
}
The last error Cannot determine GraphQL output type for id basically comes from getGraphQLOutputType and convertTypeIfScalar which performs if type instanceof GraphQLScalarType. The problem is that separate project has separate node_modules so GraphQLScalarType !== GraphQLScalarType.
From my experience there's always too much problems from separating things to projects/modules than the benefits of this. I would recommend restructuring your app to don't need this.
i dont need graphql form the angular project. But i want the class definitions.
The solution for coupling backend with frontend is GraphQL 馃槈 Use apollo-codegen for generating TS interfaces describing the data received/passed to backend, not share the "model" class. Why your angular app has to now all the implementation details of XAItem? Isn't field&types info enough? 馃槙
Wow..? that's a lot of error... Thank you very much for your support and time.
I have business functions on my types. I am building a progressive app... Every derived class (from XaItem) has business functions.
What do you think ?
I have business functions on my types.
So seems you like OOP. But with this you are volatiling the single responsibility principle.
Use TypeGraphQL types like a DTO classes. Move the logic to separate services or create adapters for converting model classes (business logic, db entity stuffs, etc.) to DTO and vice-versa. Don't use big, all-in-one classes with multiple interfaces and inheritance chains 馃槈
So, one class representing Data only. And interface for specific behavior ? Seems good to me. Did i get it ?
Basically, yes 馃槈
I am closing this issue for now.
If you have more question, please ask them on the gitter channel. Issues should be used for bug reports and feature requests. Thanks!