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

Typescript module and type-graphql dependency #69

Closed
fromnowhereuser opened this issue Apr 23, 2018 · 13 comments
Closed

Typescript module and type-graphql dependency #69

fromnowhereuser opened this issue Apr 23, 2018 · 13 comments
Labels
Question ❔ Not future request, proposal or bug issue Solved ✔️ The issue has been solved

Comments

@fromnowhereuser
Copy link

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.

@MichalLytek
Copy link
Owner

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.

@MichalLytek MichalLytek added Question ❔ Not future request, proposal or bug issue Need More Info 🤷‍♂️ Further information is requested labels Apr 24, 2018
@MichalLytek
Copy link
Owner

@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.

@MichalLytek
Copy link
Owner

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.

@fromnowhereuser
Copy link
Author

@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 ?

@MichalLytek
Copy link
Owner

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

@fromnowhereuser
Copy link
Author

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...

@MichalLytek
Copy link
Owner

Please create a repository with minimal example code that reproduce the issue, so I could run it and find where the problem is 😉

@MichalLytek MichalLytek reopened this Apr 30, 2018
@fromnowhereuser
Copy link
Author

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

@MichalLytek
Copy link
Owner

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? 😕

@fromnowhereuser
Copy link
Author

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 ?

@MichalLytek
Copy link
Owner

MichalLytek commented May 3, 2018

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 😉

@fromnowhereuser
Copy link
Author

So, one class representing Data only. And interface for specific behavior ? Seems good to me. Did i get it ?

@MichalLytek
Copy link
Owner

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!

@MichalLytek MichalLytek added Solved ✔️ The issue has been solved and removed Need More Info 🤷‍♂️ Further information is requested labels Oct 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question ❔ Not future request, proposal or bug issue Solved ✔️ The issue has been solved
Projects
None yet
Development

No branches or pull requests

2 participants