From 5ae4b77d8b2dfe1b6e6cbcd66a3bfa48108dbf30 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Wed, 1 Mar 2017 11:24:11 +0000 Subject: [PATCH] feat(aio): add document service --- .../app/documents/document.service.spec.ts | 14 +++++ aio/src/app/documents/document.service.ts | 54 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 aio/src/app/documents/document.service.spec.ts create mode 100644 aio/src/app/documents/document.service.ts diff --git a/aio/src/app/documents/document.service.spec.ts b/aio/src/app/documents/document.service.spec.ts new file mode 100644 index 0000000000..95fc21665b --- /dev/null +++ b/aio/src/app/documents/document.service.spec.ts @@ -0,0 +1,14 @@ +import { TestBed, inject } from '@angular/core/testing'; +import { DocumentService } from './document.service'; + +describe('DocumentService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [DocumentService] + }); + }); + + it('should ...', inject([DocumentService], (service: DocumentService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/aio/src/app/documents/document.service.ts b/aio/src/app/documents/document.service.ts new file mode 100644 index 0000000000..47a78eb7fb --- /dev/null +++ b/aio/src/app/documents/document.service.ts @@ -0,0 +1,54 @@ +import { Injectable } from '@angular/core'; +import { Http, Response } from '@angular/http'; + +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/operator/switchMap'; + +import { DocumentContents } from './document'; +import { LocationService } from '../shared/location.service'; +import { Logger } from '../shared/logger.service'; + +const FILE_NOT_FOUND_DOC = 'file-not-found'; + +@Injectable() +export class DocumentService { + + private cache = new Map>(); + + currentDocument: Observable; + + constructor(private logger: Logger, private http: Http, location: LocationService) { + // Whenever the URL changes we try to get the appropriate doc + this.currentDocument = location.currentUrl.switchMap(url => this.getDocument(url)); + } + + private getDocument(url: string) { + this.logger.log('getting document', url); + if ( !this.cache.has(url)) { + this.cache.set(url, this.fetchDocument(url)); + } + return this.cache.get(url); + } + + private fetchDocument(url: string) { + const path = this.computePath(url); + this.logger.log('fetching document from', path); + return this.http + .get(path) + .map(res => res.json()) + .catch((error: Response) => { + if (error.status === 404 && url !== FILE_NOT_FOUND_DOC) { + this.logger.error(`Document file not found at '${url}'`); + // using `getDocument` means that we can fetch the 404 doc contents from the server and cache it + return this.getDocument(FILE_NOT_FOUND_DOC); + } else { + throw error; + } + }); + } + + private computePath(url) { + url = url.startsWith('/') ? url : '/' + url; + return 'content/docs' + url + '.json'; + } +}