diff --git a/app/app.component.ts b/app/app.component.ts index 86d2e145..804c2741 100755 --- a/app/app.component.ts +++ b/app/app.component.ts @@ -2,72 +2,32 @@ import {Component, OnInit} from '@angular/core'; import {Observable} from "rxjs"; import {Store} from "@ngrx/store"; -import {CurrentSearch} from "./models/current-search.model"; -import {SearchResult} from "./models/search-result.model"; -import {YouTubeService} from "./services/youtube.service"; - @Component({ selector: 'my-app', template: `

{{title}}

- - -
-
-

Can't use geolocalization with an empty searchbox

+
-

- Try to type something in the searchbox, play with the location and with radius: the above state will - always be consistent and up to date. -

-

{{ state | json }}

-

state is empty

-

Search results:

+
-

No results

-
-
-
-

{{ result.title }}

-
- -
-
-
+ ` }) export class AppComponent implements OnInit { title = 'One Source of Truth for Angular 2'; - private state: CurrentSearch; - private currentSearch: Observable; - private searchResults: SearchResult[] = []; - private disableSearch = false; - constructor( - private store: Store, - private youtube: YouTubeService + // inject store and youtube service ) { - this.currentSearch = this.store.select('currentSearch'); - this.youtube.searchResults.subscribe((results: SearchResult[]) => this.searchResults = results); + // select the state here } ngOnInit() { - this.currentSearch.subscribe((state: CurrentSearch) => { - this.state = state; - if (state && state.name && state.name.length > 0) { - this.disableSearch = false; - this.youtube.search(state) - } else { - this.disableSearch = true; - this.searchResults = []; - } - }); + // handle here the state's update } } diff --git a/app/app.module.ts b/app/app.module.ts index 1fd1ca10..e49342b0 100755 --- a/app/app.module.ts +++ b/app/app.module.ts @@ -1,19 +1,13 @@ -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import {AppComponent} from "./app.component"; -import {Store, StoreModule} from "@ngrx/store"; -import {SearchReducer} from "./reducers/search.reducer"; -import {YouTubeService} from "./services/youtube.service"; +import {NgModule} from '@angular/core'; +import {BrowserModule} from '@angular/platform-browser'; import {HttpModule} from "@angular/http"; -import {SearchBox} from "./components/search-box.component"; -import {ProximitySelector} from "./components/proximity-selector.component"; +import {Store, StoreModule} from "@ngrx/store"; -const storeManager = StoreModule.provideStore ({ currentSearch: SearchReducer }); +import {AppComponent} from "./app.component"; @NgModule({ - imports: [ BrowserModule, StoreModule, storeManager, HttpModule ], - declarations: [ AppComponent, SearchBox, ProximitySelector ], - bootstrap: [ AppComponent ], - providers: [ YouTubeService ] + imports: [ BrowserModule, HttpModule ], + declarations: [ AppComponent, ], + bootstrap: [ AppComponent ] }) export class AppModule { } diff --git a/app/components/proximity-selector.component.ts b/app/components/proximity-selector.component.ts deleted file mode 100755 index 50bdff22..00000000 --- a/app/components/proximity-selector.component.ts +++ /dev/null @@ -1,78 +0,0 @@ -import {Component, Input} from '@angular/core'; -import {Store} from '@ngrx/store'; - -@Component({ - selector: 'proximity-selector', - template: ` -
- - -
-
- - -
- ` -}) - -export class ProximitySelector { - - static StoreEvents = { - position: 'ProximitySelector:POSITION', - radius: 'ProximitySelector:RADIUS', - off: 'ProximitySelector:OFF' - }; - - @Input() - store: Store; - - @Input() - disabled: boolean; - - active = false; - - onLocation($event: any) { - this.active = $event.target.checked; - if (this.active) { - navigator.geolocation.getCurrentPosition((position: any) => { - this.store.dispatch({ - type: ProximitySelector.StoreEvents.position, - payload: { - position: { - latitude: position.coords.latitude, - longitude: position.coords.longitude - } - } - }); - }); - } else { - this.store.dispatch({ - type: ProximitySelector.StoreEvents.off, - payload: {} - }); - } - } - - onRadius($event: any) { - const radius = parseInt($event.target.value, 10); - this.store.dispatch({ - type: ProximitySelector.StoreEvents.radius, - payload: { - radius: radius - } - }); - } - -} diff --git a/app/components/search-box.component.ts b/app/components/search-box.component.ts deleted file mode 100755 index 9e90b70c..00000000 --- a/app/components/search-box.component.ts +++ /dev/null @@ -1,37 +0,0 @@ -import {Observable} from 'rxjs/Rx'; -import {ElementRef, OnInit, Component, Input} from '@angular/core'; -import {Store} from '@ngrx/store'; - -@Component({ - selector: 'search-box', - template: ` - - ` -}) - -export class SearchBox implements OnInit { - - static StoreEvents = { - text: 'SearchBox:TEXT_CHANGED' - }; - - @Input() - store: Store; - - constructor(private el: ElementRef) {} - - ngOnInit(): void { - Observable.fromEvent(this.el.nativeElement, 'keyup') - .map((e: any) => e.target.value) - .debounceTime(500) - .subscribe((text: string) => - this.store.dispatch({ - type: SearchBox.StoreEvents.text, - payload: { - text: text - } - }) - ); - } - -} diff --git a/app/models/current-search.model.ts b/app/models/current-search.model.ts deleted file mode 100755 index 92d5f43f..00000000 --- a/app/models/current-search.model.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface CurrentSearch { - name: string; - location?: { - latitude: number, - longitude: number - }, - radius: number -} diff --git a/app/models/search-result.model.ts b/app/models/search-result.model.ts deleted file mode 100755 index 5126da8b..00000000 --- a/app/models/search-result.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface SearchResult { - id: string; - title: string; - thumbnailUrl: string; -} diff --git a/app/reducers/search.reducer.ts b/app/reducers/search.reducer.ts deleted file mode 100755 index 4589743e..00000000 --- a/app/reducers/search.reducer.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ActionReducer, Action } from '@ngrx/store'; -import {SearchBox} from '../components/search-box.component'; -import {ProximitySelector} from '../components/proximity-selector.component'; -import {CurrentSearch} from "../models/current-search.model"; - -export const SearchReducer: ActionReducer = (state: CurrentSearch, action: Action) => { - switch (action.type) { - case SearchBox.StoreEvents.text: - return Object.assign({}, state, { - name: action.payload.text - }); - case ProximitySelector.StoreEvents.position: - return Object.assign({}, state, { - location: { - latitude: action.payload.position.latitude, - longitude: action.payload.position.longitude - } - }); - case ProximitySelector.StoreEvents.radius: - return Object.assign({}, state, { - radius: action.payload.radius - }); - case ProximitySelector.StoreEvents.off: - return Object.assign({}, state, { - location: null - }); - default: - return state; - } -}; diff --git a/app/services/youtube.service.ts b/app/services/youtube.service.ts deleted file mode 100755 index a881dafa..00000000 --- a/app/services/youtube.service.ts +++ /dev/null @@ -1,58 +0,0 @@ -import {Observable, BehaviorSubject} from 'rxjs/Rx'; -import {Injectable} from '@angular/core'; -import {Response, Http} from '@angular/http'; -import {SearchResult} from '../models/search-result.model'; -import {CurrentSearch} from '../models/current-search.model'; - -const YOUTUBE_API_KEY = 'AIzaSyDOfT_BO81aEZScosfTYMruJobmpjqNeEk'; -const YOUTUBE_API_URL = 'https://www.googleapis.com/youtube/v3/search'; -const LOCATION_TEMPLATE = 'location={latitude},{longitude}&locationRadius={radius}km'; - - -@Injectable() -export class YouTubeService { - - searchResults: BehaviorSubject = new BehaviorSubject([]); - - constructor( private http: Http ) {} - - search(query: CurrentSearch): Observable { - let params = [ - `q=${query.name}`, - `key=${YOUTUBE_API_KEY}`, - `part=snippet`, - `type=video`, - `maxResults=50` - ]; - - if (query.location) { - const radius = query.radius ? query.radius : 50; - const location = - LOCATION_TEMPLATE - .replace(/\{latitude\}/g, query.location.latitude.toString()) - .replace(/\{longitude\}/g, query.location.longitude.toString()) - .replace(/\{radius\}/g, radius.toString()); - params.push(location); - } - - const queryUrl: string = `${YOUTUBE_API_URL}?${params.join('&')}`; - - console.log(queryUrl); - - this.http.get(queryUrl) - .map((response: Response) => { - console.log(response); - return response.json().items.map(item => { - return { - id: item.id.videoId, - title: item.snippet.title, - thumbnailUrl: item.snippet.thumbnails.high.url - }; - }); - }) - .subscribe((results: SearchResult[]) => this.searchResults.next(results)); - - return this.searchResults; - } - -}