Skip to content

Commit d3be32d

Browse files
committed
Created API + Model, updated Container state with API and mapper auxiliary module
1 parent 13d0c64 commit d3be32d

File tree

6 files changed

+74
-14
lines changed

6 files changed

+74
-14
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {fetchMemberList} from './memberApi';
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { MemberEntity } from './model';
2+
3+
const baseRoot = 'https://api.github.com/orgs/lemoncode';
4+
const membersURL = `${baseRoot}/members`
5+
6+
export const fetchMemberList = () : Promise<MemberEntity[]> => {
7+
8+
return fetch(membersURL)
9+
.then(checkStatus)
10+
.then(parseJSON)
11+
.then(resolveMembers)
12+
13+
14+
}
15+
16+
// If we return a value that is not a "thennable", it is automatically
17+
// promoted to a promise, so we can keep chaining "then" class without
18+
// wrapping the returned values with Promise.resolve(...)
19+
const checkStatus = (response : Response) : Response => {
20+
if (response.status >= 200 && response.status < 300) {
21+
return response;
22+
} else {
23+
let error = new Error(response.statusText);
24+
throw error;
25+
}
26+
}
27+
28+
const parseJSON = (response : Response) : any => {
29+
return response.json();
30+
}
31+
32+
// This simplified syntax represents the following steps:
33+
// 1- First, we call our function for each entry in the "data" array
34+
// 2- For each of this objects, we then create 3 input varialbes (id, login, avatar_url)
35+
// using destructuring in the signature for the arrow function's arguments
36+
// 3- We create a new object with these 3 variables using the short syntax
37+
// for objects parameters (i.e. {id, login, avatar_url} equals {id:id, login: login,
38+
// avatar_url: avatar_url})
39+
// 4- Finally, we perform a "cast" of this object to MemberEntity TS interface
40+
// (since our properties have the same names and types as the ones in the interface,
41+
// we sort of "implement" it)
42+
const resolveMembers = (data : any) : MemberEntity[] => {
43+
const members = data.map(
44+
({id, login, avatar_url,}) => ({ id, login, avatar_url, } as MemberEntity)
45+
);
46+
47+
return members;
48+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {MemberEntity} from './member';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface MemberEntity {
2+
login: string;
3+
id: number;
4+
avatar_url: string;
5+
}

02 create API and expose it in Container/src/pages/members/container.tsx

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as React from 'react';
22
import { MemberListPage } from './page';
33
import { MemberEntity } from './viewModel';
4+
import { fetchMemberList } from '../../api';
5+
import { mapMemberListFromModelToVm } from './mapper';
46

57
interface State {
68
memberList : MemberEntity[];
@@ -14,22 +16,11 @@ export class MemberListContainer extends React.Component<{}, State> {
1416
}
1517

1618
fetchMembers = () => {
17-
setTimeout(() => {
19+
fetchMemberList().then((memberList) => {
1820
this.setState({
19-
memberList: [
20-
{
21-
id: 1,
22-
name: 'John',
23-
avatarUrl: 'https://avatars1.githubusercontent.com/u/1457912?v=4',
24-
},
25-
{
26-
id: 2,
27-
name: 'Martin',
28-
avatarUrl: 'https://avatars2.githubusercontent.com/u/4374977?v=4',
29-
},
30-
]
21+
memberList: mapMemberListFromModelToVm(memberList),
3122
});
32-
}, 500);
23+
});
3324
}
3425

3526
render() {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import * as apiModel from '../../api/model';
2+
import * as vm from './viewModel';
3+
4+
const mapMemberFromModelToVm = (member: apiModel.MemberEntity) : vm.MemberEntity => (
5+
{
6+
id: member.id,
7+
avatarUrl: member.avatar_url,
8+
name: member.login,
9+
}
10+
)
11+
12+
export const mapMemberListFromModelToVm = (memberList: apiModel.MemberEntity[]) : vm.MemberEntity[] => (
13+
memberList.map(mapMemberFromModelToVm)
14+
)

0 commit comments

Comments
 (0)