fix new travel

This commit is contained in:
Eneko Nieto
2021-02-04 03:14:39 +01:00
parent 1ffb87c90d
commit 2fb505d913
7 changed files with 78 additions and 38 deletions

View File

@@ -6,7 +6,7 @@ export class Travel {
constructor(
public id: TravelId = -1,
public driverInfo: UserInfo = null,
public travelersInfo: UserInfo[] = null,
public travelersInfo: UserInfo[] = [],
public departureDate: string = '',
public origin: string = '',
public destination: string = '',

7
src/app/entities/user.ts Normal file
View File

@@ -0,0 +1,7 @@
export type UserId = string;
export interface User {
id: UserId;
matrixId?: string;
name: string;
}

View File

@@ -9,7 +9,7 @@ import { ApiService } from '../../services/api.service';
styleUrls: ['./new-travel.component.css']
})
export class NewTravelComponent implements OnInit {
travel: Travel;
travel: Travel = new Travel();
@ViewChild(TravelFormComponent, { static: true }) form: TravelFormComponent;
@@ -17,19 +17,17 @@ export class NewTravelComponent implements OnInit {
private apiService: ApiService
) { }
ngOnInit(): void {
this.travel = new Travel();
}
ngOnInit(): void { }
createTravel(travel: Travel): void {
this.apiService.createTravel(travel)
.subscribe(res => {
if (res.success) {
console.log('Travel created');
}
else {
console.error('Error creating travel: ' + res.error);
}
});
.subscribe(res => {
if (res.success) {
console.log('Travel created');
}
else {
console.error('Error creating travel: ' + res.error);
}
});
}
}

View File

@@ -4,8 +4,9 @@ import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { ApiResponse } from '../entities/api-response';
import { Travel, TravelId } from '../entities/travel';
import { PUBLIC_API_URL, TRAVEL_API_URL } from '../app.config';
import { PUBLIC_API_URL, TRAVEL_API_URL, USER_API_URL } from '../app.config';
import { ListDto } from '../entities/list-dto';
import { User } from '../entities/user';
export type ApiCall<T> = (params?: { [param: string]: any }) => (Observable<ApiResponse<ListDto<T>>>);
@@ -13,11 +14,15 @@ export type ApiCall<T> = (params?: { [param: string]: any }) => (Observable<ApiR
providedIn: 'root',
})
export class ApiService {
constructor(private http: HttpClient) {}
constructor(private http: HttpClient) { }
// Las llamadas al API son arrow-functions para capturar el parámetro this en la definición
// y no en la ejecución.
getUser = () => {
return this.callApi<User>(USER_API_URL + '/user');
}
getTravel = (travelId: TravelId) => {
return this.callApi<Travel>(PUBLIC_API_URL + '/travel', { travelId });
}
@@ -31,16 +36,29 @@ export class ApiService {
}
createTravel = (travel: Travel) => {
return this.callApi<void>(TRAVEL_API_URL + '/create', { travel });
return this.callApi<void>(TRAVEL_API_URL + '/create', null, travel);
}
private callApi<T>(
url: string,
params?: { [param: string]: any }
params?: { [param: string]: any },
body?: any
): Observable<ApiResponse<T>> {
return this.http
.get<ApiResponse<T>>(url, { params })
.pipe(
console.log('ApiService.callApi(): url=' + url);
if (params) {
console.log('Params=');
console.log(params);
}
if (body) {
console.log('Body=');
console.log(body);
}
const response$ = body ?
this.http.post<ApiResponse<T>>(url, body, { params }) :
this.http.get<ApiResponse<T>>(url, { params });
return response$.pipe(
retry(0), // retry a failed request up to 3 times
catchError(this.handleError) // then handle the error
);
@@ -49,12 +67,12 @@ export class ApiService {
private handleError(error: HttpErrorResponse): Observable<never> {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
console.error('ApiService: A client error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong.
console.error(
`API returned code ${error.status}, ` + `body was: ${error.error}`
`ApiService: API returned code ${error.status}, ` + `body was: ${error.error}`
);
}
// Return an observable with a user-facing error message.

View File

@@ -1,5 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
import { ApiService } from 'src/app/services/api.service';
import { authConfig } from '../../auth.config';
@Component({
@@ -8,17 +9,33 @@ import { authConfig } from '../../auth.config';
styleUrls: ['./header.component.css'],
})
export class HeaderComponent implements OnInit {
constructor(private oauthService: OAuthService) { }
constructor(
private oauthService: OAuthService,
private apiService: ApiService
) { }
ngOnInit(): void {
this.oauthService.configure(authConfig);
this.oauthService.loadDiscoveryDocumentAndTryLogin().then(success => {
console.log('Autologin success=' + success + ' logged=' + String(this.logged));
console.log('USER autologin');
if (this.logged) {
this.apiService.getUser().subscribe(user => {
console.log(user);
});
}
});
}
async login(): Promise<void> {
this.oauthService.loadDiscoveryDocumentAndLogin();
this.oauthService.loadDiscoveryDocumentAndLogin().then(success => {
console.log('USER login');
if (this.logged) {
this.apiService.getUser().subscribe(user => {
console.log(user);
});
}
});
}
logout(): void {

View File

@@ -2,44 +2,42 @@
<div>
<label for="departureDate">Fecha de salida</label>
<input matInput id="departureDate" name="departureDate" [ngxMatDatetimePicker]="picker"
placeholder="Choose a date" [min]="minDate" [(ngModel)]="travel.departureDate" #departureDate="ngModel">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker [showSeconds]="false" [stepMinute]="15">
placeholder="Choose a date" [min]="minDate" [(ngModel)]="newTravel.departureDate">
<mat-datepicker-toggle matSuffix [for]="$any(picker)"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker [showSeconds]="$any('false')" [stepMinute]="$any('15')">
</ngx-mat-datetime-picker>
<div [hidden]="departureDate.valid || departureDate.pristine" class="alert alert-danger">
<div hidden="departureDate.valid || departureDate.pristine" class="alert alert-danger">
La fecha es obligatoria
</div>
</div>
<div>
<label for="origin">Origen</label>
<input type="text" id="origin" required [(ngModel)]="travel.origin" name="origin" #origin="ngModel">
<div [hidden]="origin.valid || origin.pristine" class="alert alert-danger">
<input type="text" id="origin" required [(ngModel)]="newTravel.origin" name="origin">
<div hidden="origin.valid || origin.pristine" class="alert alert-danger">
El origen es obligatorio
</div>
</div>
<div>
<label for="destination">Destino</label>
<input type="text" id="destination" required [(ngModel)]="travel.destination" name="destination"
#destination="ngModel">
<div [hidden]="destination.valid || destination.pristine" class="alert alert-danger">
<input type="text" id="destination" required [(ngModel)]="newTravel.destination" name="destination">
<div hidden="destination.valid || destination.pristine" class="alert alert-danger">
El destino es obligatorio
</div>
</div>
<div>
<label for="places">Plazas</label>
<input type="number" id="places" required [(ngModel)]="travel.places" name="places" #places="ngModel">
<div [hidden]="places.valid || places.pristine" class="alert alert-danger">
<input type="number" id="places" required [(ngModel)]="newTravel.places" name="places">
<div hidden="places.valid || places.pristine" class="alert alert-danger">
El destino es obligatorio
</div>
</div>
<div>
<label for="description">Descripción</label>
<input type="text" id="description" required [(ngModel)]="travel.description" name="description"
#description="ngModel">
<input type="text" id="description" [(ngModel)]="newTravel.description" name="description">
</div>

View File

@@ -10,16 +10,18 @@ export class TravelFormComponent implements OnInit {
@Output() travelSubmitted: EventEmitter<Travel> = new EventEmitter();
@Input() travel: Travel;
newTravel: Travel;
submitted = false;
minDate = new Date();
constructor() { }
ngOnInit(): void {
this.newTravel = { ...this.travel };
}
onSubmit(): void {
this.submitted = true;
this.travelSubmitted.emit(this.travel);
this.travelSubmitted.emit(this.newTravel);
}
}