Add HttpClient
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -4,7 +4,7 @@
|
||||
"configurations": [
|
||||
{
|
||||
"name": "ng serve",
|
||||
"type": "chrome",
|
||||
"type": "msedge",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "npm: start",
|
||||
"url": "http://localhost:4200/"
|
||||
|
||||
28
package-lock.json
generated
28
package-lock.json
generated
@@ -3947,9 +3947,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.25.2",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.2.tgz",
|
||||
"integrity": "sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==",
|
||||
"version": "4.25.3",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.3.tgz",
|
||||
"integrity": "sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -3967,8 +3967,8 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30001733",
|
||||
"electron-to-chromium": "^1.5.199",
|
||||
"caniuse-lite": "^1.0.30001735",
|
||||
"electron-to-chromium": "^1.5.204",
|
||||
"node-releases": "^2.0.19",
|
||||
"update-browserslist-db": "^1.1.3"
|
||||
},
|
||||
@@ -4708,9 +4708,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.203",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.203.tgz",
|
||||
"integrity": "sha512-uz4i0vLhfm6dLZWbz/iH88KNDV+ivj5+2SA+utpgjKaj9Q0iDLuwk6Idhe9BTxciHudyx6IvTvijhkPvFGUQ0g==",
|
||||
"version": "1.5.204",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.204.tgz",
|
||||
"integrity": "sha512-s9VbBXWxfDrl67PlO4avwh0/GU2vcwx8Fph3wlR8LJl7ySGYId59EFE17VWVcuC3sLWNPENm6Z/uGqKbkPCcXA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@@ -5013,9 +5013,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eventsource-parser": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.3.tgz",
|
||||
"integrity": "sha512-nVpZkTMM9rF6AQ9gPJpFsNAMt48wIzB5TQgiTLdHiuO8XEDhUgZEhqKlZWXbIzo9VmJ/HvysHqEaVeD5v9TPvA==",
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.5.tgz",
|
||||
"integrity": "sha512-bSRG85ZrMdmWtm7qkF9He9TNRzc/Bm99gEJMaQoHJ9E6Kv9QBbsldh2oMj7iXmYNEAVvNgvv5vPorG6W+XtBhQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -5930,9 +5930,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/istanbul-reports": {
|
||||
"version": "3.1.7",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
|
||||
"integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
|
||||
"integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZonelessChangeDetection } from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
|
||||
import { routes } from './app.routes';
|
||||
import { routes } from './app.routes'; // Ensure this matches the export in app.routes.ts
|
||||
import { provideClientHydration, withEventReplay } from '@angular/platform-browser';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideBrowserGlobalErrorListeners(),
|
||||
provideZonelessChangeDetection(),
|
||||
provideRouter(routes), provideClientHydration(withEventReplay())
|
||||
provideRouter(routes),
|
||||
provideClientHydration(withEventReplay())
|
||||
]
|
||||
};
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { HomepageComponent } from './features/homepage/homepage.component';
|
||||
|
||||
export const routes: Routes = [];
|
||||
export const routes: Routes = [
|
||||
{ path: '', component: HomepageComponent },
|
||||
// Add other routes here
|
||||
];
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Component, signal } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
standalone: true,
|
||||
imports: [RouterOutlet],
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css'
|
||||
template: `<router-outlet></router-outlet>`,
|
||||
styleUrls: ['./app.css']
|
||||
})
|
||||
export class App {
|
||||
protected readonly title = signal('insurance-fe');
|
||||
protected readonly title = 'insurance-fe';
|
||||
}
|
||||
|
||||
11
src/app/features/homepage/homepage.component.css
Normal file
11
src/app/features/homepage/homepage.component.css
Normal file
@@ -0,0 +1,11 @@
|
||||
.card-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin: 10px;
|
||||
padding: 20px;
|
||||
border: 1px solid #ccc;
|
||||
cursor: pointer;
|
||||
}
|
||||
6
src/app/features/homepage/homepage.component.html
Normal file
6
src/app/features/homepage/homepage.component.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<div>Homepage Component Loaded</div>
|
||||
<div *ngFor="let card of cards" class="card">
|
||||
<h2>{{ card.title }}</h2>
|
||||
<p>{{ card.description }}</p>
|
||||
<button (click)="navigate(card.link)">View Details</button>
|
||||
</div>
|
||||
52
src/app/features/homepage/homepage.component.ts
Normal file
52
src/app/features/homepage/homepage.component.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Router } from '@angular/router';
|
||||
import { InsuranceService } from '../../shared/services/insurance.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
interface Card {
|
||||
title: string;
|
||||
description: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-homepage',
|
||||
standalone: true,
|
||||
imports: [CommonModule], // Remove HttpClientModule here
|
||||
templateUrl: './homepage.component.html',
|
||||
styleUrls: ['./homepage.component.css']
|
||||
})
|
||||
export class HomepageComponent implements OnInit {
|
||||
cards: Card[] = [];
|
||||
|
||||
constructor(private router: Router, private insuranceService: InsuranceService) {
|
||||
console.log('HomepageComponent constructor');
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
console.log('HomepageComponent ngOnInit');
|
||||
this.fetchInsurances();
|
||||
}
|
||||
|
||||
fetchInsurances() {
|
||||
console.log('Fetching insurances');
|
||||
this.insuranceService.getInsurances().subscribe(
|
||||
insurances => {
|
||||
console.log('Insurances fetched:', insurances);
|
||||
this.cards = insurances.map(insurance => ({
|
||||
title: insurance.name,
|
||||
description: `Category: ${insurance.category}, Price: $${insurance.price}`,
|
||||
link: `/insurance/${insurance.id}`
|
||||
}));
|
||||
},
|
||||
error => {
|
||||
console.error('Error fetching insurances:', error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
navigate(link: string) {
|
||||
this.router.navigate([link]);
|
||||
}
|
||||
}
|
||||
0
src/app/features/homepage/homepage.module.ts
Normal file
0
src/app/features/homepage/homepage.module.ts
Normal file
62
src/app/shared/services/insurance.service.spec.ts
Normal file
62
src/app/shared/services/insurance.service.spec.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { InsuranceService } from './insurance.service';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { provideHttpClientTesting, HttpTestingController } from '@angular/common/http/testing';
|
||||
|
||||
describe('InsuranceService', () => {
|
||||
let service: InsuranceService;
|
||||
let httpTestingController: HttpTestingController;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
providers: [
|
||||
InsuranceService,
|
||||
provideHttpClient(),
|
||||
provideHttpClientTesting(),
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
service = TestBed.inject(InsuranceService);
|
||||
httpTestingController = TestBed.inject(HttpTestingController);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Ensure that there are no outstanding requests
|
||||
httpTestingController.verify();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return expected insurances (HttpClient called once)', () => {
|
||||
const expectedInsurances = [
|
||||
{ id: 1, name: 'Comprehensive Health Plan', category: 'Health', price: 1200.0 },
|
||||
{ id: 2, name: 'Standard Auto Coverage', category: 'Auto', price: 800.0 },
|
||||
];
|
||||
|
||||
service.getInsurances().subscribe(insurances => {
|
||||
expect(insurances).toEqual(expectedInsurances);
|
||||
});
|
||||
|
||||
const req = httpTestingController.expectOne('https://your-api-url.com/insurances');
|
||||
expect(req.request.method).toEqual('GET');
|
||||
|
||||
req.flush(expectedInsurances);
|
||||
});
|
||||
|
||||
// it('should return expected insurance by ID (HttpClient called once)', () => {
|
||||
// const expectedInsurance = { id: 1, name: 'Comprehensive Health Plan', category: 'Health', price: 1200.0 };
|
||||
|
||||
// service.getInsuranceById(1).subscribe(insurance => {
|
||||
// expect(insurance).toEqual(expectedInsurance);
|
||||
// });
|
||||
|
||||
// const req = httpTestingController.expectOne('https://your-api-url.com/insurances/1');
|
||||
// expect(req.request.method).toEqual('GET');
|
||||
|
||||
// req.flush(expectedInsurance);
|
||||
// });
|
||||
|
||||
// Add more tests for other methods and scenarios as needed
|
||||
});
|
||||
31
src/app/shared/services/insurance.service.ts
Normal file
31
src/app/shared/services/insurance.service.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
|
||||
interface Insurance {
|
||||
id: number;
|
||||
name: string;
|
||||
category: string;
|
||||
price: number;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root' // Use 'root' to make the service available globally
|
||||
})
|
||||
export class InsuranceService {
|
||||
private apiUrl = 'http://localhost:1204/api/insurance';
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
getInsurances(): Observable<Insurance[]> {
|
||||
return this.http.post<Insurance[]>(`${this.apiUrl}/all`, {}).pipe(
|
||||
catchError(this.handleError)
|
||||
);
|
||||
}
|
||||
|
||||
private handleError(error: HttpErrorResponse) {
|
||||
console.error('An error occurred:', error.message);
|
||||
return throwError('Something went wrong; please try again later.');
|
||||
}
|
||||
}
|
||||
14
src/main.ts
14
src/main.ts
@@ -1,6 +1,12 @@
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { appConfig } from './app/app.config';
|
||||
import { App } from './app/app';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { provideHttpClient } from '@angular/common/http'; // Import provideHttpClient
|
||||
import { HomepageComponent } from './app/features/homepage/homepage.component';
|
||||
import { routes } from './app/app.routes'; // Adjust the path to your routes file
|
||||
|
||||
bootstrapApplication(App, appConfig)
|
||||
.catch((err) => console.error(err));
|
||||
bootstrapApplication(HomepageComponent, {
|
||||
providers: [
|
||||
provideRouter(routes),
|
||||
provideHttpClient(), // Use provideHttpClient to provide HttpClient
|
||||
],
|
||||
}).catch(err => console.error(err));
|
||||
|
||||
Reference in New Issue
Block a user