Angular 2 News Application
npm install @ngrx/store-devtools
appmodule
============
/***** Modules *****/
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';
import { StoreModule } from '@ngrx/store';
import {StoreDevtoolsModule} from '@ngrx/store-devtools';
/***** Components *****/
import { AppComponent } from './[Link]';
import { NewsComponent } from './components/news/[Link]';
import { HeaderComponent } from './components/header/[Link]';
import { NavbarComponent } from './components/navbar/[Link]';
import { NewsItemComponent } from './components/news/news-item/news-
[Link]';
import { SectionsComponent } from './components/sections/[Link]';
/***** Services *****/
import { NewsService } from './services/[Link]';
import { routes } from './routes';
import { news } from './store/reducers/[Link]';
import { sections } from './store/reducers/[Link]';
import { NewsActions } from './store/actions/[Link]';
@NgModule({
declarations: [
AppComponent,
NewsComponent,
HeaderComponent,
NavbarComponent,
NewsItemComponent,
SectionsComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
[Link](routes),
[Link]({ sections, news }),
[Link]({ })
],
providers: [NewsService, NewsActions],
bootstrap: [AppComponent]
})
export class AppModule { }
app comp html
===================================================================================
===================================================================================
=
<div class="row">
<app-sections></app-sections>
<div class="container" >
<app-header></app-header>
<app-navbar></app-navbar>
<router-outlet></router-outlet>
</div>
</div>
[Link]
===================================================================================
===================================================================================
=
import { Component } from '@angular/core';
import { HeaderComponent } from './components/header/[Link]';
import { SectionsComponent } from './components/sections/[Link]';
@Component({
selector: 'app-root',
templateUrl: './[Link]',
styleUrls: ['./[Link]']
})
export class AppComponent {
}
[Link]
===================================================================================
===================================================================================
=
<div>
<img class="d-block mx-auto" src="../../../assets/images/[Link]" alt=""
width="100" height="100">
</div>
[Link]
===================================================================================
===================================================================================
=
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-header',
templateUrl: './[Link]',
styleUrls: ['./[Link]']
})
export class HeaderComponent implements OnInit {
constructor() { }
ngOnInit() {
}
navbar comp html
===================================================================================
===================================================================================
=====
<ul class="nav justify-content-center bg-dark">
<li
class="nav-item"
*ngFor="let subsection of subsections">
<a
href="javascript:void(0);"
class="nav-link text-white small"
(click)="dispatchAction(subsection)"> {{subsection}} </a>
</li>
</ul>
navbar comp
===================================================================================
=====================================================================
import { News } from './../../model/news';
import { NewsState } from './../../store/reducers/[Link]';
import { NewsActions } from '../../store/actions/[Link]';
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { getNews, getSectionData } from '../../store/reducers/selector';
@Component({
selector: 'app-navbar',
templateUrl: './[Link]',
styleUrls: ['./[Link]']
})
export class NavbarComponent implements OnInit {
subsections: string[];
response: Object[];
constructor(
private store: Store<any>,
private newsActions: NewsActions
) { }
ngOnInit() {
[Link](getNews).subscribe(
(news: any)=>{
if([Link]>0){
[Link](getSectionData).subscribe(state=>{
let filter=[Link];
if(filter===''){
const tempArray = new Array();
[Link]((element: News) => {
if([Link]!==''){
[Link]([Link]);
}
});
[Link] = [Link](new Set(tempArray));//CHECK IF OBJECT
OR ARRAY
}
});
}
});
}
dispatchAction($event: string) {
const createAction = [Link]($event);
[Link](createAction);
}
news item comp html
===================================================================================
=====================================================================
<div class="media">
<!-- Display "image not found", when multimedia[] is empty" -->
<img
*ngIf="[Link] === 0"
class="d-flex mr-3"
alt="64x64"
src="[Link]
[Link]"
style="width: 75px; height: 75px;">
<!-- Display "the image", when multimedia[] is not empty" -->
<img
*ngIf="[Link] > 0"
class="d-flex mr-3"
alt="64x64"
[src]="[Link][0].url"
style="width: 75px; height: 75px;">
<div class="media-body">
<h5 class="mt-0"> {{ [Link] }} </h5>
{{ [Link] }}
</div>
</div>
<!-- Button trigger modal -->
<div class="d-flex justify-content-end">
<button type="button" class="btn btn-sm btn-outline-secondary" data-
toggle="modal" [[Link]-target]="'#modal'">
Read More ...
</button>
</div>
<!-- Modal -->
<div class="modal fade" [id]="'modal'" tabindex="-1" role="dialog" aria-
labelledby="exampleModal1Label" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModal1Label"></h5>
<!-- <button type="button" class="close" data-dismiss="modal" aria-
label="Close">
<span aria-hidden="true">×</span>
</button> -->
</div>
<div class="modal-body">
<img
*ngIf="[Link][4]"
class="d-flex mr-3 fit-image"
alt="image"
[src]="[Link][4].url">
<!-- display only if caption present -->
<p *ngIf="[Link][2]">
{{ [Link][2].caption }}
</p>
</div>
<div class="modal-footer justify-content-between">
<a [href]="[Link]" target="_blank"> Source </a>
<button type="button" class="btn btn-secondary" data-
dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<br>
<div class="h-divider"></div>
<br>
news item comp ts
===================================================================================
=====================================================================
import { Component, OnInit, Input } from '@angular/core';
import { News } from '../../../model/news';
@Component({
selector: 'app-news-item',
templateUrl: './[Link]',
styleUrls: ['./[Link]']
})
export class NewsItemComponent implements OnInit {
@Input() newsItem: News;
@Input() id: number;
url: string;
constructor() {
}
ngOnInit() {
[Link] = [Link];
}
}
news comp html
===================================================================================
=====================================================================
<br>
<app-news-item
*ngFor="let oneNews of sectionNewsList; let i=index"
[id]="i"
[newsItem]="oneNews">
</app-news-item>
news comp ts
===================================================================================
=====================================================================
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';
import { Store } from '@ngrx/store';
import '../../../../node_modules/[Link]/dist/[Link]';
import { NewsItemComponent } from './news-item/[Link]';
import { NewsService } from '../../services/[Link]';
import { News, NewsResponse } from '../../model/news';
import { NewsActions } from '../../store/actions/[Link]';
import { getNews } from '../../store/reducers/selector';
import { news } from '../../store/reducers/[Link]';
@Component({
selector: 'app-news',
templateUrl: './[Link]',
styleUrls: ['./[Link]'],
providers: []
})
export class NewsComponent implements OnInit {
sectionNewsList: any;
constructor(
private newsService: NewsService,
private router: ActivatedRoute,
private store: Store<any>,
private newsActions: NewsActions
) { }
ngOnInit() {
let sectionName;
// send this sectionName to newsService. Subscribe newsService and get the
newsList
// now, get news from store
[Link](params=>{
sectionName=[Link];
[Link](sectionName).subscribe((news:
NewsResponse)=>{
[Link]([Link]([Link]));
});
});
[Link](getNews)
.subscribe(
newsList => {
[Link] = newsList;
}
);
}
}
sections comp html
===================================================================================
=====================================================================
<div class="list-group">
<a
href="#!"
class="list-group-item list-group-item-action ml-2"
routerLink="/section/{{sectionName}}"
routerLinkActive="active"
*ngFor="let sectionName of sectionList">
{{sectionName}}
</a>
</div>
sections comp ts
===================================================================================
=====================================================================
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { sections } from '../../store/reducers/[Link]';
import { getSectionData } from '../../store/reducers/selector';
// import { Observable } from 'rxjs/Observable';
@Component({
selector: 'app-sections',
templateUrl: './[Link]',
styleUrls: ['./[Link]']
})
export class SectionsComponent implements OnInit {
sectionList: any;
constructor(private store: Store<any>) {
}
ngOnInit() {
const createAction = { type: 'LOAD_SECTIONS', payload: {} };
[Link](createAction);
[Link](getSectionData).subscribe(state=>{
[Link]=[Link];
});
}
news service
===================================================================================
=====================================================================
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { News, NewsResponse } from '../model/news';
import 'rxjs/add/operator/map';
@Injectable()
export class NewsService {
constructor(private http: Http) { }
/*getSectionNews(sectionName: string): any {
// fetch news of that sectionName
}*/
getSectionNews(sectionName: string): any {
// fetch news of that sectionName
let url = '[Link] + sectionName + '.json?
api-key=315a5a51483b469a918246dc2753b339';
return [Link](url)
.map((response)=>[Link]());
}
}
news actions
===================================================================================
=====================================================================
import { Injectable } from '@angular/core';
import { Action } from '@ngrx/store';
import { News } from '../../model/news';
@Injectable()
export class NewsActions {
static LOAD_SECTION_NEWS = '[News] LOAD_SECTION_NEWS';
static FILTER_SUBSECTION = '[News] FILTER_SUBSECTION';
LoadSectionNews(list: News[]): Action {
return {
type: NewsActions.LOAD_SECTION_NEWS,
payload: list
};
}
FilterSubsection(subsection: string): Action {
return {
type: NewsActions.FILTER_SUBSECTION,
payload: subsection
};
}
}
news reducer
===================================================================================
=====================================================================
import { NewsActions } from './../actions/[Link]';
import { Action } from '@ngrx/store';
import { News } from '../../model/news';
// define actions
export const LOAD_SECTION_NEWS = '[News] LOAD_SECTION_NEWS';
export const FILTER_SUBSECTION = '[News] FILTER_SUBSECTION';
// define state interface
export interface NewsState {
newsList: News[];
filter: string;
}
// initial state
export const initialState: NewsState = {
newsList: [],
filter: ''
};
// implement actions
export function news (state = initialState, action: Action) {
switch ([Link]) {
case LOAD_SECTION_NEWS: {
return {
newsList: [Link],
filter: ''
};
}
case FILTER_SUBSECTION: {
return {
newsList: [Link],
filter: [Link],
};
}
default:
return state;
}
}
export const getNewsList = (state: any) => {
return [Link];
};
export const getFilter = (state: any) => {
return [Link];
};
sections reducer
===================================================================================
=====================================================================
import { Action } from '@ngrx/store';
// define actions
export const LOAD_SECTIONS = '[Section] LOAD_SECTIONS';
// initial state
export const initialState = [
'home', 'opinion', 'world', 'national', 'politics', 'business',
'technology',
'science', 'health', 'sports', 'arts', 'books', 'movies', 'theater',
'fashion',
'food', 'travel', 'magazine', 'realestate', 'automobiles'
];
// implement actions
export function sections (state = initialState, action: Action) {
switch ([Link]) {
case LOAD_SECTIONS: {
return state;
}
default:
return state;
}
}
export const getSections = (state: any = initialState) => {
return state;
};
selector
===================================================================================
=====================================================================
import {createSelector } from 'reselect';
import { getNewsList, getFilter } from './[Link]';
import { getSections } from './[Link]';
//export const getNews = '';
export const getNews = createSelector(getNewsList,getFilter,(newsList,filter)=>{
return [Link]((x: { subsection: any; })=>{
if(filter && [Link]!==0){
if([Link]===filter) return x;
}else{
return x;
}
});
});
export const getSectionData = createSelector(getSections,(sections)=>{
return sections;
});