Add helper to get denormalised entities from an SDK response

This commit is contained in:
Kimmo Puputti 2018-01-19 11:18:00 +02:00
parent 9a64952105
commit ed2319e781
7 changed files with 55 additions and 32 deletions

View file

@ -1,5 +1,5 @@
import { pick } from 'lodash';
import { updatedEntities, denormalisedEntities } from '../../util/data';
import { denormalisedResponseEntities } from '../../util/data';
import { storableError } from '../../util/errors';
import { TRANSITION_REQUEST } from '../../util/types';
import * as log from '../../util/log';
@ -176,10 +176,11 @@ export const speculateTransaction = (listingId, bookingStart, bookingEnd) => (
return sdk.transactions
.initiateSpeculative(bodyParams, queryParams)
.then(response => {
const transactionId = response.data.data.id;
const entities = updatedEntities({}, response.data);
const denormalised = denormalisedEntities(entities, 'transaction', [transactionId]);
const tx = denormalised[0];
const entities = denormalisedResponseEntities(response);
if (entities.length !== 1) {
throw new Error('Expected a resource in the sdk.transactions.initiateSpeculative response');
}
const tx = entities[0];
dispatch(speculateTransactionSuccess(tx));
})
.catch(e => {

View file

@ -2,7 +2,7 @@ import { pick } from 'lodash';
import { types as sdkTypes } from '../../util/sdkLoader';
import { storableError } from '../../util/errors';
import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck';
import { updatedEntities, denormalisedEntities } from '../../util/data';
import { denormalisedResponseEntities } from '../../util/data';
import { TRANSITION_ENQUIRE } from '../../util/types';
import { fetchCurrentUser } from '../../ducks/user.duck';
@ -117,10 +117,8 @@ export const fetchReviews = listingId => (dispatch, getState, sdk) => {
return sdk.reviews
.query({ listing_id: listingId, state: 'public', include: ['author', 'author.profileImage'] })
.then(response => {
const entities = updatedEntities({}, response.data);
const reviewIds = response.data.data.map(d => d.id);
const denormalized = denormalisedEntities(entities, 'review', reviewIds);
dispatch(fetchReviewsSuccess(denormalized));
const reviews = denormalisedResponseEntities(response);
dispatch(fetchReviewsSuccess(reviews));
})
.catch(e => {
dispatch(fetchReviewsError(storableError(e)));

View file

@ -1,6 +1,6 @@
import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck';
import { fetchCurrentUser } from '../../ducks/user.duck';
import { updatedEntities, denormalisedEntities } from '../../util/data';
import { denormalisedResponseEntities } from '../../util/data';
import { storableError } from '../../util/errors';
// ================ Action types ================ //
@ -139,10 +139,8 @@ export const queryUserReviews = userId => (dispatch, getState, sdk) => {
sdk.reviews
.query({ subject_id: userId, state: 'public', include: ['author', 'author_profile_image'] })
.then(response => {
const entities = updatedEntities({}, response.data);
const reviewIds = response.data.data.map(d => d.id);
const denormalized = denormalisedEntities(entities, 'review', reviewIds);
dispatch(queryReviewsSuccess(denormalized));
const reviews = denormalisedResponseEntities(response);
dispatch(queryReviewsSuccess(reviews));
})
.catch(e => dispatch(queryReviewsError(e)));
};

View file

@ -1,4 +1,4 @@
import { updatedEntities, denormalisedEntities } from '../../util/data';
import { denormalisedResponseEntities } from '../../util/data';
import { storableError } from '../../util/errors';
import { currentUserShowSuccess } from '../../ducks/user.duck';
@ -134,11 +134,11 @@ export const updateProfile = actionPayload => {
.then(response => {
dispatch(updateProfileSuccess(response));
// Include profile image to denormalized user entity
const currentUserId = response.data.data.id;
const entities = updatedEntities({}, response.data);
const denormalised = denormalisedEntities(entities, 'currentUser', [currentUserId]);
const currentUser = denormalised[0];
const entities = denormalisedResponseEntities(response);
if (entities.length !== 1) {
throw new Error('Expected a resource in the sdk.currentUser.updateProfile response');
}
const currentUser = entities[0];
// Update current user in state.user.currentUser through user.duck.js
dispatch(currentUserShowSuccess(currentUser));

View file

@ -10,7 +10,11 @@ import {
TRANSITION_REVIEW_2_BY_PROVIDER,
} from '../../util/types';
import * as log from '../../util/log';
import { updatedEntities, denormalisedEntities } from '../../util/data';
import {
updatedEntities,
denormalisedEntities,
denormalisedResponseEntities,
} from '../../util/data';
import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck';
import { fetchCurrentUserNotifications } from '../../ducks/user.duck';
@ -302,15 +306,13 @@ const fetchMessages = (txId, page) => (dispatch, getState, sdk) => {
return sdk.messages
.query({ transaction_id: txId, include: ['sender', 'sender.profileImage'], ...paging })
.then(response => {
const entities = updatedEntities({}, response.data);
const messageIds = response.data.data.map(d => d.id);
const denormalizedMessages = denormalisedEntities(entities, 'message', messageIds);
const messages = denormalisedResponseEntities(response);
const { totalItems, totalPages, page: fetchedPage } = response.data.meta;
const pagination = { totalItems, totalPages, page: fetchedPage };
const totalMessages = getState().TransactionPage.totalMessages;
// Original fetchMessages call succeeded
dispatch(fetchMessagesSuccess(denormalizedMessages, pagination));
dispatch(fetchMessagesSuccess(messages, pagination));
// Check if totalItems has changed between fetched pagination pages
// if totalItems has changed, fetch first page again to include new incoming messages.

View file

@ -1,4 +1,4 @@
import { updatedEntities, denormalisedEntities } from '../util/data';
import { denormalisedResponseEntities } from '../util/data';
import { storableError } from '../util/errors';
import { TRANSITION_REQUEST, TRANSITION_REQUEST_AFTER_ENQUIRY } from '../util/types';
import * as log from '../util/log';
@ -335,11 +335,12 @@ export const fetchCurrentUser = () => (dispatch, getState, sdk) => {
return sdk.currentUser
.show({ include: ['profileImage'] })
.then(response => {
// Include profile image to denormalized user entity
const currentUserId = response.data.data.id;
const entities = updatedEntities({}, response.data);
const denormalised = denormalisedEntities(entities, 'currentUser', [currentUserId]);
const currentUser = denormalised[0];
const entities = denormalisedResponseEntities(response);
if (entities.length !== 1) {
throw new Error('Expected a resource in the sdk.currentUser.show response');
}
const currentUser = entities[0];
// set current user id to the logger
log.setUserId(currentUser.id.uuid);
dispatch(currentUserShowSuccess(currentUser));

View file

@ -104,6 +104,29 @@ export const denormalisedEntities = (entities, type, ids) => {
});
};
/**
* Denormalise the data from the given SDK response
*
* @param {Object} sdkResponse response object from an SDK call
*
* @return {Array} entities in the response with relationships
* denormalised from the included data
*/
export const denormalisedResponseEntities = sdkResponse => {
const apiResponse = sdkResponse.data;
const data = apiResponse.data;
const resources = Array.isArray(data) ? data : [data];
if (!data || resources.length === 0) {
return [];
}
const entities = updatedEntities({}, apiResponse);
const type = resources[0].type;
const resourceIds = resources.map(r => r.id);
return denormalisedEntities(entities, type, resourceIds);
};
/**
* Create shell objects to ensure that attributes etc. exists.
*