Skip to content

Commit

Permalink
add UI full error and loading handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mucsi96 committed Jul 19, 2023
1 parent 3b118f4 commit 80cd32c
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 17 deletions.
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
- Try using WebTestClient https://docs.spring.io/spring-framework/reference/testing/webtestclient.html#webtestclient-json
- Add pgAdmin to dev container https://www.pgadmin.org/download/pgadmin-4-container/s
- fix client tests
- add logs to server services
6 changes: 5 additions & 1 deletion client/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
<app-weight *ngIf="$sync | async"></app-weight>
<app-weight *ngIf="syncState.isReady"></app-weight>

<h1 *ngIf="syncState.hasFailed">Error occured</h1>

<p *ngIf="syncState.isLoading">Loading....</p>
16 changes: 12 additions & 4 deletions client/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { subscribeToRequestState, initialHttpRequestState } from './utils';
import { WithingsService } from './withings.service';
import { HttpRequestState } from './types';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
styleUrls: ['./app.component.css'],
})
export class AppComponent {
export class AppComponent implements OnInit {
constructor(private withingsService: WithingsService) {}

$sync = this.withingsService.sync();
syncState: HttpRequestState<void> = initialHttpRequestState;

ngOnInit(): void {
subscribeToRequestState(this.withingsService.sync(), (newState) => {
this.syncState = newState;
});
}
}
12 changes: 11 additions & 1 deletion client/src/app/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
import { HttpErrorResponse } from "@angular/common/http";

export interface HttpRequestState<T> {
isLoading: boolean;
hasFailed: boolean;
isReady: boolean;
value?: T;
error?: HttpErrorResponse | Error;
}

export interface WeightResponse {
weight?: number;
}
}
29 changes: 29 additions & 0 deletions client/src/app/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Observable, catchError, map, of, startWith } from 'rxjs';
import { HttpRequestState } from './types';

export const initialHttpRequestState: HttpRequestState<any> = {
isLoading: false,
isReady: false,
hasFailed: false,
};

export function subscribeToRequestState<T>(
$target: Observable<T>,
setState: (newState: HttpRequestState<T>) => void
): void {
$target
.pipe(
map((value) => ({
isLoading: false,
isReady: true,
hasFailed: false,
value,
})),
catchError((error) => {
console.log(error);
return of({ isLoading: false, isReady: false, hasFailed: true, error });
}),
startWith({ isLoading: true, isReady: false, hasFailed: false })
)
.subscribe(setState);
}
6 changes: 5 additions & 1 deletion client/src/app/weight/weight.component.html
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
<p>{{$weight | async}}</p>
<p *ngIf="weightState.isReady">{{ weightState.value || '?' }}</p>

<h1 *ngIf="weightState.hasFailed">Error occured</h1>

<p *ngIf="weightState.isLoading">Loading....</p>
17 changes: 11 additions & 6 deletions client/src/app/weight/weight.component.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import { Component } from '@angular/core';
import { map } from 'rxjs';
import { Component, OnInit } from '@angular/core';
import { HttpRequestState } from '../types';
import { initialHttpRequestState, subscribeToRequestState } from '../utils';
import { WeightService } from '../weight.service';

@Component({
selector: 'app-weight',
templateUrl: './weight.component.html',
styleUrls: ['./weight.component.css'],
})
export class WeightComponent {
export class WeightComponent implements OnInit {
constructor(private weightService: WeightService) {}

$weight = this.weightService
.getWeight()
.pipe(map((weight) => weight?.toString() ?? '?'));
weightState: HttpRequestState<number | undefined> = initialHttpRequestState;

ngOnInit(): void {
subscribeToRequestState(this.weightService.getWeight(), newState => {
this.weightState = newState
})
}
}
7 changes: 3 additions & 4 deletions client/src/app/withings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ import { Observable, catchError, map, of } from 'rxjs';
export class WithingsService {
constructor(private http: HttpClient) {}

sync(): Observable<boolean> {
sync(): Observable<void> {
return this.http.post<void>('/api/withings/sync', undefined).pipe(
map(() => true),
catchError((error) => {
if (error instanceof HttpErrorResponse && error.status === 401) {
debugger;
window.location.href = error.error._links.oauth2Login.href;
return of();
}

return of();
throw error;
})
);
}
Expand Down

0 comments on commit 80cd32c

Please sign in to comment.