Refactor Round 2

In last week’s post accessing a web API was refactored to a central service in an Aurelia application instead of being spread across the application. In this post we will push the refactor even further. The service will change from a pass through to the backing web API to be the data provider for the Aurelia application.

The first set of changes is to the service, which may be a bad name with the changes that are being made. GetAll will now keep a copy of the contact retrieved for the web API.

Before:
GetAll() {
    return this.http.fetch('contacts')
        .then(response => response.json())
        .catch(error => console.log(error));
}
After:
GetAll() {
    return this.http.fetch('contacts')
        .then(response => response.json())
        .then(contacts => this.contacts = contacts)
        .catch(error => console.log(error));
}

As an example of the implications of this change we will look at the Get function which require a contact ID. Instead of hitting the web API to pull the details of contact the information is pull from the service’s local copy that was cached in the GetAll function above.

Before:
Get(id) {
    return this.http.fetch(`contacts/${id}`)
        .then(response => response.json())
        .catch(error => console.log(error));
}
After:
Get(id) {
    return new Promise((resolve) => {
        resolve(this.contacts.filter(contact => contact.Id == id)[0])
    });
}

With the above changes the view model for the contact list contains very little code. With the binding of the contact list now bound to the service changes to contacts are automatically reflected in the contact list. This removed the need for the event aggregator. The full code for the list view model follows.

import {inject} from 'aurelia-framework';
import {ContactService} from 'Aurelia/contactService';

@inject(ContactService)
export class List {

    constructor(contactService) {
        this.contactService = contactService;
        this.contactService.GetAll()
             .then(() => this.contacts = this.contactManager.contacts);
    }
}

All the view models had similar reductions in the amount of code required. There are many more options on the best way to factor this code. A next step could be to keep the web API access separate from the a new business class used to manage and cache the contact data once it has been retrieved.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.