This is the third post in the series of building a HackerNews clone with Angular 2, Angular Material and Firebase. This post we will setup firebase and we will pull in and display the top stories, new stories from hackernews.
Previous posts :
Next post:
Dynamic Components, Routing Params and Refactor
Create an account with Firebase here and create a new project, we need only the API key for this project for now. After creating the project grab the API key from the project by clicking on Add firebase to web app
.
We will be using AngularFire2 — official library for Firebase and Angular2. We will use moment and angular2-moment for date time manipulations.
Below are the setups that we will be doing in this post,
app.routing.ts
to load top stories as default.#STEP 1
npm install angularfire2 firebase moment angular2-moment --save
Open up app.module.ts
import dependencies and configure AngularFire. For databaseURL will be using the HackerNews Firebase Database Url provided in the documentation. Take sometime to go through the API documentation, understanding the API is important.
import { AngularFireModule } from 'angularfire2';import * as firebase from 'firebase';import * as moment from 'moment';
@NgModule({declarations: [AppComponent,HeaderComponent],imports: [BrowserModule,MaterialModule.forRoot(),RouterModule.forRoot(routes),AngularFireModule.initializeApp({apiKey: '<API_KEY>',databaseURL: 'https://hacker-news.firebaseio.com',authDomain: '<AUTH_DOMAIN>'}),NewestModule],providers: [],bootstrap: [AppComponent]})
#STEP2
Under /src/app
— we are going to create shared
folder which will host our shared code for our application like utils, services, etc., Right now we are creating our hackernews service.
As we registered AngualrFire in our app module — the configuration will be accessible across the application. Open up hacker-news.service.ts
import { Injectable } from '@angular/core';import { AngularFire, FirebaseListObservable } from 'angularfire2';
@Injectable()export class HackerNewsService {
constructor(private af: AngularFire) { }
getNewestStories(limit: number) {return this.af.database.list('/v0/newstories', {query: {limitToFirst: limit,orderByKey : true}});}
getItem(id: number) {return this.af.database.object('/v0/item/' + id);}
}
Here we are creating an injectable
class with three methods.
getTopStories
— Returns ids of newest stories with a limit passed
getNewestStories
— Returns ids of newest stories with a limit passed.
getItem
— Returns the single item object.
this.af.database.list('v0/newstories')
— _What database is this accessing ?_As the configuration is across the application. We configured AngularFire in our app.module.ts
to access HackerNewsAPI on Firebase (docs) .
The cool thing in AngularFire2 is you can pass an Observable to query properties like limit, etc., instead of a number — docs
#STEP3
Register our hacknews service to our services module.
import { NgModule } from '@angular/core';import { HackerNewsService } from './hacker-news.service';
@NgModule({imports: [],exports : [],declarations: [],providers: []})export class ServicesModule{static forRoot() {return {ngModule: ServicesModule,providers: [HackerNewsService]}}}
export {HackerNewsService}
The last three lines is a helper I write always so I can access all the services from within application from this single module instead of going to individual folder in the import statement. You can see the import statement for HackerNewsService in Step4.
#STEP4
Generate a module Components
under shared
folder and generate a component ng g component story
We are going to create a component which takes id
as an input — retrieves the item from HackerNewsService
and renders it.
We have a setter
method for the property id, when the id changes we call the HackerNewsService
to retrieve the new story.
Import MomentModule
from angular2-moment
and MdCardModule
from angular-material
. We will use md-card
component from angular-material
to display our story. Below is our template file, I am using pipes
from angular2-moment to display the time.
Styles for the story component
#STEP5
Create a new module and component for top stories — refer to the previous blog post
I will show the component and the markup first, then we will go one by one to see what it does. I am pasting a screenshot of the code so it is well formatted.
We are importing MdCardModule in _topstories.module.ts_
as we will using in our template to display each story
So we are importing HackerNewsService, FirebaseListObservable
from respective modules.
I am getting the top 100 stories from the top stories in hackernews which is currently configured at limit
property within our component.
On ngOnInit
— We are calling the HackerNewsService
to get the top 100 stories.
trackByForStory
method — is used in the [trackBy](https://angular.io/docs/ts/latest/api/common/index/NgFor-directive.html)
section of ngFor
in our template.
#STEP6
Perform similar steps on top stories to update the newest component
.
#STEP7
Open the app.routing.ts
and update the path to redirect to topstories
and add a new route.
Thats the top stories page.
The app is deployed in firebase hosting (another post). The url is https://hackernews-clone.firebaseapp.com/. and the repo is actively worked around.