Caches records locally if connection to backend fails
This commit is contained in:
parent
25c999d7f2
commit
1a7c551dfa
|
@ -21,14 +21,16 @@ import {AppComponent} from './app.component';
|
|||
import {CountComponent} from './count/count.component';
|
||||
import {FooterComponent} from './footer/footer.component';
|
||||
import {HomeComponent} from './home/home.component';
|
||||
import {LabelLayoutComponent} from './label-layout/label-layout.component';
|
||||
import {LoadingComponent} from './loading/loading.component';
|
||||
import {NavbarComponent} from './navbar/navbar.component';
|
||||
import {PrintLayoutComponent} from './print-layout/print-layout.component';
|
||||
import {PrintComponent} from './print/print.component';
|
||||
import {SampleComponent} from './sample/sample.component';
|
||||
import {ApiService} from './services/api.service';
|
||||
import {CacheService} from './services/cache.service';
|
||||
import {SettingsService} from './services/settings.service';
|
||||
import {SettingsComponent} from './settings/settings.component';
|
||||
import { LabelLayoutComponent } from './label-layout/label-layout.component';
|
||||
import { PrintLayoutComponent } from './print-layout/print-layout.component';
|
||||
|
||||
/**
|
||||
* This function is used internal to get a string instance of the `<base href="" />` value from `index.html`.
|
||||
|
@ -48,16 +50,16 @@ export function getBaseHref(platformLocation: PlatformLocation): string {
|
|||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
LoadingComponent,
|
||||
FooterComponent,
|
||||
NavbarComponent,
|
||||
HomeComponent,
|
||||
SampleComponent,
|
||||
CountComponent,
|
||||
SettingsComponent,
|
||||
PrintComponent,
|
||||
FooterComponent,
|
||||
HomeComponent,
|
||||
LabelLayoutComponent,
|
||||
LoadingComponent,
|
||||
NavbarComponent,
|
||||
PrintComponent,
|
||||
PrintLayoutComponent,
|
||||
SampleComponent,
|
||||
SettingsComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
|
@ -65,25 +67,26 @@ export function getBaseHref(platformLocation: PlatformLocation): string {
|
|||
FormlyModule,
|
||||
FormsModule,
|
||||
HttpClientModule,
|
||||
MatProgressSpinnerModule,
|
||||
ReactiveFormsModule,
|
||||
MatCardModule,
|
||||
MatInputModule,
|
||||
MatToolbarModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatCardModule,
|
||||
MatFormFieldModule,
|
||||
QRCodeSVGModule,
|
||||
AppRoutingModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatOptionModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatSelectModule,
|
||||
// <-- This line MUST be last (https://angular.io/guide/router#module-import-order-matters)
|
||||
MatToolbarModule,
|
||||
QRCodeSVGModule,
|
||||
ReactiveFormsModule,
|
||||
AppRoutingModule, // <-- This line MUST be last (https://angular.io/guide/router#module-import-order-matters)
|
||||
],
|
||||
providers: [
|
||||
{provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: {appearance: 'outline'}},
|
||||
ApiService,
|
||||
CacheService,
|
||||
SettingsService,
|
||||
{provide: 'APP_ENVIRONMENT', useClass: ThisEnvironment},
|
||||
{provide: APP_BASE_HREF, useFactory: getBaseHref, deps: [PlatformLocation]},
|
||||
{provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: {appearance: 'outline'}},
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
entryComponents: []
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {ApiService} from '../services/api.service';
|
||||
import {CacheService} from '../services/cache.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
|
@ -7,9 +9,33 @@ import { Component, OnInit } from '@angular/core';
|
|||
})
|
||||
export class HomeComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
constructor(
|
||||
private cacheService: CacheService,
|
||||
private apiService: ApiService,
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
const cachedRecords = this.cacheService.getRecords();
|
||||
let numSuccess = 0;
|
||||
if (cachedRecords && cachedRecords.length > 0) {
|
||||
cachedRecords.forEach(r => {
|
||||
this.apiService.addSample(r).subscribe(() => {
|
||||
numSuccess++;
|
||||
console.log('cachedRecords', cachedRecords);
|
||||
console.log('numSuccess', numSuccess);
|
||||
|
||||
if (numSuccess === cachedRecords.length) {
|
||||
console.log('Cache cleared.');
|
||||
this.cacheService.clearCache();
|
||||
}
|
||||
}, error => {
|
||||
console.log('Cannot connect to server. Cache not cleared.');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.log('No cached records to upload.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<mat-toolbar color="primary">
|
||||
<mat-toolbar-row>
|
||||
<button id="nav_logo" mat-button routerLink="/" class="logo">BeSAFE</button>
|
||||
<button id="nav_location" mat-button routerLink="/settings">{{testingLocation ? testingLocation.name : 'No location found'}} ({{locationId}})</button>
|
||||
<button id="nav_location" mat-button routerLink="/settings">{{locationId === '0000' ? 'Click here to set location' : 'Location: ' + locationId}}</button>
|
||||
<span fxFlex></span>
|
||||
<button id="nav_home" mat-icon-button routerLink="/"><mat-icon>home</mat-icon></button>
|
||||
<button id="nav_settings" mat-icon-button routerLink="/settings"><mat-icon>settings</mat-icon></button>
|
||||
|
|
|
@ -9,14 +9,15 @@ import {TestingLocation} from '../models/testingLocation.interface';
|
|||
})
|
||||
export class NavbarComponent implements OnInit {
|
||||
@Input() testingLocation: TestingLocation;
|
||||
locationId: string;
|
||||
|
||||
constructor(private settingsService: SettingsService) {
|
||||
const settings = this.settingsService.getSettings();
|
||||
this.locationId = settings.locationId;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
get locationId(): string {
|
||||
const settings = this.settingsService.getSettings();
|
||||
return settings.locationId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import {AppDefaults} from '../models/appDefaults.interface';
|
|||
import {LabelLayout} from '../models/labelLayout.interface';
|
||||
import {Sample} from '../models/sample.interface';
|
||||
import {ApiService} from '../services/api.service';
|
||||
import {CacheService} from '../services/cache.service';
|
||||
import {SettingsService} from '../services/settings.service';
|
||||
|
||||
@Component({
|
||||
|
@ -26,7 +27,8 @@ export class PrintComponent implements AfterViewInit {
|
|||
private api: ApiService,
|
||||
private route: ActivatedRoute,
|
||||
private changeDetector: ChangeDetectorRef,
|
||||
private settingsService: SettingsService
|
||||
private settingsService: SettingsService,
|
||||
private cacheService: CacheService,
|
||||
) {
|
||||
this.dateCreated = new Date();
|
||||
this.route.queryParamMap.subscribe(queryParamMap => {
|
||||
|
@ -86,6 +88,14 @@ export class PrintComponent implements AfterViewInit {
|
|||
this.api.addSample(newSample).subscribe((result) => {
|
||||
console.log('addSample subscribe callback');
|
||||
callback(result);
|
||||
}, err => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
const cachedRecords = this.cacheService.saveRecord(newSample);
|
||||
console.log('cachedRecords', cachedRecords);
|
||||
callback(newSample);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -34,11 +34,11 @@ export class ApiService {
|
|||
}
|
||||
|
||||
/** Add new sample */
|
||||
addSample(sample: Sample): Observable<Sample> {
|
||||
addSample(sample: Sample): Observable<null> {
|
||||
const url = this.apiRoot + this.endpoints.sample;
|
||||
|
||||
return this.httpClient
|
||||
.post<Sample>(url, sample)
|
||||
.post<null>(url, sample)
|
||||
.pipe(catchError(err => this._handleError(err)));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
import {Injectable} from '@angular/core';
|
||||
import serializeJs from 'serialize-javascript';
|
||||
import {Sample} from '../models/sample.interface';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class CacheService {
|
||||
// Default form field and data values
|
||||
records: Sample[] = [];
|
||||
|
||||
// localStorage key
|
||||
private localStorageKey = 'cachedRecords';
|
||||
|
||||
// Deserializes settings from local storage and returns AppDefaults instance
|
||||
getStoredRecords(): Sample[] {
|
||||
// tslint:disable-next-line:no-eval
|
||||
return (eval(`(${localStorage.getItem(this.localStorageKey)})`) || []) as Sample[];
|
||||
}
|
||||
|
||||
// Returns true if settings are found in local storage
|
||||
hasStoredRecords(): boolean {
|
||||
return this.getStoredRecords().length > 0;
|
||||
}
|
||||
|
||||
// Returns records from local storage, or [] if none have been saved yet.
|
||||
getRecords(): Sample[] {
|
||||
if (this.hasStoredRecords()) {
|
||||
return this.getStoredRecords();
|
||||
} else {
|
||||
return this.saveRecords(this.records);
|
||||
}
|
||||
}
|
||||
|
||||
// Serializes given record and adds it to cache in local storage
|
||||
saveRecord(newRecord: Sample): Sample[] {
|
||||
const records = this.getRecords();
|
||||
records.push(newRecord);
|
||||
return this.saveRecords(records);
|
||||
}
|
||||
|
||||
// Serializes multiple given records and stores them in local storage
|
||||
saveRecords(newRecords: Sample[]): Sample[] {
|
||||
localStorage.setItem(this.localStorageKey, serializeJs(newRecords));
|
||||
return newRecords;
|
||||
}
|
||||
|
||||
// Clears cached records.
|
||||
clearCache(): Sample[] {
|
||||
return this.saveRecords([]);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue