It is a real-time News Application using New York Times news API.
The New York Times is an American newspaper based in New York City with worldwide influence and readership.
Following are the few concepts used while building this application:
- Routing
- API Calls
- Dependency Injection
- State Management using NgRx
- Components
[SectionsComponent, NavbarComponent, NewsComponent, and NewsIemComponent] - Services
[NewsService] - Store
[Actions, Reducers, Selectors, Effects]
Create a reducer function for each data type you have in your application. The combination of these reducers will make up your application state:
export interface SectionsState {
allSections: Array<string>;
currentSection: string;
}
export function reducer(state: SectionsState = initialState, action: SectionsActions): SectionsState {
switch (action.type) {
case SectionsActionTypes.LOAD_SECTIONS:
return state;
case SectionsActionTypes.SET_CURRENT_SECTION:
return {
...state,
currentSection: action.payload
};
default:
return state;
}
}
In your app's main module, import those reducers and use the StoreModule.provideStore(reducers) function to provide them to Angular's injector:
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { reducers } from './store/reducers';
import { NewsEffects } from './store/effects/news.effects';
@NgModule({
imports: [
StoreModule.forRoot(reducers),
EffectsModule.forRoot([
NewsEffects
])
]
})
export class AppModule { }
You can then inject the Store service into your components and services. Use store.select to select slice(s) of state:
this.store.pipe(select(getAllSections))
.subscribe(
allSections => {
this.allSections = allSections;
}
);
filterNews(filter: string): void {
this.store.dispatch(new fromActions.FilterSubSection(filter));
}
Build Actions to dispatch actions and Selectors to fetch slice of state:
import { Action } from '@ngrx/store';
export class LoadSections implements Action {
readonly type = SectionsActionTypes.LOAD_SECTIONS;
constructor() {}
}
import { createSelector } from '@ngrx/store';
export const getAllSections = createSelector(
selectSectionsState,
sections => sections.allSections
)
The effect listens for any defined action(s) (e.g. LoadNewsSection), then does some processing and returns any action(s) that are then processed by the store and distributed to a reducer or some other effect:
this.store.dispatch(new fromActions.LoadNewsSection());
import { Effect, Actions, ofType } from '@ngrx/effects';
@Effect()
loadNews$: Observable<Action> = this.actions$.pipe(
ofType(fromActions.NewsActionTypes.LOAD_SECTION_NEWS), // watch action
mergeMap((action: LoadNewsSection) =>
this.newsService.getSectionNews(action.payload).pipe(
map((news: NewsInfo) => (new fromActions.LoadNewsSectionSuccess(news.results))),
catchError(error => of(new fromActions.LoadNewsSectionFailure(error)))
)
)
);
This project was generated with Angular CLI version 6.1.2.
git clone https://github.com/kprokkie/angular-ngrx-news-app.git
Run
npm installto install project dependencies
Run
ng servefor a dev server. Navigate tohttp://localhost:4200/
Run
ng buildto build the project.
The build artifacts will be stored in the dist/ directory. Use the --prod flag for a production build.
Run
ng testto execute the unit tests via Karma.
Run
ng e2eto execute the end-to-end tests via Protractor.