Service implementation

First of all, we need to import localForage in our code:

  1. Add the following statement at the top of the file in order to import localForage: import localForage from "localforage";. Without this, you will not be able to use the library. By doing this, we will actually trigger loading localForage when our JavaScript code gets loaded by the index.html file.
  2. Now that we have added localForage and have loaded it, we can create an implementation of the MediaService interface:
class MediaServiceImpl<T extends Media> implements MediaService<T> 
{ loadMediaCollection(identifier: string):
Promise<MediaCollection<T>> { ... } saveMediaCollection(collection: MediaCollection<T>):
Promise<void>
{ ... } getMediaCollectionIdentifiersList(): Promise<string[]> { ... } removeMediaCollection(identifier: string): Promise<void> { ... } }

Notice how we have made our service implementation generic by requiring a type argument extending from our Media abstract class and how this T generic type is also used on the right side of the implements keyword.

We have added the Impl suffix to the class name to indicate that this is an implementation of an interface. This is a common naming convention. Opt for this approach instead of prefixing interfaces with an I character.

The first thing that we need to do is configure localForage properly. In order to keep things simple, we will create a separate instance of the MediaServiceImpl class for each media type that we will manage. We could actually make our code smarter and even more generic, but it would hinder readability. For this reason, we will use a specific object store for each type of media. Let's see how!

Add the following code to the class:

private readonly _store: LocalForage; 
 
constructor(private _type: Function) { 
    console.log(`Initializing media service for ${_type.name}`); 
 
    // each instance of the media service has its own data store: 
https://github.com/localForage/localForage // the initialization options are described here:
https://localforage.github.io/localForage/#settings-api-config this._store = localForage.createInstance({ name: 'mediaMan', version: 1.0, storeName: `media-man-${_type.name}`, // we add the type name
to the object store name! description: 'MediaMan data store' }); }

First of all, we have declared a _store field. This is what our service will use to load/persist data using localForage. The _store field gets initialized in the constructor, where we used the createInstance function, allowing us to create a dedicated store instance. This is explained in the official localForage documentation at https://localforage.github.io/localForage/#multiple-instances-createinstance.

Notice the -<name> suffix that we have added to the storeName property with -${_type.name}. This suffix will help us to differentiate between collections of media (for example, between collections of Book objects, collections of Movie objects, and so on​). The _type.name property will give us the name of the type that this specific service instance will take care of (for example, Book).

If you pay close attention to the constructor of our class, you'll note that the type is passed through there as Function. Actually, when creating an instance of the MediaServiceImpl class, we can pass it a type by name. The following is an example of what this looks like: const bookService = new MediaServiceImpl<Book>(Book);. When you pass the name of a class as an argument, you actually pass its constructor function. The reality is more complicated than this; take a look at the TypeScript handbook (https://www.typescriptlang.org/docs/handbook/classes.html) for details. Classes actually have a static and a non-static (or instance) side. Here, we took advantage of the static side to get the class name.

Next, we will implement the saveMediaCollection method. This method needs to invoke localForage to serialize and persist the given MediaCollection object. As this operation will be asynchronous, our method will have to return a Promise object. Before we can do so, we need to take care of two important issues.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.16.184