-
-
Save xmlking/282da723642ab0239940a3e6710d3064 to your computer and use it in GitHub Desktop.
Angular 2 Wikipedia Image Search
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SystemJS.config({ | |
transpiler: "typescript", | |
typescriptOptions: { | |
"experimentalDecorators": true, | |
"emitDecoratorMetadata": true | |
}, | |
map: { | |
"rxjs": "https://npmcdn.com/[email protected]", | |
"angular2": "https://npmcdn.com/[email protected]", | |
"typescript": "https://npmcdn.com/[email protected]/lib/typescript.js" | |
}, | |
packages: { | |
"rxjs": { "defaultExtension": "js" }, | |
"angular2": { "defaultExtension": "js" }, | |
"@ngrx/store":{ | |
"main":"dist/index.js" | |
}, | |
"src": { "defaultExtension": "ts" }, | |
"build": { "defaultExtension": "ts" } | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Angular 2 App</title> | |
<script src="https://npmcdn.com/angular2/bundles/angular2-polyfills.js"></script> | |
<script src="https://npmcdn.com/systemjs/dist/system.js"></script> | |
<link rel="stylesheet" type="text/css" href="style.css"> | |
</head> | |
<body> | |
<app></app> | |
<script src="config.js"></script> | |
<script>System.import('src/main');</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Component} from 'angular2/core'; | |
import 'rxjs/add/operator/map'; | |
import 'rxjs/add/operator/do'; | |
import 'rxjs/add/operator/concatAll'; | |
import 'rxjs/add/operator/mergeMap'; | |
import 'rxjs/add/operator/scan'; | |
import 'rxjs/add/operator/filter'; | |
import 'rxjs/add/operator/debounceTime'; | |
import 'rxjs/add/operator/reduce'; | |
import 'rxjs/add/operator/startWith'; | |
import 'rxjs/add/operator/share'; | |
import 'rxjs/add/operator/distinctUntilChanged'; | |
import 'rxjs/add/operator/combineLatest'; | |
import 'rxjs/add/operator/withLatestFrom'; | |
import 'rxjs/add/operator/switchMap'; | |
import 'rxjs/add/operator/concat'; | |
import 'rxjs/add/operator/takeUntil'; | |
import 'rxjs/add/operator/race'; | |
import 'rxjs/add/operator/mapTo'; | |
import 'rxjs/add/observable/bindCallback'; | |
import 'rxjs/add/observable/merge'; | |
import {JSONP_PROVIDERS, HTTP_PROVIDERS, Http, Jsonp} from 'angular2/http'; | |
import {Subject} from 'rxjs/Subject'; | |
import {BehaviorSubject} from 'rxjs/BehaviorSubject'; | |
import {WikipediaService} from './services/wikipedia.service'; | |
import {Observable} from 'rxjs/Observable'; | |
@Component({ | |
selector: 'app', | |
providers: [HTTP_PROVIDERS, JSONP_PROVIDERS, WikipediaService] | |
template: ` | |
<style> | |
.container{ | |
width: 350px; | |
} | |
img{ | |
width: 90px; | |
border: 5px solid black; | |
} | |
img:hover { | |
width: 90px; | |
border: 5px solid gray; | |
} | |
</style> | |
<div> | |
<h2>Search: {{(searchTerm$ | async)}}</h2> | |
<input type="text" (input)="input$.next($event)"> | |
<h3>{{imageCount$ | async}} results</h3> | |
<div class="container"> | |
<a *ngFor="#image of images$ | async" [href]="image.descriptionurl"> | |
<img [src]="image.url" alt=""> | |
</a> | |
</div> | |
</div> | |
` | |
}) | |
export class App { | |
input$ = new Subject().map(event => event.target.value); | |
searchTerm$; | |
images$; | |
imageCount$; | |
constructor(wikipediaService:WikipediaService) { | |
this.searchTerm$ = this.input$ | |
.distinctUntilChanged() | |
.debounceTime(500) | |
.filter(term => term.length > 0) | |
.share(); | |
this.images$ = this.searchTerm$ | |
.switchMap(term=> wikipediaService.searchAllImages(term) | |
.map(wikipediaService.mapAllImagesToTitles) | |
.concatAll() | |
.mergeMap(wikipediaService.getImageInfoFromTitle) | |
.map(wikipediaService.mapImageInfoToUrls) | |
.scan((acc, curr)=> [...acc, ...curr]) | |
) | |
.startWith([]) | |
.share() | |
this.imageCount$ = this.images$ | |
.map(results => results.length) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {enableProdMode} from 'angular2/core'; | |
import {bootstrap} from 'angular2/platform/browser'; | |
import {App} from './app'; | |
enableProdMode(); | |
bootstrap(App) | |
.catch(console.log.bind(console)); | |
console.clear(); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Injectable} from 'angular2/core'; | |
import {Jsonp} from 'angular2/http'; | |
const CALLBACK = 'callback=JSONP_CALLBACK'; | |
const WIKIPEDIA = 'https://en.wikipedia.org/w/api.php'; | |
const QUERY = 'action=query'; | |
const JSON = 'format=json'; | |
const ALLIMAGES = 'list=allimages'; | |
const IMAGEINFO = 'prop=imageinfo'; | |
const API = `${WIKIPEDIA}?${QUERY}&${JSON}&${CALLBACK}&${ALLIMAGES}`; | |
const PROP_URL = 'iiprop=url'; | |
@Injectable() | |
export class WikipediaService{ | |
constructor(private _jsonp:Jsonp){} | |
searchAllImages = term => this._jsonp.get(`${API}&${ALLIMAGES}&aifrom=${term}`) | |
.map(res => res.json()); | |
mapAllImagesToTitles = allImages => allImages.query.allimages.map(({title}) => title); | |
getImageInfoFromTitle= title => this._jsonp.get(`${API}&${IMAGEINFO}&${PROP_URL}&titles=${title}`) | |
.map(res => res.json()); | |
mapImageInfoToUrls = body => Object.keys(body.query.pages) | |
.filter(page => page > 0) //page -1 means no images | |
.map(page =>{ | |
return body.query.pages[page].imageinfo[0]; | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Styles go here */ | |
body{ | |
font-family: sans-serif; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment