The past few days I've been studying NestJS + Graphql + Mongoose building a small project but started to find some issues due to database relationship and circular dependency. At the moment I'm able to query a patient with a list of previous hospitalizations (code first)
type Patient {
_id: ID!
name: String!
hospitalizations: [Hospitalization!]!
}
type Hospitalization {
_id: ID!
hospitalBed: Bed!
patient: Patient!
}
type PaginatedHospitalization {
totalCount: Int!
edges: [HospitalizationEdge!]
pageInfo: PageInfo!
}
type HospitalizationEdge {
cursor: String!
node: Hospitalization!
}
but I'm unable to update to update hospitalizations to be PaginatedHospitalization probably because of some circular dependency issue I'm unaware of. The error I'm getting on terminal when try to run the project is:
[8:35:19 AM] Starting compilation in watch mode...
[8:35:21 AM] Found 0 errors. Watching for file changes.
================ Hospitalization undefined
==== classRef undefined
/home/notroot/Documents/pessoal/_estudo/nest-graphql/src/common/entities/paginated.entity.ts:18
#ObjectType(`${classRef.name}Edge`)
^
TypeError: Cannot read properties of undefined (reading 'name')
at Paginated (/home/notroot/Documents/pessoal/_estudo/nest-graphql/src/common/entities/paginated.entity.ts:18:27)
at Object.<anonymous> (/home/notroot/Documents/pessoal/_estudo/nest-graphql/src/hospitalization/entities/paginated-hospitalization.entity.ts:9:56)
at Module._compile (node:internal/modules/cjs/loader:1103:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/home/notroot/Documents/pessoal/_estudo/nest-graphql/src/patient/entities/patient.entity.ts:7:1)
at Module._compile (node:internal/modules/cjs/loader:1103:14)
These are my modules
#Module({
imports: [
MongooseModule.forRoot('mongodb://localhost:27017/nest-mongo'),
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
BedModule,
HospitalizationModule,
PatientModule,
],
})
export class AppModule {}
#Module({
imports: [
MongooseModule.forFeature([{ name: Patient.name, schema: PatientSchema }]),
forwardRef(() => HospitalizationModule),
],
providers: [PatientResolver, PatientService],
exports: [PatientService],
})
export class PatientModule {}
#Module({
imports: [
MongooseModule.forFeature([{ name: Bed.name, schema: BedSchema }]),
forwardRef(() => HospitalizationModule),
],
providers: [BedResolver, BedService],
exports: [BedService],
})
export class BedModule {}
#Module({
imports: [
MongooseModule.forFeature([
{ name: Hospitalization.name, schema: HospitalizationSchema },
]),
forwardRef(() => BedModule),
forwardRef(() => PatientModule),
],
providers: [HospitalizationResolver, HospitalizationService],
exports: [HospitalizationService],
})
export class HospitalizationModule {}
These are my Entities
#Schema()
#ObjectType()
export class Patient extends BaseEntity {
#Prop({ required: true })
#Field()
name: string;
#Prop({
type: [{ type: MongoSchema.Types.ObjectId, ref: 'Hospitalization' }],
})
// #Field(() => [Hospitalization], { defaultValue: [] })
#Field(() => PaginatedHospitalization)
hospitalizations?: Hospitalization[];
}
#Schema()
#ObjectType()
export class Bed extends BaseEntity {
#Prop({ required: true })
#Field()
name: string;
#Prop({
type: [{ type: MongoSchema.Types.ObjectId, ref: 'Hospitalization' }],
})
#Field(() => [Hospitalization], { defaultValue: [] })
// TODO: will be update to PaginatedHospitalization as well
hospitalizations?: Hospitalization[];
}
#Schema()
#ObjectType()
export class Hospitalization extends BaseEntity {
#Prop({ type: MongoSchema.Types.ObjectId, ref: 'Bed' })
#Field(() => Bed)
hospitalBed?: Bed;
#Prop({ type: MongoSchema.Types.ObjectId, ref: 'Patient' })
#Field(() => Patient)
patient?: Patient;
}
My paginated object is based on this generic pagination object from NestJS documentation
export function Paginated<T>(classRef: Type<T>): Type<IPaginatedType<T>> {
console.log('==== classRef', classRef);
#ObjectType(`${classRef.name}Edge`)
abstract class EdgeType {
#Field(() => String)
cursor: string;
#Field(() => classRef)
node: T;
}
#ObjectType({ isAbstract: true })
abstract class PaginatedType implements IPaginatedType<T> {
#Field(() => Int)
totalCount: number;
#Field(() => [EdgeType], { nullable: true })
edges: EdgeType[];
#Field(() => PageInfo)
pageInfo: PageInfo;
}
return PaginatedType as Type<IPaginatedType<T>>;
}
console.log('================ Hospitalization', Hospitalization);
#ObjectType()
export class PaginatedHospitalization extends Paginated(Hospitalization) {}
On the docs and examples I saw multiple cases of separate modules like PetModule, OwnerModule but the docs says that circular dependency should be avoided where possible. Is this a case that I should have a single module that have Patient, Bed and Hospitalization on the same module or some other solution?
Related
Below is my code
I tried to set a web socket gateway as below.
events.gateways.ts
import {
MessageBody,
SubscribeMessage,
WebSocketGateway,
WebSocketServer,
} from "#nestjs/websockets";
import { Server } from "socket.io";
#WebSocketGateway({
cors: {
origin: "http://localhost:3000",
},
})
export class EventsGateway {
#WebSocketServer()
server: Server;
#SubscribeMessage("events")
handleEvent(#MessageBody() data: string): string {
return data;
}
}
I set above gateway as a provider to a module.
events.module.ts
import { Module } from "#nestjs/common";
import { EventsGateway } from "./events.gateway";
#Module({
providers: [EventsGateway],
})
export class EventsModule {}
Fianllt, i imported above module to the app.module.ts and now I am getting the error
app.module.ts
import { Module } from "#nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { APP_FILTER } from "#nestjs/core";
import { AllExceptionFilter } from "./all-exception.filter";
import { ConfigModule } from "#nestjs/config";
import { TypeOrmModule } from "#nestjs/typeorm";
import { Student } from "./student/entities/student.entity";
import { EventsModule } from "./events/events.module";
#Module({
imports: [
ConfigModule.forRoot(),
TypeOrmModule.forRoot({
type: "postgres",
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT as string) | 5432,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
entities: [Student],
synchronize: true,
}),
EventsModule,
],
controllers: [AppController],
providers: [
{
provide: APP_FILTER,
useClass: AllExceptionFilter,
},
AppService,
],
})
export class AppModule {}
This is the error I am keep getting.
TypeError: this.graphInspector.insertEntrypointDefinition is not a function
at /home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/web-sockets-controller.js:108:33
at Array.forEach (<anonymous>)
at WebSocketsController.inspectEntrypointDefinitions (/home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/web-sockets-controller.js:106:25)
at WebSocketsController.subscribeToServerEvents (/home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/web-sockets-controller.js:39:14)
at WebSocketsController.connectGatewayToServer (/home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/web-sockets-controller.js:30:14)
at SocketModule.connectGatewayToServer (/home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/socket-module.js:47:35)
at /home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/socket-module.js:36:38
at IteratorWithOperators.forEach (/home/Desktop/New Folder/nest_try_1/node_modules/iterare/lib/iterate.js:157:13)
at SocketModule.connectAllGateways (/home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/socket-module.js:36:14)
at /home/Desktop/New Folder/nest_try_1/node_modules/#nestjs/websockets/socket-module.js:31:61
Node.js v19.4.0
I am follwing the documentation and I am keep getting above error.
you should align your dependencies, ie., if you're using #nestjs/websockets v9.3.1, #nestjs/core must be in v9.3.1 as well
Run npx nest info and check that out.
That error is because #nestjs/websockets is invoking a method added in v9.3 which depends on a method added in v9.3 of #nestjs/core as well.
btw there are closed issues on GitHub about that error: https://github.com/nestjs/nest/issues?q=is%3Aissue+sort%3Aupdated-desc+is%3Aclosed+insertEntrypointDefinition
I'm trying to figure out what I need to do in order to have lib/graphql recognise the mutations I have made.
I have an issue.tsx (which is a form). It imports:
import {
IssueInput,
useUpdateIssueMutation,
useAllIssuesQuery,
useCreateIssueMutation,
useDeleteIssueMutation,
Issue as IssueGQLType,
} from "lib/graphql"
Other than IssueInput and Issue, I'm getting errors in my terminal that say these queries and mutations are not exported members.
However when I try to load the issue page in local host, I get an error that says:
error - GraphQLError [Object]: Syntax Error: Expected Name, found
. It points to the line where Issue is imported.
I made all of these queries and mutations in my resolver as follows:
import { Arg, Mutation, Query, Resolver } from "type-graphql"
import { Issue } from "./issue.model"
import { IssueService } from "./issue.service"
import { IssueInput } from "./inputs/create.input"
import { Inject, Service } from "typedi"
import { UseAuth } from "../shared/middleware/UseAuth"
import { Role } from "#generated"
#Service()
#Resolver(() => Issue)
export default class IssueResolver {
#Inject(() => IssueService)
issueService: IssueService
#Query(() => [Issue])
async allIssues() {
return await this.issueService.getAllIssues()
}
#Query(() => [Issue])
async futureRiskIssues() {
return await this.issueService.getFutureRiskIssues()
}
#Query(() => Issue)
async issue(#Arg("id") id: string) {
return await this.issueService.getIssue(id)
}
#UseAuth([Role.ADMIN])
#Mutation(() => Issue)
async createIssue(#Arg("data") data: IssueInput) {
return await this.issueService.createIssue(data)
}
#UseAuth([Role.ADMIN])
#Mutation(() => Issue)
async deleteIssue(#Arg("id") id: string) {
return await this.issueService.deleteIssue(id)
}
#UseAuth([Role.ADMIN])
#Mutation(() => Issue)
async updateIssue(#Arg("id") id: string, #Arg("data") data: IssueInput) {
return await this.issueService.updateIssue(id, data)
}
}
I can also see from my graphql.tsx file, that these functions are recognised as follows:
export type Mutation = {
__typename?: 'Mutation';
createIssue: Issue;
createUser: User;
deleteIssue: Issue;
destroyAccount: Scalars['Boolean'];
forgotPassword: Scalars['Boolean'];
getBulkSignedS3UrlForPut?: Maybe<Array<SignedResponse>>;
getSignedS3UrlForPut?: Maybe<SignedResponse>;
login: AuthResponse;
register: AuthResponse;
resetPassword: Scalars['Boolean'];
updateIssue: Issue;
updateMe: User;
};
export type MutationCreateUserArgs = {
data: UserCreateInput;
};
export type MutationDeleteIssueArgs = {
id: Scalars['String'];
};
export type MutationUpdateIssueArgs = {
data: IssueInput;
id: Scalars['String'];
};
I have run the codegen several times and can't think of anything else to try to force these mutations and queries to be recognised. Can anyone see a way to trouble shoot this?
My codegen.yml has:
schema: http://localhost:5555/graphql
documents:
- "src/components/**/*.{ts,tsx}"
- "src/lib/**/*.{ts,tsx}"
- "src/pages/**/*.{ts,tsx}"
overwrite: true
generates:
src/lib/graphql.tsx:
config:
withMutationFn: false
addDocBlocks: false
scalars:
DateTime: string
plugins:
- add:
content: "/* eslint-disable */"
- typescript
- typescript-operations
- typescript-react-apollo
When I look at the mutations available on the authentication objects (that are provided with the [boilerplate app][1] that I am trying to use), I can see that there are mutations and queries that are differently represented in the lib/graphql file. I just can't figure out how to force the ones I write to be included in this way:
export function useLoginMutation(baseOptions?: Apollo.MutationHookOptions<LoginMutation, LoginMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<LoginMutation, LoginMutationVariables>(LoginDocument, options);
}
Instead, I get all of these things, but none of them look like the above and I can't figure out which one to import into my front end form so that I can make an entry in the database. None of them look like the queries or mutations I defined in my resolver
export type IssueInput = {
description: Scalars['String'];
issueGroup: Scalars['String'];
title: Scalars['String'];
};
export type IssueListRelationFilter = {
every?: InputMaybe<IssueWhereInput>;
none?: InputMaybe<IssueWhereInput>;
some?: InputMaybe<IssueWhereInput>;
};
export type IssueRelationFilter = {
is?: InputMaybe<IssueWhereInput>;
isNot?: InputMaybe<IssueWhereInput>;
};
export type IssueWhereInput = {
AND?: InputMaybe<Array<IssueWhereInput>>;
NOT?: InputMaybe<Array<IssueWhereInput>>;
OR?: InputMaybe<Array<IssueWhereInput>>;
createdAt?: InputMaybe<DateTimeFilter>;
description?: InputMaybe<StringFilter>;
id?: InputMaybe<UuidFilter>;
issueGroup?: InputMaybe<IssueGroupRelationFilter>;
issueGroupId?: InputMaybe<UuidFilter>;
subscribers?: InputMaybe<UserIssueListRelationFilter>;
title?: InputMaybe<StringFilter>;
updatedAt?: InputMaybe<DateTimeFilter>;
};
export type IssueWhereUniqueInput = {
id?: InputMaybe<Scalars['String']>;
};
I do have this record in my graphql.tsx file:
export type Mutation = {
__typename?: 'Mutation';
createIssue: Issue;
createIssueGroup: IssueGroup;
createUser: User;
deleteIssue: Issue;
deleteIssueGroup: IssueGroup;
destroyAccount: Scalars['Boolean'];
forgotPassword: Scalars['Boolean'];
getBulkSignedS3UrlForPut?: Maybe<Array<SignedResponse>>;
getSignedS3UrlForPut?: Maybe<SignedResponse>;
login: AuthResponse;
register: AuthResponse;
resetPassword: Scalars['Boolean'];
updateIssue: Issue;
updateIssueGroup: IssueGroup;
updateMe: User;
};
but I can't say: createIssueMutation as an import in my issue.tsx where I'm trying to make a form to use to post to the database.
[1]: https://github.com/NoQuarterTeam/boilerplate
In the issue form, I get an error that says:
"resource": "/.../src/pages/issue.tsx", "owner": "typescript",
"code": "2305", "severity": 8, "message": "Module '"lib/graphql"'
has no exported member 'useCreateIssueMutation'.", "source": "ts",
"startLineNumber": 7, "startColumn": 27, "endLineNumber": 7,
"endColumn": 54 }]
and the same thing for the query
check your codegen.yml
overwrite: true
schema: "http://localhost:4000/graphql"
documents: "src/graphql/**/*.graphql"
generates:
src/generated/graphql.tsx:
plugins:
- "typescript"
- "typescript-operations"
- "typescript-react-apollo"
./graphql.schema.json:
plugins:
- "introspection"
or try something like #Resolver(Issue)
It seems like you are not generating the hooks that you are trying to import.
You can update your codegen.yml file to add the generated hooks:
schema: http://localhost:5555/graphql
documents:
- "src/components/**/*.{ts,tsx}"
- "src/lib/**/*.{ts,tsx}"
- "src/pages/**/*.{ts,tsx}"
overwrite: true
generates:
src/lib/graphql.tsx:
config:
withMutationFn: false
addDocBlocks: false
scalars:
DateTime: string
withHooks: true # <--------------------- this line
plugins:
- add:
content: "/* eslint-disable */"
- typescript
- typescript-operations
- typescript-react-apollo
I am experimenting with NestJS and TypeGraphQL. And I have an example model of a cat.
import { Document } from 'mongoose';
import { ObjectType, InputType, Field, ID } from 'type-graphql';
export interface Cat extends Document {
readonly name: string;
readonly age?: number;
}
class CatBase {
#Field()
name: string;
#Field({ nullable: true })
age?: number;
}
#ObjectType()
export class CatObjectType extends CatBase implements Cat {
#Field(type => ID)
id: string;
}
#InputType()
export class CatInputType extends CatBase implements Cat {
}
Here I am trying to reuse BaseCat in CatObjectType and CatInputType. But I getting this error:
[ { GraphQLError: Input Object type CatInputType must define one or more fields.
at SchemaValidationContext.reportError (/Users/pavel/Dev/exampleproject/node_modules/graphql/type/validate.js:90:19)
at validateInputFields (/Users/pavel/Dev/exampleproject/node_modules/graphql/type/validate.js:432:13)
at validateTypes (/Users/pavel/Dev/exampleproject/node_modules/graphql/type/validate.js:240:7)
at validateSchema (/Users/pavel/Dev/exampleproject/node_modules/graphql/type/validate.js:54:3)
at graphqlImpl (/Users/pavel/Dev/exampleproject/node_modules/graphql/graphql.js:79:62)
at /Users/pavel/Dev/exampleproject/node_modules/graphql/graphql.js:28:59
at new Promise (<anonymous>)
at Object.graphql (/Users/pavel/Dev/exampleproject/node_modules/graphql/graphql.js:26:10)
at Function.<anonymous> (/Users/pavel/Dev/exampleproject/node_modules/type-graphql/dist/schema/schema-generator.js:18:52)
at Generator.next (<anonymous>)
at /Users/pavel/Dev/exampleproject/node_modules/tslib/tslib.js:110:75
at new Promise (<anonymous>)
at Object.__awaiter (/Users/pavel/Dev/exampleproject/node_modules/tslib/tslib.js:106:16)
at Function.generateFromMetadata (/Users/pavel/Dev/exampleproject/node_modules/type-graphql/dist/schema/schema-generator.js:15:24)
at /Users/pavel/Dev/exampleproject/node_modules/type-graphql/dist/utils/buildSchema.js:11:65
at Generator.next (<anonymous>)
message:
'Input Object type CatInputType must define one or more fields.' } ]
(node:72485) UnhandledPromiseRejectionWarning: Error: Generating schema error
at Function.<anonymous> (/Users/pavel/Dev/exampleproject/node_modules/type-graphql/dist/schema/schema-generator.js:20:27)
at Generator.next (<anonymous>)
at fulfilled (/Users/pavel/Dev/exampleproject/node_modules/tslib/tslib.js:107:62)
at processTicksAndRejections (internal/process/next_tick.js:81:5)
(node:72485) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:72485) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
When in CatInputType are described all fields from BaseCat all work as expected. What I am doing wrong?
TypeGraphQL by default doesn't inherit all #Fields from parent classes that are not decorated with #InputType or #ObjectType because this types should not be mixed as things like unions and interfaces are invalid GraphQL input types.
So if you are sure you're not violating this rules, just place both decorators on top of the class:
#ObjectType({ isAbstract: true })
#InputType({ isAbstract: true })
class CatBase {
#Field()
name: string;
#Field({ nullable: true })
age?: number;
}
I'm currently trying to inherit schemas for a rootQuery in order to get more modularity. The setup currently looks as follows:
invoiceSchema.js
import {
GraphQLObjectType,
GraphQLInt,
} from 'graphql';
export default new GraphQLObjectType({
name: 'Invoice',
description: 'A monthly billing invoice for an organization',
fields: () => ({
amountDue: {
type: GraphQLInt,
description: 'The amount the card will be charged (total + startingBalance with a min value of 0)'
},
})
});
rootQuery.js
import {
GraphQLObjectType,
GraphQLString,
GraphQLInt,
GraphQLList,
GraphQLID
} from 'graphql';
import Invoice from './invoiceSchema';
export default {
Invoice: {
type: Invoice,
resolve(parentValue, args){
return 'Hello world';
}
}
};
schema.js
import query from './rootQuery';
import {GraphQLSchema} from 'graphql';
export default new GraphQLSchema({query});
When trying to do the following error and hoped for some help and insight, as what I'm exporting in invoiceSchema.js is clearly an ObjectType and not an object Object.
C:\project\node_modules\graphql\jsutils\invariant.js:19
throw new Error(message);
^
Error: Schema query must be Object Type but got: [object Object].
at invariant (C:\project\node_modules\graphql\jsutils\invariant.js:19:11)
at new GraphQLSchema (C:\project\node_modules\graphql\type\schema.js:72:88)
at Object.<anonymous> (C:/project/api/schema/schema.js:6:16)
at Module._compile (module.js:573:30)
at loader (C:\project\node_modules\babel-register\lib\node.js:144:5)
at Object.require.extensions.(anonymous function) [as .js] (C:\project\node_modules\babel-register\lib\node.js:154:7)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
at Module.require (module.js:517:17)
[nodemon] app crashed - waiting for file changes before starting...
Actually got the idea from here and I'm wondering why it doesn't work...
Your root query needs to be an instance of GraphQLObjectType, however, rootQuery.js is exporting a plain Object instead. You'll need to change your export to something like this:
export default new GraphQLObjectType({
name: 'RootQuery',
fields: () => ({
invoice: {
type: Invoice,
resolve(parentValue, args){
return 'Hello world';
}
}
})
};
Note: it's common practice to keep all field names, including query and mutation names, in camelCase and use PascalCase for type names, to help distinguish between the two.
Also, if you are modularizing your schema, you may find it helpful to utilize graphql-tools for generating your schema instead. IMO, it makes your schema more readable and helps avoid some of the more common pitfalls you may face when modularizing a schema. The docs have a great example of how to modularize your schema with makeExecutableSchema here.
I am planning to start learning angular 2 component router.
I have used Angular ui-router heavily.All my projects uses UI-router complex features like nested states and nested named views.
What will be good start to use angular 2 component router?
how can I configure nested states in Angular 2 component router?
All in all i would say routing is pretty simple and intuitive in angular 2
I would suggest reading through the router docs to get all the basics.
Keep in mind that child components can have routes too. They build from its parents routes.
app.component.ts (excerpt)
#Component({ ... })
#RouteConfig([
{path:'/crisis-center/...', name: 'CrisisCenter', component: CrisisListComponent},
{path:'/heroes', name: 'Heroes', component: HeroListComponent},
{path:'/hero/:id', name: 'HeroDetail', component: HeroDetailComponent}
])
export class AppComponent { }
crisis-center.component.ts(excerpt)
#RouteConfig([
{path:'/', name: 'CrisisCenter', component: CrisisListComponent, useAsDefault: true},
{path:'/:id', name: 'CrisisDetail', component: CrisisDetailComponent}
])
Notice that the path ends with a slash and three trailing periods (/...).
That means this is an incomplete route (AKA a non-terminal route). The finished route will be some combination of the parent /crisis-center/ route and a route from the child router that belongs to the designated component.
All is well. The parent route's designated component is the CrisisCenterComponent which is a Routing Component with its own router and routes.
From angular.io router guide
You can define a app.routing.ts like below.
export const routes: Routes = [
{
path: '',
component: SimpleLayoutComponent,
data: {
title: 'Login form'
},
children: [
{
path: '', component: LoginComponent,
}
]
},
{
path: 'dashboard',
component: FullLayoutComponent,
data: {
title: 'Home'
},
children: [
{
path: '',
component: 'mycomponent'
}
]
}
];
Then import this class to your app.module.ts file like below.
import { AppRoutingModule } from './app.routing';
#NgModule({
imports: [
BrowserModule,
HttpModule,
FormsModule,
AppRoutingModule,
],
declarations: [
AppComponent,
LoginComponent
],
providers: [
UserService, AuthGuard],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.component.ts Below: views get injected in
import { Component } from '#angular/core';
#Component({
selector: 'body',
template: '<router-outlet></router-outlet>'
})
export class AppComponent { }
#NgModule({
declarations: [AppComponent,CreateComponent,ListComponent],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
RouterModule.forRoot([
{path:"",component:ListComponent},
{path:"Create",component:CreateComponent},
])
],
bootstrap: [AppComponent]
})
Put this RouterModule in app.module file.
For this you have to import { RouterModule} ;
<router-outlet></router-outlet>
Put router-outlet element in app.component.html to render component through routing.