REDUX
Action
@Injectable()
export class SearchActions {
static GET_VIDEOS = '[Search] GET_VIDEOS';
constructor(private store: Store<any>) {
}
getVideos(payload) {
this.store.dispatch({type: SearchActions.GET_VIDEOS, payload});
}
}
Effect
@Effect()
getVideos_ = this.appState_
.ofType(SearchActions.GET_VIDEOS)
.map((action: any) => action.payload)
.switchMap(_ => this.dtsiVideosService.getVideos()
.map((vid: VideoEntity) => this.searchEvents.getVideosComplete(vid))
.catch(err => of(this.searchEvents.getVideosError(err))));
Event
import {Injectable} from '@angular/core';
import {Store} from '@ngrx/store';
@Injectable()
export class SearchEvents {
static GET_VIDEOS_COMPLETE = '[Search] GET_VIDEOS_COMPLETE';
constructor() {
}
getVideosComplete(payload) {
return {type: SearchEvents.GET_VIDEOS_COMPLETE, payload};
}
}
Reducer
@Reducer(VideoEvents.GET_VIDEOS_COMPLETE)
@Reducer(SearchEvents.GET_VIDEOS_COMPLETE)
getVideosComplete(state: VideosState, event: ReducerEvent) {
const videosClone = {...state.entities};
const videos = VideoNormalizer.videos(event.payload);
const entities = videos.reduce((acc, curr) => {
acc[curr.id] = curr;
return acc;
}, videosClone);
return {...state, entities: entities};
}
Projection
getVideoById_(videoId): Observable<VideoEntity> {
return this.store.select('videos', 'entities')
.map((entities: any) => entities[videoId]);
}
getSearchResults_(): Observable<any> {
return Observable.combineLatest(
this.store.select('videos', 'entities'),
this.store.select('tags', 'entities'),
this.store.select('search', 'terms')
).map(([videos, tags, terms = []]: [any, any, any]) => {
const videosIds = Object.keys(videos);
const entities = videos;
const tagIds = terms;
const vids = videosIds
.map(videosId => {
let vid = entities[videosId];
vid.tagIds = vid.tagIds || [];
const ts = vid.tagIds.map(tagId => tags[tagId]);
vid = {...vid, tags: ts};
return vid;
})
.filter(video => {
if (tagIds.length === 0) {
return true;
}
const res = video.tagIds.map(tagId => tagIds.includes(tagId));
return res.includes(true);
});
return _.orderBy(vids, (video) => {
return video.tagIds.length;
}, 'desc');
});
}
Combine Projection
getOnlineStatus(): any {
let online = null;
this.store.select('ui', 'online').take(1).subscribe(x => online = x);
return online;
}
Synchronous Projection
REDUX
By bretto
REDUX
- 197