AngularFire2 as a dataservice?

167 views Asked by At

So I have been pouring through the documentation found in Angular.io as well as the Git Docs for AngularFire2. After completing some of the tutorial work and seeing that it works, I decided to try and do things in a "more correct" fashion.

It is my understanding that if you are going to interact with the same data in different components within the app perhaps it's best to write a service. In my example, I am building a small CMS with Angular2/4? and using firebase to store the data.

So I wrote this first part where the admin could alter his CTA on the home page. So to do that, he would go the admin panel make changes to the text via inputs and save. Then of course in the home page you would see the updated text. So the home component would really only have access to read. The question is how would you create the service and make it importable to the components that use it?

import { Component } from '@angular/core';
import { AngularFireDatabase, FirebaseObjectObservable } from 'angularfire2/database';

@Component({
selector: 'app-root',
template: `
  <h1>{{ item | async | json }}</h1>
  <input type="text" #newname placeholder="Name" />
  <input type="text" #newsize placeholder="Size" />
  <br />
  <button (click)="save(newname.value)">Set Name</button>
  <button (click)="update(newsize.value)">Update Size</button>
  <button (click)="delete()">Delete</button>
`,})
export class AppComponent {
  item: FirebaseObjectObservable<any>;

  constructor(db: AngularFireDatabase) {
    this.item = db.object('/item');
  }

  save(newName: string) {
    this.item.set({ name: newName });
  }

  update(newSize: string) {
    this.item.update({ size: newSize });
  }

  delete() {
    this.item.remove();
  }
}

As you can see in the code they are bringing this straight into the main component. This would be better (In my unknowing opinion) to be a service that can be injected. I wrote several attempts to do so on my own. Only to get many types of errors. Any help?

1

There are 1 answers

4
sketchthat On

You could create a service that is used by multiple components.

Make sure to include it in the providers section of NgModule. (So it only gets created once and stays persistent throughout your whole application.

import { ItemService } from './services/item.service';

@NgModule({
  providers: [ItemService]
});

The service could just be copied from your existing component.

import { AngularFireDatabase, FirebaseObjectObservable } from 'angularfire2/database';

@Injectable()
export class ItemService {
  public item: FirebaseObjectObservable<any>;

  constructor(
    private db: AngularFireDatabse
  ) {
    this.item = db.object('/item');
  }

  save(newName: string) {
    this.item.set({ name: newName });
  }

  update(newSize: string) {
    this.item.update({ size: newSize });
  }

  delete() {
    this.item.remove();
  }
}

Then your component slims down and accesses the service.

import { Component } from '@angular/core';
import { ItemService } from './services/item.service';

@Component({
  selector: 'app-root',
  template: `
    <h1>{{ item.service.item | async | json }}</h1>
    <input type="text" #newname placeholder="Name" />
    <input type="text" #newsize placeholder="Size" />
    <br />
    <button (click)="itemService.save(newname.value)">Set Name</button>
    <button (click)="itemService.update(newsize.value)">Update Size</button>
    <button (click)="itemService.delete()">Delete</button>
  `,})
  export class AppComponent {
    constructor(
      public itemService: ItemService
    ) {}
  }

In addition, you shouldn't make calls within your constructor on components. Have a look into Life Cycle Hooks