Integration SDK: Search listings from SDK and API

This commit is contained in:
Mikko Koski 2017-02-13 14:50:44 +02:00
parent 5b44a2fdb5
commit f9724f3c8e
5 changed files with 117 additions and 9 deletions

View file

@ -23,7 +23,8 @@
"sanitize.css": "^4.1.0",
"sharetribe-scripts": "0.8.6",
"source-map-support": "^0.4.11",
"url": "^0.11.0"
"url": "^0.11.0",
"sharetribe-sdk": "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js.git"
},
"devDependencies": {
"enzyme": "^2.7.1",

View file

@ -52,10 +52,10 @@ const ListingCard = props => {
ListingCard.defaultProps = { location: null, review: {}, author: {} };
const { number, shape, string } = PropTypes;
const { shape, string } = PropTypes;
ListingCard.propTypes = {
id: number.isRequired,
id: string.isRequired,
title: string.isRequired,
price: string.isRequired,
description: string.isRequired,

View file

@ -5,8 +5,11 @@
*/
import { unionWith, isEqual } from 'lodash';
import { call, put, takeEvery } from 'redux-saga/effects';
import { types } from 'sharetribe-sdk';
import { createRequestTypes } from '../../util/sagaHelpers';
const { LatLng } = types;
// ================ Action types ================ //
export const ADD_FILTER = 'app/SearchPage/ADD_FILTER';
@ -64,11 +67,73 @@ export const loadListings = {
// ================ Worker sagas ================ //
/**
Take `included` values from the JSON API response
and transforms it to a map which provide easy and fast lookup.
Example:
```
const included = [
{ id: new UUID(123), type: 'user', attributes: { name: "John" }},
{ id: new UUID(234), type: 'user', attributes: { name: "Jane" }},
];
const map = lookupMap(included)
#=> returns
# {
# user: {
# 123: { id: 123, type: 'user', attributes: { name: "John" }},
# 234: { id: 234, type: 'user', attributes: { name: "Jane" }},
# }
# }
map.user.123
#=> returns
# { id: 123, type: 'user', attributes: { name: "John" }},
```
*/
const lookupMap = included => included.reduce((memo, resource) => {
const { type, id } = resource;
// eslint-disable-next-line no-param-reassign
memo[type] = memo[type] || {};
// eslint-disable-next-line no-param-reassign
memo[type][id.uuid] = resource;
return memo;
}, {});
// Format the data as ListingCard component expects it and
// add some fake data
// TODO Remove this and think about the real implementation
const formatListingData = response => {
const includedMap = lookupMap(response.data.included);
const data = response.data.data;
return data.map(({ id, attributes, relationships }) => {
const author = includedMap.user[relationships.author.data.id.uuid];
const { firstName, lastName } = author.attributes.profile;
return {
id: id.uuid,
title: attributes.title,
description: attributes.description,
location: attributes.address,
price: '55\u20AC / day',
author: {
name: `${firstName} ${lastName}`,
avatar: 'http://placehold.it/44x44',
review: { rating: '4' },
},
};
});
};
export function* callFetchListings(sdk) {
try {
const response = yield call(sdk.fetchListings);
yield put(loadListings.success(response));
} catch(error) {
const response = yield call(sdk.listings.search, {
origin: new LatLng(40, 70),
include: ['author'],
});
yield put(loadListings.success(formatListingData(response)));
} catch (error) {
yield put(loadListings.failure(error));
}
}

View file

@ -1,6 +1,14 @@
import { createInstance } from 'sharetribe-sdk';
import { watchAuth } from './ducks/Auth.ducks';
import { watchLoadListings } from './containers/SearchPage/SearchPage.ducks';
import sdk from './util/fakeSDK';
// eslint-disable-next-line no-unused-vars
import fakeSdk from './util/fakeSDK';
const clientId = '08ec69f6-d37e-414d-83eb-324e94afddf0';
const baseUrl = 'http://localhost:8088';
const sdk = createInstance({ clientId, baseUrl });
const mockLogin = (email, password) => new Promise((resolve, reject) => {
window.setTimeout(
@ -25,5 +33,10 @@ const mockSdk = { login: mockLogin, logout: mockLogout };
export default function* rootSaga() {
// TODO: inject sdk in function arguments
// FakeSDK
// yield [watchAuth(mockSdk), watchLoadListings(fakeSdk)];
// Real SDK
yield [watchAuth(mockSdk), watchLoadListings(sdk)];
}

View file

@ -240,6 +240,12 @@ aws4@^1.2.1:
version "1.5.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755"
axios@^0.15.3:
version "0.15.3"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.15.3.tgz#2c9d638b2e191a08ea1d6cc988eadd6ba5bdc053"
dependencies:
follow-redirects "1.0.0"
babel-code-frame@6.22.0, babel-code-frame@^6.11.0, babel-code-frame@^6.16.0, babel-code-frame@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
@ -2410,6 +2416,12 @@ flow-parser@0.38.0:
colors ">=0.6.2"
minimist ">=0.2.0"
follow-redirects@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.0.0.tgz#8e34298cbd2e176f254effec75a1c78cc849fd37"
dependencies:
debug "^2.2.0"
for-in@^0.1.5:
version "0.1.6"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.6.tgz#c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8"
@ -3432,6 +3444,10 @@ js-base64@^2.1.9:
version "2.1.9"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce"
js-cookie@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.1.3.tgz#48071625217ac9ecfab8c343a13d42ec09ff0526"
js-tokens@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.0.tgz#a2f2a969caae142fb3cd56228358c89366957bd1"
@ -5028,11 +5044,11 @@ pseudomap@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
punycode@1.3.2:
punycode@1.3.2, punycode@^1.2.4:
version "1.3.2"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
punycode@^1.2.4, punycode@^1.4.1:
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
@ -5658,6 +5674,15 @@ sharetribe-scripts@0.8.6:
optionalDependencies:
fsevents "1.0.14"
"sharetribe-sdk@git+ssh://git@github.com/sharetribe/sharetribe-sdk-js.git":
version "0.0.1"
resolved "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js.git#037a4328da4926428f6d36f19d349186d06f8aad"
dependencies:
axios "^0.15.3"
js-cookie "^2.1.3"
lodash "^4.17.4"
transit-js "^0.8.846"
shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
@ -6021,6 +6046,10 @@ tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
transit-js@^0.8.846:
version "0.8.846"
resolved "https://registry.yarnpkg.com/transit-js/-/transit-js-0.8.846.tgz#76e06e8f0e6be27675e3442112f5c9bb75343464"
tryit@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb"