so just new with angular and firebase, i am trying to create authentication, the code is not throwing any error but when i try accessing it in the browser it freezes, i can't even click on anything. below are the authentication code.
import { Injectable, NgZone } from '#angular/core';
import { AngularFireAuth } from '#angular/fire/compat/auth';
import { AngularFirestore, AngularFirestoreDocument } from '#angular/fire/compat/firestore';
import { Router } from '#angular/router';
import * as auth from 'firebase/auth';
import { UserService } from '../users/user.service';
//import { User } from '../../models/users/user';
import { DataService } from '../database/data.service';
#Injectable({
providedIn: 'root'
})
export class AuthService {
loggedin = false;
// user$: Observable<any> | undefined;
// user: any;
userData: any;
constructor(
public firestore: AngularFirestore,
public fireauth: AngularFireAuth,
public userservice: UserService,
public router: Router,
public ngZone: NgZone,
public dataService: DataService,
) {
// this.fireauth.authState.subscribe((user) => {
// if (user){
// this.userData = user;
// this.dataService.addData('users', this.userData); // you can json stringify this if you want
// localStorage.setItem('user', JSON.stringify(this.userData));
// JSON.parse(localStorage.getItem('user') || '{}');
// }
// else {
// this.dataService.addData('users', null);
// localStorage.setItem('user', '');
// JSON.parse(localStorage.getItem('user') || '{}');
// }
// });
//this.loggedin = !!localStorage.getItem('user');
}
// Sign in with email/password
async loginUser(email: string, password: string) {
try {
const result = await this.fireauth
.signInWithEmailAndPassword(email, password);
this.SetUserData(result.user);
this.fireauth.authState.subscribe((user_1) => {
if (user_1) {
this.router.navigate(['dashboard']);
}
});
} catch (error) {
window.alert(error);
}
}
i have comment out eveery code int he login components but i still get this issue,
app.modules
#NgModule({
declarations: [
AppComponent,
LoginComponent,
OrderListComponent,
DashboardComponent,
ProfileGeneralComponent,
MenuComponent,
ProfileMenuComponent,
ProfileServicesComponent,
Dashboard2Component,
LineChartComponent,
],
imports: [
BrowserModule,
RouterModule,
FormsModule,
ReactiveFormsModule,
AppRoutingModule,
IonicStorageModule.forRoot(),
IonicModule.forRoot({
mode: 'ios'
}),
AngularFireModule.initializeApp(environment.firebase),
AngularFireAuthModule,
AngularFirestoreModule,
AngularFireStorageModule,
AngularFireDatabaseModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAuth(() => getAuth()),
provideFirestore(() => getFirestore()),
provideStorage(() => getStorage()),
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app-routing.module
const routes: Routes = [
{ path: '', component: LoginComponent },
{
path: 'dashboard',
//canActivate: [AuthGuard],
component: DashboardComponent
},
{
path: 'overview-dashboard',
canActivate: [AuthGuard],
component: Dashboard2Component
},
{
path: 'profile',
canActivate: [AuthGuard],
component: ProfileGeneralComponent
},
{
path: 'profile-menu',
canActivate: [AuthGuard],
component: ProfileMenuComponent
},
{
path: 'profile-services',
canActivate: [AuthGuard],
component: ProfileServicesComponent
},
{
path: 'order-list',
canActivate: [AuthGuard],
component: OrderListComponent
},
{
path: 'login',
canActivate: [AuthGuard],
component: LoginComponent
},
{
path: 'line-chart',
canActivate: [AuthGuard],
component: LineChartComponent
}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
when i access other pages with nothing related to authentication they work.
Related
I am trying to use jsonwebtoken with NestJs, and have been battling with this issue whereby NestJS returns an empty object once it encouters my code line to generate a token.
Each time, I try to generate a token, the server simply responds with an empty object.
Here is my jwt strategy code for passport
import { ConfigService } from "#nestjs/config";
import { ExtractJwt, Strategy } from "passport-jwt";
import { PassportStrategy } from "#nestjs/passport";
import { Inject, Injectable, UnauthorizedException } from "#nestjs/common";
import { RidersService } from "../riders/riders.service";
import { DriversService } from "../drivers/drivers.service";
#Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
private readonly riderService: RidersService,
private readonly driverService: DriversService,
#Inject(ConfigService) config: ConfigService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: config.get("JWT_SECRET"),
});
}
async validate(payload: {
role: string;
iat: number;
exp: number;
phone: string;
}) {
if (!payload) {
throw new UnauthorizedException();
}
const service = {
rider: this.riderService,
driver: this.driverService,
};
const user = await service[payload.role].findByAny(payload.phone);
if (!user) {
throw new UnauthorizedException();
}
// eslint-disable-next-line #typescript-eslint/no-unused-vars
const { iat, exp, ...rest } = payload;
return rest;
}
}
Now here is my AuthService stripped off
import { InjectModel } from "#nestjs/mongoose";
import { Injectable, Logger, HttpException } from "#nestjs/common";
import { JwtService } from "#nestjs/jwt";
#Injectable()
export class AuthService {
private readonly logger = new Logger(AuthService.name);
constructor(
private readonly jwtService: JwtService,
) {}
async register(
phone: string,
role: string,
): Promise<LoginResponseDTO | GENERIC_RESPONSE | unknown> {
return {
token: this.jwtService.sign({ role, phone }),
};
}
}
This line return { token: this.jwtService.sign({ role, phone }), } returns an empt object {} no matter what I do, once the code execution gets there, it stops and sends back an empty response.
Here is my Authmodule stripped off
import { JwtStrategy } from "./jwt.strategy";
import { Module } from "#nestjs/common";
import { AuthService } from "./auth.service";
import { AuthController } from "./auth.controller";
import { PassportModule } from "#nestjs/passport";
import { JwtModule } from "#nestjs/jwt";
import { ConfigModule, ConfigService } from "#nestjs/config";
#Module({
imports: [
PassportModule,
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
secret: configService.get<string>("JWT_SECRET"),
signOptions: { expiresIn: configService.get<string>("JWT_EXPIRESIN") },
}),
inject: [ConfigService],
}),
],
providers: [
AuthService,
JwtStrategy,
],
exports: [AuthService],
controllers: [AuthController],
})
export class AuthModule {}
Here is my Authcontroller stripped off
import { AuthService } from "./auth.service";
import { BadRequestException, Controller, Post, Query } from "#nestjs/common";
import { ParsePhonePipe } from "./../pipes/transform-phone.pipes";
#Controller("auth")
export class AuthController {
constructor(private readonly authService: AuthService) {}
#Post("signup")
async register(
#Query("phone", new ParsePhonePipe()) phone: string,
#Query("role") role: string,
) {
if (!role) {
throw new BadRequestException("user role is missing");
}
try {
const response = await this.authService.register(phone, role);
console.log(response, "RESPONSE");
return response;
} catch (error) {
return error;
}
}
}
Here is Appmodule stripped of
import { ConfigModule, ConfigService } from "#nestjs/config";
import { Module } from "#nestjs/common";
import { APP_GUARD } from "#nestjs/core";
import { AuthModule } from "./auth/auth.module";
import { JwtAuthGuard } from "./auth/jwt.auth.guard";
#Module({
imports: [
AuthModule,
MongooseModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
uri: configService.get<string>("RYDR_DB_URI"),
}),
inject: [ConfigService],
}),
ConfigModule.forRoot({
isGlobal: true,
}),
],
providers: [
{
provide: APP_GUARD,
useClass: JwtAuthGuard,
},
TripHistoryService,
DriversService,
],
})
export class AppModule {}
The login response has nothing to do with the jwt as there are three possible response types defined.
I am unable to generate jwt token and it simply exit with an empty object {}, there is no error whatsoever.
What might I be doing wrong?
I tried to use jsonwebtoken package itself, expecting that there might be an issue with NestJs but it still failed to generate any token instead it returned an empty object as a response.
I am trying to use an exception filter in my NestJS app. I have to translate my exception message into another language based on the request value. I have two languages file en and fr.
I have initialized i18N in my app.module.ts as per the following:
#Module({
imports: [
I18nModule.forRoot({
fallbackLanguage: 'en',
parser: I18nJsonParser,
parserOptions: {
path: path.join(__dirname, '/i18n/'),
},
resolvers: [
PathResolver,
{ use: QueryResolver, options: ['lang', 'locale', 'l'] },
AcceptLanguageResolver
]
}),
],
controllers: [AppController],
providers: [AppService,
{
provide: APP_FILTER,
useClass: NotFoundExceptionFilter,
},
{
provide: APP_FILTER,
useClass: HttpExceptionFilter,
}
],
})
export class AppModule { }
My Exception filter class looks like this:
#Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter<HttpException> {
constructor(private readonly i18n: I18nService) { }
async catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const request = ctx.getRequest();
const statusCode = exception.getStatus();
await this.i18n.translate('message.Unauthorized', { lang: 'fr' }).then(message => {
console.log('message -> ', message);
response.status(403).send({
status: 6,
message: message,
data: null
});
})
}
}
I am throwing an exception from the LocalAuthGuard file:
#Injectable()
export class LocalAuthGuard implements CanActivate {
canActivate(context: ExecutionContext,): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest().body;
if(isEmpty(request.authkey)){
return false;
}else{
return true;
}
}
}
I have just put here my sample code from the project. When I run this project by some specific URL, I am not getting messages in the specific language. I am getting the following output in my console log.
message -> message.Unauthorized
It should return the message in fr language.
Can anybody help me, where am I going wrong?
I forgot to add the path in nest-cli.json. If we put the path in that file as below then the above code perfectly works fine.
{
"collection": "#nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"assets": ["i18n/**/*","ssl/**/*"]
}
}
I have an Angular app which requires session authorization from an OIDC service. With the normal/happy path, a separate NodeJS/Express app checks for session authorization and redirects to the OIDC authorization/authentication service and attaches the relevant headers. If everything passes, the middleware routes to the Angular app.
At a point though, the Angular app runs with a token that is expired. The Angular app gets the username and at that point I could check for expiration. However, if it is expired, I need the Angular way to react to the error condition by re-routing the whole Angular app to the relevant middleware page. Because the indicator will go to a component nested within the app, I don't know how to get the little component to redirect the bigger/encompassing app.
I'm not an Angular person, so I don't even know what part of Angular to look up. Because of my lack of knowledge, I'm including source files that might or might not be relevant.
header.component.ts is where it gets the username and could return a bad token indicator
import { Component, OnInit } from '#angular/core';
import { ProfileService } from '../../../core/services/profile.service';
#Component({
selector: 'header-comp',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
userName: string = 'No Session';
constructor(private profileService: ProfileService) { }
ngOnInit() {
this.onDisplayUserLogged();
}
onDisplayUserLogged() {
this.profileService.getUsername().subscribe(data => {
this.userName = 'Welcome: ' + data;
});
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '#angular/common/http';
import { APP_BASE_HREF } from '#angular/common';
import { Router } from '#angular/router';
//Services
import { ProfileService } from './core/services/profile.service';
import { FinanceService } from './core/services/finance.service';
import { CmasService } from './core/services/cmas.service';
import { SoftlayerService } from './core/services/softlayer.service';
import { DashboardService } from './core/services/dashboard.service';
import { LowDollarExceptionService } from './core/services/lowDollarException.service';
//Components
import { AppComponent } from './app.component';
import { CmasComponent } from './modules/cmas/cmas.component';
import { SoftlayerComponent } from './modules/softlayer/softlayer.component';
import { FinanceComponent } from './modules/finance/finance.component';
import { ErrorComponent } from './modules/error/error/error.component';
import { LowDollarExceptionComponent } from './modules/lowDollarException/lowDollarException.component'
import { MenuComponent } from './shared/layout/menu/menu.component';
import { BasicComponent } from './shared/modals/basic/basic.component';
import { HeaderComponent } from './shared/layout/header/header.component';
import { PreProcessedPipe } from './shared/components/file-listing/file-listing.component';
import { ProcessedPipe } from './shared/components/softlayer-file-list/softlayer-file-list.component';
//Routing
import { AppRoutingModule } from './app-routing.module';
//Libs
import { AuthInterceptor } from 'auth-lib';
import { TermsComponent } from './modules/terms/terms.component';
import { FileListingComponent } from './shared/components/file-listing/file-listing.component';
import { ConfirmCancelComponent } from './shared/modals/confirm-cancel/confirm-cancel.component';
import { ErrorDisplayComponent } from './shared/components/error-display/error-display.component';
import { AboutComponent } from './modules/about/about.component';
import { ResultsComponent } from './modules/cmas/results/results.component';
import { SoftlayerFileListComponent } from './shared/components/softlayer-file-list/softlayer-file-list.component';
import { DashboardComponent } from './modules/dashboard/dashboard.component';
import { ReviewResultsComponent } from './modules/softlayer/review-results/review-results.component';
import { InvoiceDetailsComponent } from './modules/dashboard/invoice-details/invoice-details.component';
import { FormsModule } from '#angular/forms';
import { LowDollarNewRecordComponent } from './modules/lowDollarException/lowDollarNewRecord.component';
#NgModule({
declarations: [
AppComponent,
CmasComponent,
FinanceComponent,
ErrorComponent,
MenuComponent,
BasicComponent,
HeaderComponent,
TermsComponent,
FileListingComponent,
PreProcessedPipe,
ProcessedPipe,
ConfirmCancelComponent,
ErrorDisplayComponent,
AboutComponent,
ResultsComponent,
SoftlayerComponent,
SoftlayerFileListComponent,
DashboardComponent,
ReviewResultsComponent,
InvoiceDetailsComponent,
LowDollarExceptionComponent,
LowDollarNewRecordComponent
],
imports: [BrowserModule, HttpClientModule, AppRoutingModule, FormsModule],
providers: [
ProfileService,
FinanceService,
CmasService,
SoftlayerService,
DashboardService,
LowDollarExceptionService,
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
deps: [Router],
multi: true,
},
{ provide: APP_BASE_HREF, useValue: '/sprint-cost-recovery' },
],
bootstrap: [AppComponent],
})
export class AppModule {}
app.component.ts
import { Component, OnInit } from '#angular/core';
import { Observable } from 'rxjs';
import listadeTerms from '../assets/config/properties.json';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
constructor() {}
ngOnInit() {
this.openOverlay();
}
openOverlay() {
var sheet = document.createElement('style');
sheet.innerHTML =
'.ds-full-width {visibility: hidden;} .usabilla_live_button_container{visibility: hidden;}';
document.body.appendChild(sheet);
if (document.getElementById('termsDialog')) {
var overlayElement = document.querySelector('#termsDialog');
overlayElement.classList.add('ds-open');
document
.querySelector('#termsDialogCloseBtn')
.addEventListener('click', load);
}
function load() {
var div = document.getElementById('termsDialog');
sheet.innerHTML = '.usabilla_live_button_container{visibility: true;}';
var parent = div.parentElement;
parent.removeChild(div);
var node = sheet.parentNode;
node.removeChild(sheet);
}
}
}
app-routing.module.ts
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
// Components
import { CmasComponent } from './modules/cmas/cmas.component';
import { FinanceComponent } from './modules/finance/finance.component';
import { ErrorComponent } from './modules/error/error/error.component';
import { AboutComponent } from './modules/about/about.component';
import { SoftlayerComponent } from './modules/softlayer/softlayer.component';
import { DashboardComponent } from './modules/dashboard/dashboard.component';
import { LowDollarExceptionComponent } from './modules/lowDollarException/lowDollarException.component';
import { LowDollarNewRecordComponent } from './modules/lowDollarException/lowDollarNewRecord.component';
const appRoutes: Routes = [
{ path: 'finance', component: FinanceComponent },
{ path: 'cmas-process', component: CmasComponent },
{ path: 'about', component: AboutComponent },
{ path: 'softlayer-process', component: SoftlayerComponent },
{ path: 'cost-dashboard', component: DashboardComponent },
{ path: 'low-dollar', component: LowDollarExceptionComponent },
{ path: 'low-dollar/create', component: LowDollarNewRecordComponent },
{ path: 'error/auth', component: ErrorComponent, data: { forbidden: true } },
{ path: '', redirectTo: '/finance', pathMatch: 'full' },
{
path: 'error/badgateway',
component: ErrorComponent,
data: { badgateway: true },
},
];
#NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule],
})
export class AppRoutingModule {}
The way to achieve this in Angular is through the Route Guards. At a high level, it was like so:
Create the route guards. It returns a true or false depending on a condition it checks.
Add the canActivate parameter to the routes that need to be checked for authentication, e.g.:
const appRoutes: Routes = [
{ path: 'finance', component: FinanceComponent, canActivate: [AuthGuard] },
{ path: 'cmas-process', component: CmasComponent, canActivate: [AuthGuard] },
If the user is not authenticated, the redirect (to the login page for example) is specified in the route guard:
#Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivateChild {
constructor(
private authService: AuthService,
private logger: NGXLogger,
private router: Router
) {}
canActivateChild(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> {
return this.authService.isLoggedIn().pipe(
map(isLoggedIn => {
if (!isLoggedIn) {
return this.router.parseUrl('/login');
}
return true;
})
);
}
}
I'm trying to build this simple MEAN stack app with the simple functionality of registering, login in and then viewing the profile.
So, where does the error occur? It pops up when this newbie coder tries to log in to this simple app
Here's a screenshot of it
Here are the codes for you to see the errors that I might have made.
This is the code belonging to the login component
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '#angular/router'
import { FlashMessagesService } from 'angular2-flash-messages';
import { Observable } from 'rxjs/Rx';
import { map, subscribeOn } from 'rxjs/operators';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
username: String;
password: String;
constructor(
private authService: AuthService,
private router: Router,
private flashMessage: FlashMessagesService
) { }
ngOnInit(): void {
}
onLoginSubmit() {
console.log(this.username, this.password);
const user = {
username: this.username,
password: this.password
}
this.authService.authenticateUser(user).subscribe(data => {
console.log(data);
if (data) {
this.authService.storeUserData(data.token, data.user);
this.flashMessage.show('You are now logged in', {
cssClass: 'alert-success',
timeout: 5000
});
this.router.navigate(['/dashboard']);
}
else {
this.flashMessage.show('incorrect information you stupidass', {
cssClass: 'alert-danger',
timeout: 5000
});
this.router.navigate(['/login']);
}
});
}
}
The next one is of the authentication service file
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import { map } from 'rxjs/operators';
import { tokenNotExpired } from 'angular2-jwt';
#Injectable({
providedIn: 'root'
})
export class AuthService {
authToken: any;
user: any;
constructor(private http: Http) { }
registerUser(user: { name: String; email: String; username: String; password: String; }) {
let headers = new Headers();
//adding a value to the header and connecting to the backend
headers.append('Content-Type', 'application/json');
return this.http.post('http://localhost:3000/users/register', user, { headers: headers }).pipe(map((res: { json: any; }) => res.json));
}
authenticateUser(user: { username: String; password: String; }) {
let headers = new Headers();
//adding a value to the header and connecting to the backend
headers.append('Content-Type', 'application/json');
return this.http.post('http://localhost:3000/users/authenticate', user, { headers: headers }).pipe(map((res: { json: any; }) => res.json));
}
getProfile() {
let headers = new Headers();
this.loadToken();
headers.append('Authroization', this.authToken);
//adding a value to the header and connecting to the backend
headers.append('Content-Type', 'application/json');
return this.http.get('http://localhost:3000/users/profile', { headers: headers }).pipe(map((res: { json: any; }) => res.json));
}
storeUserData(token, user) {
localStorage.setItem('id_token', token);
localStorage.setItem('user', JSON.stringify(user));
this.authToken = token;
this.user = user;
}
loadToken() {
const token = localStorage.getItem('id_token');
this.authToken = token;
}
loggedIn() {
return tokenNotExpired(null, localStorage.getItem('id_token'));
}
logout() {
this.authToken = null;
this.user = null;
localStorage.clear();
}
}
//this.myObservable().pipe(map(data => {}))
And this last one is of the app.component file
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpModule } from '#angular/http';
import { RouterModule, Routes } from '#angular/router';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { LoginComponent } from './components/login/login.component';
import { RegisterComponent } from './components/register/register.component';
import { HomeComponent } from './components/home/home.component';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { ProfileComponent } from './components/profile/profile.component';
import { JwtModule } from '#auth0/angular-jwt';
import { FormsModule } from '#angular/forms';
import { ValidateService } from './services/Validate.service';
import { FlashMessagesModule } from 'angular2-flash-messages';
import { AuthService } from './services/auth.service';
import { AuthGuard } from './guards/auth.guard';
export function tokenGetter() {
return localStorage.getItem('access_token');
}
const appRoutes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'login', component: LoginComponent },
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
{ path: 'profile', component: ProfileComponent, canActivate: [AuthGuard] },
]
#NgModule({
declarations: [
AppComponent,
NavbarComponent,
LoginComponent,
RegisterComponent,
HomeComponent,
DashboardComponent,
ProfileComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(appRoutes),
FlashMessagesModule.forRoot(),
JwtModule.forRoot({
config: {
tokenGetter: tokenGetter,
whitelistedDomains: ['localhost:4000'],
blacklistedRoutes: ['localhost:4000/api/auth']
}
})
],
providers: [ValidateService, AuthService, AuthGuard],
bootstrap: [AppComponent]
})
export class AppModule { }
Why does this error occur?
Edit: Below are the screenshot of postman requests that I did for this app. There you can find the value of the token as well.
The authentication request is what you see here:
This next one is for the get request done to get into the profile:
I have a problem with a simple application. I already have it in production, but when I access a URL directly, I get an error:
In firefox:
In chrome:
But if I access localhost:8080, it is redirected to /home correctly:
I am using the following code:
In app.routes.ts
import { RouterModule, Routes } from '#angular/router';
import { HomeComponent } from './components/home/home.component';
import { AboutComponent } from './components/about/about.component';
import { HeroesComponent } from './components/heroes/heroes.component';
import { HeroeComponent } from './components/heroe/heroe.component';
import { BuscarComponent } from './components/buscar/buscar.component';
const ROUTES: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'heroes', component: HeroesComponent },
{ path: 'heroe/:id', component: HeroeComponent },
{ path: 'buscar/:palabra', component: BuscarComponent },
{ path: '**', pathMatch: 'full', redirectTo: 'home' }
];
export const APP_ROUTING = RouterModule.forRoot(ROUTES);
In app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { APP_ROUTING } from './app.routes';
import { HeroesService } from './servicios/heroes.service';
import { AppComponent } from './app.component';
import { NavbarComponent } from './components/shared/navbar/navbar.component';
import { HomeComponent } from './components/home/home.component';
import { AboutComponent } from './components/about/about.component';
import { HeroesComponent } from './components/heroes/heroes.component';
import { HeroeComponent } from './components/heroe/heroe.component';
import { BuscarComponent } from './components/buscar/buscar.component';
import { HeroeTarjetaComponent } from './components/heroe-tarjeta/heroe-tarjeta.component';
#NgModule({
declarations: [
AppComponent,
NavbarComponent,
HomeComponent,
AboutComponent,
HeroesComponent,
HeroeComponent,
BuscarComponent,
HeroeTarjetaComponent
],
imports: [
BrowserModule,
APP_ROUTING
],
providers: [
HeroesService
],
bootstrap: [AppComponent]
})
export class AppModule { }
I try to change { path: '**', pathMatch: 'full', redirectTo: 'home' } to { path: '', pathMatch: 'full', redirectTo: 'home' } or anything and nothing, not solve.
I tried the application with the NodeJS http-server module.