forked from housseindjirdeh/angular2-hn
-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathhackernews-api.service.ts
More file actions
76 lines (67 loc) · 2.24 KB
/
Copy pathhackernews-api.service.ts
File metadata and controls
76 lines (67 loc) · 2.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { forkJoin } from 'rxjs';
import fetch from 'unfetch';
import {map } from 'rxjs/operators';
import { Story } from '../models/story';
import { User } from '../models/user';
import { PollResult } from '../models/poll-result';
// wrap fetch in observable so we can keep it chill
@Injectable()
export class HackerNewsAPIService {
baseUrl: string;
constructor() {
this.baseUrl = 'https://node-hnapi.herokuapp.com';
}
fetchFeed(feedType: string, page: number): Observable<Story[]> {
return lazyFetch(`${this.baseUrl}/${feedType}?page=${page}`);
}
fetchWeeklyTop(): Observable<Story[]> {
const pages = [1, 2, 3, 4, 5].map(page => lazyFetch<Story[]>(`${this.baseUrl}/news?page=${page}`));
const weekAgo = Date.now() / 1000 - 7 * 24 * 3600;
return forkJoin(pages).pipe(
map(results => ([] as Story[]).concat(...results)
.filter(story => story.time >= weekAgo)
.sort((a, b) => b.points - a.points))
);
}
fetchItemContent(id: number): Observable<Story> {
return lazyFetch(`${this.baseUrl}/item/${id}`).pipe(map((story: Story) => {
if (story.type === 'poll') {
const numberOfPollOptions = story.poll.length;
story.poll_votes_count = 0;
for (let i = 1; i <= numberOfPollOptions; i++) {
this.fetchPollContent(story.id + i).subscribe(pollResults => {
story.poll[i - 1] = pollResults;
story.poll_votes_count += pollResults.points;
});
}
}
return story;
}));
}
fetchPollContent(id: number): Observable<PollResult> {
return lazyFetch(`${this.baseUrl}/item/${id}`);
}
fetchUser(id: string): Observable<User> {
return lazyFetch(`${this.baseUrl}/user/${id}`);
}
}
function lazyFetch<T>(url, options?) {
return new Observable<T>(fetchObserver => {
let cancelToken = false;
fetch(url, options)
.then(res => {
if (!cancelToken) {
return res.json()
.then(data => {
fetchObserver.next(data);
fetchObserver.complete();
});
}
}).catch(err => fetchObserver.error(err));
return () => {
cancelToken = true;
};
});
}