I made a simple app which is running correctly.
Now I am trying to write test cases of that application, so I tried with routing.
stackblitz
My routing code is this
Main module:
export const routes: Routes = [
{ path: '', redirectTo: '/users', pathMatch: 'full' },
];
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
UserModule,
HttpClientModule,
RouterModule.forRoot(routes)
],
Feature module:
const routes: Routes = [
{path: 'users', component: ListingComponent}
];
#NgModule({
imports: [
CommonModule,
RouterModule.forChild(routes)
],
declarations: [ListingComponent]
})
Code
I try to run my spec but I am getting above error
describe('Initial navigation', () => {
it('default route redirects to home (async)', fakeAsync(() => {
router.initialNavigation(); // triggers default
fixture.detectChanges();
tick();
console.log('==================');
console.log(location.path());
// fixture.whenStable().then(() => {
expect(location.path()).toBe('/users');
// })
}));
});
If you import UserModule to the spec, this resolves the error. As AppModule modules imports UserModule to register user feature/module routes, it must also be imported in the spec to ensure it's route registrations are available in the spec as well.
The need for this is implied at a basic level in the documentation Testing: Import a feature module.
//setup
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
UserModule, // import module
RouterTestingModule.withRoutes(routes)],
declarations: [
TestComponent,
]
});
fixture = TestBed.createComponent(TestComponent);
router = TestBed.get(Router);
location = TestBed.get(Location);
});
Here is an updated StackBlitz demonstrating the functionality (test passing with no error).
Related
Can someone tell me why i have this error:
[Nest] 556 - 2020-06-10 18:52:55 [ExceptionHandler] Nest can't resolve dependencies of the JwtService (?). Please make sure that the argument JWT_MODULE_OPTIONS at index [0] is available in the JwtModule context.
Potential solutions:
- If JWT_MODULE_OPTIONS is a provider, is it part of the current JwtModule?
- If JWT_MODULE_OPTIONS is exported from a separate #Module, is that module imported within JwtModule?
#Module({
imports: [ /* the Module containing JWT_MODULE_OPTIONS */ ]
})
my modules:
#Module({
imports: [
PassportModule.register({ defaultStrategy: 'jwt'}),
JwtModule.register({
secret: 'topSecret51',
signOptions: {
expiresIn: 3600
},
}),
TypeOrmModule.forFeature([User])
],
controllers: [AuthController],
providers: [AuthService, UserService]
})
export class AuthModule {}
#Module({
controllers: [UserController],
providers: [UserService, AuthService],
imports: [AuthModule]
})
export class UserModule {}
#Module({
imports: [
TypeOrmModule.forRoot(typeOrmConfig),
UserModule,
AuthModule
],
})
export class AppModule {}
i try to change in all of them but in all of them my app does not work
thanks for any help
////////////////////////////////////////////////////
If you are using some dependencies of the controller in JwtService, you need to add JWT_MODULE_OPTIONS as provider inside the current AuthModule. Have a look at the nestjs documentation. They have explained on how to register custom providers.
I received this error when I did not correctly import / initialize the JwtModule. The JwtModule should handle the JwtService initialization which this error comes from. I would start there. If you're using the AuthModule in your test environment which by extension needs the JwtModule then you'll need to manually define your JwtModule with something similar:
beforeAll(async () => {
const testingModule: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
MongooseModule.forFeature([{ name: 'User', schema: userSchema }]),
JwtModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
secret: configService.get('JWT_SECRET'),
signOptions: { expiresIn: '1d' }
})
}),
],
I have ERROR in Cannot read property 'loadChildren' of null on npm run build prod --aot=true in my Angular 8 project. The local build works perfect.
I found, that this error appears when I'm trying to convert some object to Route by a special function, and after that add this route to Routes array.
Please help to understand how to fix it.
Some piece of code:
function objToRoute(obj: any): Route {
// convert it to route and return
}
const routes: Routes = [
path: '',
component: SomeComponent,
children: [
objToRoute(specialObject),
{
path: '**',
component: StubComponent
}
]
]
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class SomeRoutingModule {}
To be more specific, here is a simple example of objToRoute function:
function objToRoute(obj: any): Route {
return obj;
}
const routeObj: Route = {
path: 'somePath',
pathMatch: 'full',
loadChildren: () => import('pathToDir/someLazy.module').then(m => m.SomeLazyModule)
}
const routes: Routes = [
path: '',
component: SomeComponent,
children: [
objToRoute(routeObj),
{
path: '**',
component: StubComponent
}
]
]
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class SomeRoutingModule {}
And in this case I have the error ERROR in Cannot read property 'loadChildren' of undefined on npm run build prod --aot=true
I have a module called "host" with its own routing that I want to insert into the app-routing.module. However, I have the problem of the wildcard loading first and displaying PageNotFoundComponent, instead of the Host component loading. I have the following files.
host.module.ts
....
const routes: Routes = [
{
path: 'host',
children: [
{ path: '', component: HostComponent }
]
}
];
#NgModule({
declarations: [HostComponent],
imports: [
CommonModule,
RouterModule.forChild(routes)
]
})
export class HostModule { }
app-routing.module.ts
const routes: Routes = [
{ path: '', component: HomeComponent, pathMatch: "full"},
{ path: '**', component: PageNotFoundComponent }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
app.module.ts
#NgModule({
declarations: [
AppComponent,
HomeComponent,
PageNotFoundComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HostModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
<h2>Home</h2>
<ul>
<li>
<h2><a routerLink="/host">host</a></h2>
</li>
</ul>
<router-outlet></router-outlet>
Problem: When I run the app and click on the "Host" button, it loads the PageNotFoundComponent. I obviously want it to go to the HostComponent.
In your app.module.ts you need to reorder your imports
#NgModule({
declarations: [
AppComponent,
HomeComponent,
PageNotFoundComponent
],
imports: [
BrowserModule,
HostModule, <--- this before AppRoutingModule
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Reason being is because the order of the routes in the configuration matters. https://angular.io/guide/router#configuration
The ** path in the last route is a wildcard. The router will select this route if the requested URL doesn't match any paths for routes defined earlier in the configuration. This is useful for displaying a "404 - Not Found" page or redirecting to another route.
The order of the routes in the configuration matters and this is by design. The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes. In the configuration above, routes with a static path are listed first, followed by an empty path route, that matches the default route. The wildcard route comes last because it matches every URL and should be selected only if no other routes are matched first.
I am creating an application that uses Angular 6 (6.0.6) and #uirouter/angular (2.0.0). But my app does not reconize the route '/login', it does only navigate to '/' (even if I remove the 'otherwise: '/'')
This application exists of multiple modules with multiple pages. The structure can be described as follows:
app/
-- home/
---- home.module.ts
---- home.component.ts
---- home.route.ts
---- home.scss
---- home.html
-- login/
---- login.module.ts
---- login.component.ts
---- login.route.ts
---- login.scss
---- login.html
-- app.module.ts
-- app.component.ts
Both modules have a separate routing file. The way I thought it would work was as follows (simplified example, don't mind the missing parts):
app.module.ts
#NgModule({
declarations: [AppComponent],
imports: [
UIRouterModule.forRoot({otherwise: '/'}),
HomeModule,
LoginModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
home.module.ts
#NgModule({
imports: [
UIRouterModule.forChild({states: [homeState]}),
NavbarModule
],
declarations: [HomeComponent],
providers: []
})
export class HomeModule {
}
home.route.ts
export const homeState: Ng2StateDeclaration = {
name: 'home',
url: '/',
component: HomeComponent
};
login.module.ts
#NgModule({
imports: [
UIRouterModule.forChild({states: [loginState]}),
],
declarations: [LoginComponent],
providers: []
})
export class LoginModule {
}
login.route.ts
export const loginState: Ng2StateDeclaration = {
name: 'login',
url: '/login',
component: LoginComponent
};
I expected that the UIRouterModule.forChild() method would just add the route to the configuration. But the /login route is not reconized and it just navigates back to /. I do not want to create a submodule where all my routing happens, because then I will also have to import all the dependencies my components have in that module (so far separation of concern and modularization).
This would look as follows for my example app:
const states = [homeState, loginState];
#NgModule({
imports: [
UIRouterModule.forChild({states: [states], otherwise: '/'}),
NavbarModule
],
declarations: [HomeComponent, loginComponent],
providers: []
})
export class AppRoutingModule {
}
The loginComponent does not need the NavBarModule, but still gets it this way..
Since this doesn't work I am clearly doing something wrong. Can anyone tell me what I am doing wrong and how I should fix it?
Your architecture may need a bit more thought. Have a look at the approach in this blog post which uses the native Angular router to achieve what you are trying to do.
I'm new in Angular 5 and trying to build an app with client side and admin side. So I did some search and made this:
AppRoutingModule
const appRoutes: Routes = [
{
path: '',
loadChildren: 'app/website/public.module#PublicModule'
},
{
path: 'admin',
loadChildren: 'app/admin/admin.module#AdminModule'
}
];
#NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
PublicRoutingModule
const PUBLIC_ROUTES: Routes = [
{
path: '',
component: HomeComponent,
}
];
#NgModule({
imports: [RouterModule.forChild(PUBLIC_ROUTES)],
exports: [RouterModule]
})
export class PublicRoutingModule { }
AdminRoutingModule
const ADMIN_ROUTES: Routes = [
{
path: '',
component: DashboardComponent,
data: {
title: 'Dashboard'
},
children: [
]
}
];
#NgModule({
imports: [RouterModule.forChild(ADMIN_ROUTES)],
exports: [RouterModule]
})
export class AdminRoutingModule { }
And I have imported AppRoutingModule in AppModule, and also imported PublicRoutingModule in PublicModule, also imported AdminRoutingModule in AdminModule.
When I run the app, there is no errors but the HomeComponent is not been rendered initially.
Can anyone tell what's the problem here? Thank you.
For lazy load module, I think you should add components' declarations to their own router module.
Example for PublicRoutingModule(same for AdminRoutingModule)
const PUBLIC_ROUTES: Routes = [
{
path: '',
component: HomeComponent,
}
];
#NgModule({
declarations: [ HomeComponent ], // add declaration
imports: [RouterModule.forChild(PUBLIC_ROUTES)],
exports: [RouterModule]
})
export class PublicRoutingModule { }
BTW, while debugging routing problems, you should enable tracing to see what really happened during navigation.
#NgModule({
imports: [RouterModule.forRoot(appRoutes, { enableTracing: true })],
exports: [RouterModule]
})
export class AppRoutingModule { }