Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

NewsApp Angular 2

Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

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 './app.component';
import { NewsComponent } from './components/news/news.component';
import { HeaderComponent } from './components/header/header.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { NewsItemComponent } from './components/news/news-item/news-
item.component';
import { SectionsComponent } from './components/sections/sections.component';

/***** Services *****/


import { NewsService } from './services/news.service';
import { routes } from './routes';
import { news } from './store/reducers/news.reducer';
import { sections } from './store/reducers/sections.reducer';
import { NewsActions } from './store/actions/news.actions';

@NgModule({
declarations: [
AppComponent,
NewsComponent,
HeaderComponent,
NavbarComponent,
NewsItemComponent,
SectionsComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(routes),
StoreModule.provideStore({ sections, news }),
StoreDevtoolsModule.instrumentStore({ })
],
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>

app.comp.ts
===================================================================================
===================================================================================
=
import { Component } from '@angular/core';
import { HeaderComponent } from './components/header/header.component';
import { SectionsComponent } from './components/sections/sections.component';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
}

header.comp.html
===================================================================================
===================================================================================
=
<div>
<img class="d-block mx-auto" src="../../../assets/images/logo.png" alt=""
width="100" height="100">
</div>

header.comp.ts
===================================================================================
===================================================================================
=
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
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/news.reducer';
import { NewsActions } from '../../store/actions/news.actions';

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: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
subsections: string[];
response: Object[];
constructor(
private store: Store<any>,
private newsActions: NewsActions
) { }

ngOnInit() {
this.store.select(getNews).subscribe(
(news: any)=>{
if(news.length>0){
this.store.select(getSectionData).subscribe(state=>{
let filter=state.news.filter;
if(filter===''){
const tempArray = new Array();
news.forEach((element: News) => {

if(element.subsection!==''){
tempArray.push(element.subsection);
}
});
this.subsections = Array.from(new Set(tempArray));//CHECK IF OBJECT
OR ARRAY
}
});
}
});
}
dispatchAction($event: string) {
const createAction = this.newsActions.FilterSubsection($event);
this.store.dispatch(createAction);
}

news item comp html


===================================================================================
=====================================================================

<div class="media">
<!-- Display "image not found", when multimedia[] is empty" -->
<img
*ngIf="newsItem.multimedia.length === 0"
class="d-flex mr-3"
alt="64x64"
src="http://www.video-furn.com/images/icons/AVFI-Image-not-available-
icon.jpg"
style="width: 75px; height: 75px;">

<!-- Display "the image", when multimedia[] is not empty" -->


<img
*ngIf="newsItem.multimedia.length > 0"
class="d-flex mr-3"
alt="64x64"
[src]="newsItem.multimedia[0].url"
style="width: 75px; height: 75px;">

<div class="media-body">
<h5 class="mt-0"> {{ newsItem.title }} </h5>
{{ newsItem.abstract }}
</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" [attr.data-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="newsItem.multimedia[4]"
class="d-flex mr-3 fit-image"
alt="image"
[src]="newsItem.multimedia[4].url">
<!-- display only if caption present -->
<p *ngIf="newsItem.multimedia[2]">
{{ newsItem.multimedia[2].caption }}
</p>
</div>
<div class="modal-footer justify-content-between">
<a [href]="newsItem.url" 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: './news-item.component.html',
styleUrls: ['./news-item.component.css']
})
export class NewsItemComponent implements OnInit {
@Input() newsItem: News;
@Input() id: number;
url: string;
constructor() {
}

ngOnInit() {
this.url = this.newsItem.url;
}
}

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/zone.js/dist/zone.js';

import { NewsItemComponent } from './news-item/news-item.component';


import { NewsService } from '../../services/news.service';
import { News, NewsResponse } from '../../model/news';
import { NewsActions } from '../../store/actions/news.actions';
import { getNews } from '../../store/reducers/selector';
import { news } from '../../store/reducers/news.reducer';

@Component({
selector: 'app-news',
templateUrl: './news.component.html',
styleUrls: ['./news.component.css'],
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
this.router.params.subscribe(params=>{
sectionName=params.id;
this.newsService.getSectionNews(sectionName).subscribe((news:
NewsResponse)=>{
this.store.dispatch(this.newsActions.LoadSectionNews(news.results));
});

});
this.store.select(getNews)
.subscribe(
newsList => {
this.sectionNewsList = 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/sections.reducer';
import { getSectionData } from '../../store/reducers/selector';
// import { Observable } from 'rxjs/Observable';

@Component({
selector: 'app-sections',
templateUrl: './sections.component.html',
styleUrls: ['./sections.component.css']
})
export class SectionsComponent implements OnInit {

sectionList: any;

constructor(private store: Store<any>) {


}

ngOnInit() {
const createAction = { type: 'LOAD_SECTIONS', payload: {} };
this.store.dispatch(createAction);
this.store.select(getSectionData).subscribe(state=>{
this.sectionList=state.sections;
});
}

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 = 'https://api.nytimes.com/svc/topstories/v2/' + sectionName + '.json?
api-key=315a5a51483b469a918246dc2753b339';
return this.http.get(url)
.map((response)=>response.json());
}
}

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/news.actions';


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 (action.type) {
case LOAD_SECTION_NEWS: {
return {
newsList: action.payload,
filter: ''
};
}
case FILTER_SUBSECTION: {
return {
newsList: state.newsList,
filter: action.payload,
};
}
default:
return state;
}
}

export const getNewsList = (state: any) => {


return state.news.newsList;
};

export const getFilter = (state: any) => {


return state.news.filter;
};

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 (action.type) {
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 './news.reducer';
import { getSections } from './sections.reducer';

//export const getNews = '';


export const getNews = createSelector(getNewsList,getFilter,(newsList,filter)=>{
return newsList.filter((x: { subsection: any; })=>{
if(filter && filter.length!==0){
if(x.subsection===filter) return x;
}else{
return x;
}
});
});

export const getSectionData = createSelector(getSections,(sections)=>{


return sections;
});

You might also like