Routing error with angular 2 and IIS [duplicate] - javascript

I'm trying to create an application with hash location strategy, but it does not add the hash to the url. For instance when I click on a button associated with { path: '/polls', name: 'Polls', component: PollsComponent } it loads the page with this url : localhost:3000/polls.
What do I have to change to get the hash location strategy?
Why do I have to set the default base url if I want to use hash location strategy?
This is the routing in the app.component.ts where all the routing is defined:
import {Component} from 'angular2/core'
import {HTTP_PROVIDERS, Http} from 'angular2/http';
import 'rxjs/Rx'; // load the full rxjs
import {ROUTER_PROVIDERS, RouteConfig , ROUTER_DIRECTIVES} from 'angular2/router';
import { ResultsComponent } from './results/results.component'
import { VotingCardsComponent } from './votingcards/votingcards.component'
import { DashBoardComponent } from './dash/dash.component'
import { PollsComponent } from './pollslist/pollslist.component'
#Component({
selector: 'my-app',
templateUrl: 'app/app.component.html',
directives: [ROUTER_DIRECTIVES, ResultsComponent, VotingCardsComponent, DashBoardComponent],
providers: [HTTP_PROVIDERS,
ROUTER_PROVIDERS]
})
#RouteConfig([
{ path: '/vote', name: 'VotePage', component: VotingCardsComponent },
{ path: '/votepoll/:id', name: 'VotePoll', component: VotingCardsComponent },
{ path: '/results', name: 'Results', component: ResultsComponent },
{ path: '/polls', name: 'Polls', component: PollsComponent },
{ path: '/', name: 'DashBoard', component: DashBoardComponent, useAsDefault: true }
])
export class AppComponent { }
And this is my main.ts where I configure the base url:
import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';
//this is to avoid the href empty issue
import {provide} from 'angular2/core';
import {APP_BASE_HREF, ROUTER_PROVIDERS} from 'angular2/router';
bootstrap(AppComponent, [
//this is to avoid the href empty issue
ROUTER_PROVIDERS,
provide(LocationStrategy, { useClass: HashLocationStrategy }),
provide(APP_BASE_HREF, { useValue: '/' })
]);

You can use the option "useHash" in RouterModule.forRoot().
RouterModule.forRoot(appRoutes, {useHash: true});
https://discuss.atom.io/t/angular-2-routes-breaking-on-electron-app-refresh/28370/4

ROUTER_PROVIDERS should not be added to child components,
only to
providers: [ROUTER_PROVIDERS]
or alternatively only to
bootstrap(AppComponent, [ROUTER_PROVIDERS]);
HTTP_PROVIDERS are in my opinion also a better fit for root component or bootstrap() but it doesn't break anything to add them somewhere else.
(See also Routing error with angular 2 and IIS)

Everything worked fine with the sample code OP posted as with what is in the accepted answer. But as a minor note, the format required to changing the Hash Location Strategy in the bootstrap file as of RC.4 goes like this:
{ provide: LocationStrategy, useClass: HashLocationStrategy },

It is recommended to use the HTML 5 style (PathLocationStrategy) as location strategy in Angular
Because
It produces the clean and SEO Friendly URLs that are easier for users
to understand and remember.
You can take advantage of the server-side rendering, which will make
our application load faster, by rendering the pages in the server
first before delivering it the client.
Use Hashlocationstrtegy only if you have to support the older
browsers.
Click Here for More info

Related

'<selector>' is not a known element

Before I continue with the question: I have checked the other questions with the same title and I have followed given advices. None of it helped so I decided to open a new question.
I have angular project with one module and multiple components. Dashboard component uses welcome component that is apparently not recognized.
The module has the following code:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { HomeComponent } from './home/home.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { FrameComponent } from './frame/frame.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { CardComponent } from './card/card.component';
import { AlertComponent } from './alert/alert.component';
#NgModule({
declarations: [
FrameComponent,
HomeComponent,
CardComponent,
WelcomeComponent,
AlertComponent
],
imports: [
BrowserModule,
RouterModule.forRoot([
{
path: '',
component: HomeComponent
},
{
path: 'dashboard',
component: DashboardComponent
}
])
],
exports: [CardComponent, WelcomeComponent, AlertComponent],
providers: [],
bootstrap: [FrameComponent]
})
export class AppModule { }
As you can see, I have imported WelcomeComponent, declared it and exported it.
WelcomeComponent contains the following code:
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-welcome',
templateUrl: './welcome.component.html',
styleUrls: ['./welcome.component.css']
})
export class WelcomeComponent implements OnInit {
#Input()
message: string;
welcomeMessage: string;
constructor() { }
ngOnInit(): void {
}
}
Here you can see app-welcome as a selector. It appears to be connected correctly. But when I use it in dashboard.component.html as given from the example
<app-welcome [message]="message" [welcomeMessage]="welcomeMessage"></app-welcome>
I get the following error:
Error: src/app/dashboard/dashboard.component.html:18:5 - error NG8001: 'app-welcome' is not a known element:
1. If 'app-welcome' is an Angular component, then verify that it is part of this module.
2. If 'app-welcome' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
Other errors are related to welcome and welcomeMessage not existing since component is not recognized.
I tried restarting server, running it as --prod. I tried everything that I found. Does anyone know what could this cause?
Dashboard component is not declared in your AppModule, that's the problem.
Also you don't need to export the components in that case, just declare them.

Why Angular always redirecting to main page?

Always I trying to GET '/' it shows static-root-component (component of my main page),
but when it is '/welcome' page immediately redirecting to '/' and also loading static-root-component instead of welcome-component
Initially I wanted to redirect users to welcome page if they aren't authorized, but login status only can be checked within JavaScript. After JS got info about login status it decides to redirect using location.replace("/welcome"), but... Angular again goes to '/'
"Funny" fact: there isn't any routing problems during debug with ng serve but it always happens with ng build
I don't know what's gone wrong and there is app.module.ts:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { StaticRootComponent } from './static-root/static-root.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { HttpClientModule } from '#angular/common/http';
import { HttpService } from './http.service';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
const appRoute: Routes = [
{ path: '', component: StaticRootComponent, pathMatch: 'full' },
{ path: 'welcome', component: WelcomeComponent }
];
#NgModule({
declarations: [
AppComponent,
StaticRootComponent,
WelcomeComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
RouterModule.forRoot(appRoute),
HttpClientModule
],
providers: [HttpService],
bootstrap: [AppComponent]
})
export class AppModule { }
I can drop any other Angular file if needed
In your code, change like below
const appRoute: Routes = [
{ path: '', component: StaticRootComponent },
{ path: 'welcome', component: WelcomeComponent },
{ path: '**', redirectTo: '' }
];
In the component file, inject this like below
import { Router } from '#angular/router';
constructor(
private router: Router
) {}
When you want do navigation use the below code instead of location.replace("/welcome")
this.router.navigate(['/welcome']);
Check the Module you trying to instantiate in the constructor of the Component linked to the Routing Path you are trying to access
In this case:
Our Component: example.component.ts
Our Module: HttpClientModule that contains HttpClient
Our Routing Path: "/example"
and make sure that Module is already existing in the app.module.ts , here is an example:
example.component.ts
import {HttpClient} from '#angular/common/http'; //child of HttpClientModule
#Component({selector: 'app-example',templateUrl: './example.component.html', styleUrls: ['./example.component.css']})
export class ExampleComponent{
constructor(private httpClient: HttpClient) { }
}
now let's see both examples of app module with and without the Module import and see the difference
app.module.ts
Without including HttpClientModule in imports array
import { AppComponent } from './app.component';
#NgModule({
declarations: [...],
imports: [BrowserModule,...],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
In this case loading the "/example" path will redirect you to the main page path which is usually "/" and that's because example.component.ts is using HttpClient (child of HttpClientModule) but not finding it in app.module.ts .
app.module.ts
Including HttpClientModule in imports array
import { AppComponent } from './app.component';
import { HttpClientModule} from '#angular/common/http'; //Import that module you willing to use
#NgModule({
declarations: [...],
imports: [BrowserModule,HttpClientModule,...], //add the module we currently using
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
In this case loading the "/example" path will work properly since we added the required module in app.module.ts.
If that's your case that would definitely fix your problem unless you have something else forcing the redirection to home page "index.html" or any other path, else if that didn't fix your problem read the following notes:
Make sure to check there are no redirections in the app-routing.module.ts routes array like this
const routes: Routes = [
{path: 'example', component: ExampleComponent},
{ path: '/example', redirectTo: '' }
];
it should only be like so
const routes: Routes = [
{path: 'example', component: ExampleComponent}
];
Also make sure there is no routing behaviour causing the redirection like #angular/router through something like this.router.navigate(['/'])
PS: SAME ISSUE COULD IMPLY IF YOU USING A SERVICE THAT'S USING A MODULE WHICH IS NOT ADDED TO MODULE IMPORTS IN app.module.ts
My project based on MEAN (Mongo, Express, Angular and NODEJS)... The last was a source of problem
#Shakthifuture, you said you want to see full code and I started answering:
"What you wanna to see else? My data and server files doesn't affec..."
and I've starting think "what if affect?": routing in whole of project works by Angular, but all new connection to the site pass NodeJS and Express, so I forgot about 404 case...
THE PROBLEM:
In server script file index.js of project's root folder a long time ago I've added code about what to do if entered path not found:
app.use(function (req, res, next) {
res.redirect('/');
// IF 404 NOT FOUND
});
and above of it something like:
app.get('/', function (req, res) {
res.sendFile(`${__dirname}/angular/index.html`)
});
// send index if path is '/'
but nothing for '/welcome', that's why redirecting happens
THE SOLUTION:
let's add the '/welcome' handler:
app.get('/welcome', function (req, res) {
res.sendFile(`${__dirname}/angular/index.html`)
});
(again index.html due to SPA)

How to route between modules in angular2?

I am using angular2 Final for development.
I have created 3 modules.
AppModule
ProjectModule
DesignerModule
Previously I had only AppModule,In Which I had imported following RoutingModule & it worked fine.
import {NgModule} from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import {ProjectManagerComponent} from './project-manager/project-manager.component';
import {DesignerComponent} from './designer/designer.component';
const appRoutes: Routes = [
{path: '',redirectTo: 'project-manager',pathMatch: 'full'},
{ path: 'project-manager', component: ProjectManagerComponent },
{ path: 'designer/:id', component:DesignerComponent }
];
#NgModule({
imports:[RouterModule.forRoot(appRoutes)],
exports:[RouterModule]
})
export class AppRoutingModule { }
export const routingComponents=[ProjectManagerComponent,DesignerComponent]
But recently I have created separate NgModules for ProjectManager & Designer.
I have kept ProjectManagerComponent,DesignerComponent inside declarations in their respective modules.
I want to know if it is possible to route to these modules using same routing configuration or do I need to change something.
My Routing is not working anymore.
any inputs?
instead of
export const routingComponents=[ProjectManagerComponent,DesignerComponent]
you can just
export const routing = RouterModule.forRoot(appRoutes);
Since you app.module.ts already knows about ProjectManagerComponent and DesignerComponent from their respective modules. All that is left is to teach it where to go and find them.
Inside of your app.module.ts you would have
// All the other imports
import {routing} from './app.routes;'
#NgModule({
imports:[routing, /*Other Modules*/],
})

Conditional routing change default route in Angular 2

I'm creating an app that when the user enters to the page he goes to the default route wich is "Login" page. What I want is based on a condition (if the user has a local storage variable id, a method called isAuthenticaded() returns true if not false) the user must see the "Polls" page instead of "Login" page.
I think two different ways to aprouch this:
1- Change default page: if the method returns true the default page should be "Polls" if not "Login".
2- Redirect the user: if the method returns true the user is redirected to "Polls".
What's the best aprouch to archieve this?
How can I do one or both of the point to get conditional routing?
This is my routing config with the isAuthenticated() method:
import {Component} from 'angular2/core'
import {HTTP_PROVIDERS, Http} from 'angular2/http';
import 'rxjs/Rx'; // load the full rxjs
import {RouteConfig, ROUTER_DIRECTIVES, Router} from 'angular2/router';
import { PollsComponent } from './pollslist/pollslist.component'
import { Login } from './login/login'
#Component({
selector: 'my-app',
templateUrl: 'app/app.component.html',
directives: [ROUTER_DIRECTIVES, Login, PollsComponent],
providers: [HTTP_PROVIDERS]
})
#RouteConfig([
{ path: '/login', name: 'Login', component: Login, useAsDefault: true },
{ path: '/polls', name: 'Polls', component: PollsComponent }
])
export class AppComponent {
isAuthenticated() {
if (localStorage.getItem('id')) {
return true;
} else {
return false;
}
}
}
You can check in
#CanActivate() and navigate to a different route using router.navigate()
or create a custom <router-outlet> where you do this.
For details see https://medium.com/#blacksonic86/authentication-in-angular-2-958052c64492#.f76jyafdn
See also Check if the user logged in on any page change in Angular 2
Router definition has loader parameter:
loader : () => Promise<Type>
that allows to determine component type dynamically and async.

Angular 2 - Is it possible to store my routes in another file and import them into the app.ts file (because over time the routes will build up)?

Angular 2 - Is it possible to store my routes in another file and import them into the app.ts file (because over time the routes will build up)
Here is an example of my current app.ts that works. I basically want to move the route config routes to another file to make it cleaner:
import {Todo} from './components/todo/todo';
import {About} from './components/about/about';
import {AuthService} from './authService';
import {Component, View, bootstrap, bind, provide} from 'angular2/angular2';
import {Router, ROUTER_BINDINGS, RouterOutlet, RouteConfig, RouterLink, ROUTER_PROVIDERS, APP_BASE_HREF} from 'angular2/router';
import {Location, LocationStrategy, HashLocationStrategy} from 'angular2/router';
#Component({
selector: 'app'
})
#View({
template: `
<div class="container">
<nav>
<ul>
<li><a [router-link]="['/Home']">Todo</a></li>
<li><a [router-link]="['/About']">About</a></li>
</ul>
</nav>
<router-outlet></router-outlet>
</div>
`,
directives: [RouterOutlet, RouterLink]
})
#RouteConfig([
{ path: '/', redirectTo: '/home' },
{ path: '/home', component: Todo, as: 'Home' },
{ path: '/about', component: About, as: 'About' }
])
export class AppComponent {
constructor(router: Router, _authService: AuthService, _location: Location){
//Subscribe - watches routes pop state events.
router.subscribe((val) => {
_authService.isUserLoggedIn().then((success) => {
router.parent.navigate(['/About']);
});
})
}
}
bootstrap(AppComponent, [ROUTER_PROVIDERS, provide(APP_BASE_HREF, {useValue: '/'}), AuthService]);
i personally have created an route.interface.ts and a route.ts files.
Routes file
import {Route} from './route.interface'
import {AuthComponent} from './auth/auth.component'
export const Routes: Route[] = [
{
path: '/auth',
name: 'Authenticate',
component: AuthComponent
},
];
Route Interface
export interface Route {
path: string,
name: string,
component: any,
}
Usage in main component.
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router'
import {Routes} from './routes'
#Component({
selector: 'app',
templateUrl: './angular2/app/layout.component.html',
directives: [
ROUTER_DIRECTIVES
],
providers: [
HTTP_PROVIDERS,
ROUTER_PROVIDERS
],
})
#RouteConfig(Routes)
Hope that helps. you can even create a route service and inject it you main component. Enjoy coding!
You can add your RouteConfig per component
Lets say you have home and about as in your example, then you would define the routing from that specific component in the component itself.
So in your about component you can add
// './components/about/about'
#RouteConfig([
{ path: '/about', component: About, as: 'About' }
])
And in your home component you can do the same
// './components/home/home'
#RouteConfig([
{ path: '/home', component: Todo, as: 'Home' }
])

Categories