Tom
Tom

Reputation: 8681

Refreshing the angular 2 application is generating Error 404 - Page not found exception

I am developing Angular 2 application that is using KendoUI datagrid in asp.net web application. I have set index.html as the startup page. When i press F5, index.html loads. Click on the Risks Menu displays the datagrid with data that is defined in risk-list.component.html page. Its URL is localhost/risks. If I press F5, I get 404 page not found error. Could somebody tell me what the problem could be and how can I fix it?

This is my code:

risk-list.Component.ts

import { Component, OnInit } from '@angular/core';
import { Risk } from './risk';
import { RiskService } from './risk.service';

@Component({
    moduleId: module.id,
    selector: 'rm-risks',
    templateUrl: '/app/risk-list.component.html',
    providers: [RiskService]
})

export class RiskListComponent implements OnInit {
    title = 'Risk List';
     risks: Risk[];

    constructor(private _riskService: RiskService) {
        console.log(this.risks);
    }

    getRisks(): void {
        this._riskService.getRisks().then(risks => this.risks = risks);

    }

    ngOnInit(): void {
        this.getRisks();
    }
};

risk-list.component.html

<kendo-grid [data]="risks">
    <kendo-grid-column field="reference" title="Reference" width="120">
    </kendo-grid-column>
    <kendo-grid-column field="insuredName" title="Insured Name">
    </kendo-grid-column>
    <kendo-grid-column field="inceptionDate" title="Inception Date" width="230">
    </kendo-grid-column>
    <kendo-grid-column field="riskType" title="Risk Type" width="120">
    </kendo-grid-column>
    <kendo-grid-column field="Status" title="Status">
    </kendo-grid-column>
    <kendo-grid-column field="grossPremium" title="Gross Premium" width="230">
    </kendo-grid-column>
    <kendo-grid-column field="allocatedTo" title="Allocated To" width="120">
    </kendo-grid-column>
    <kendo-grid-column field="allocatedCompany" title="Allocated Company">
    </kendo-grid-column>
    <kendo-grid-column field="Discontinued" width="120">
        <template kendoCellTemplate let-dataItem>
            <input type="checkbox" [checked]="dataItem.Discontinued" disabled />
        </template>
    </kendo-grid-column>
</kendo-grid>

risk.service.ts

import { Injectable } from '@angular/core';
import { Risk } from './risk';
import { Risks } from './mock-risk';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/from';


@Injectable()
export class RiskService {

    getRisks(): Promise<Risk[]> {
        return Promise.resolve(Risks);
    }

}

risk.ts

export class Risk {
    riskId: number;
    reference: string;
    insuredName: string;
    inceptionDate: string;
    riskType: string;
    status: string;
    grossPremium: number;
    allocatedTo: string;
    allocatedCompany: string;

}

mock-risk.ts

import { Risk } from './risk'

export const Risks: Risk[] = [

    {

        "riskId": 1,
        "reference": "HISC9308336",
        "insuredName": "SA 84161",
        "inceptionDate": "March 19, 2016",
        "riskType": "Quote",
        "status": "Indication",
        "grossPremium": 100,
        "allocatedTo": "Broker User",
        "allocatedCompany": "Broker"
    },
    {

        riskId: 2,
        reference: "HISC9308337",
        insuredName: "SA 84161",
        inceptionDate: 'April 22, 2016',
        riskType: 'Quote',
        status: 'Indication',
        grossPremium: 300,
        allocatedTo: 'Broker User',
        allocatedCompany: 'Broker'
    }

];

risks.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RiskListComponent } from './risk-list.component';
import { RiskService } from './risk.service';
import { RiskRoutingModule } from './risks-routing.module';
import { GridModule } from '@progress/kendo-angular-grid';
@NgModule({
    imports: [
        CommonModule,
        FormsModule,
        RiskRoutingModule,
        GridModule

    ],
    declarations: [
        RiskListComponent
    ],
    providers: [
        RiskService
    ]
})
export class RisksModule { }

risks-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { RiskListComponent } from './risk-list.component';

@NgModule({
    imports: [
        RouterModule.forChild([
            { path: 'risks', component: RiskListComponent }
        ])
    ],
    exports: [
        RouterModule
    ]
})
export class RiskRoutingModule { }

app.component.html

<h1>Angular Router</h1>
<nav>
    <a routerLink="/risks" routerLinkActive="active">Risks</a>

</nav>
<router-outlet></router-outlet>

app.component.ts

import { Component } from '@angular/core';

    @Component({
        moduleId: module.id,
        selector: 'my-app',
        templateUrl:'/app/app.component.html'
    })
    export class AppComponent { }

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { RiskListComponent } from './risk-list.component'
import { HomeComponent } from './home.component'

@NgModule({
    imports: [
        RouterModule.forRoot([

            { path: '', component: HomeComponent }
        ])
    ],
    exports: [
        RouterModule
    ]
})
export class AppRoutingModule { }

main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

Upvotes: 3

Views: 958

Answers (3)

Surya
Surya

Reputation: 546

The best way to get rid of this Error404 page not found, you should import HashLocationStrategy to appModule.ts

When I previously worked on Angular, Same type of error raised in my Project, so that I created a simple repository for this kind of error (404 Page Not Found), it may help you. Here is the link -> AngularAppExample

Upvotes: 0

shusson
shusson

Reputation: 5772

When the browser is refreshed it will send a get request to the server with the current url, since angular is using HTML 5 style navigation, the url will make no sense to the server. Either update your server to serve the index.html on particular paths or use the HashLocationStrategy.

The benefit of using HTML 5 style navigation is that you can mix your angular app with server rendered pages.

An example of getting this working with asp.net: http://blog.johnnyreilly.com/2015/05/a-tale-of-angular-html5mode-aspnet-mvc.html

More reading on angular: https://angular.io/docs/ts/latest/guide/router.html#!#browser-url-styles

Upvotes: 0

Stefan Svrkota
Stefan Svrkota

Reputation: 50623

This problem is solved by implementing HashLocationStrategy which adds # to all your routes. For example, http://localhost/myComponent becomes http://localhost/#/myComponent. You achieve this by adding HashLocationStrategy to AppModule's providers:

{ provide: LocationStrategy, useClass: HashLocationStrategy }

Of course, you need to import LocationStrategy and HashLocationStrategy from @angular/common:

import { LocationStrategy, HashLocationStrategy } from '@angular/common';

For more information, check Angular 2 Router & Navigation - Browser URL Styles.

Upvotes: 2

Related Questions