Last active
January 16, 2018 22:05
-
-
Save colorfield/6baae95d6211e45168e462a34ec93fcf to your computer and use it in GitHub Desktop.
React fetch on the route
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import Layout from '../../components/Layout'; | |
import ItineraryListPage from './ItineraryListPage'; | |
import { JSON_API_URL } from '../../constants/env'; | |
const title = 'Audioguide'; | |
async function action({ locale, fetch }) { | |
// Use Drupal locale (e.g. convert en-US to en). | |
const languageId = locale.substring(0, 2); | |
// Fetch the localized terms. | |
// Sort by weight is the default value, but we define it explicitly. | |
// Get only the parent term, this is defined via a boolean field because | |
// currently there is no JSON API way to get only parents. | |
const endpoint = `${JSON_API_URL}/${languageId}/jsonapi/taxonomy_term/itinerary?filter[field_is_parent][value]=1&filter[langcode][value]=${languageId}&sort=weight&include=field_image`; | |
const response = await fetch(endpoint, { method: 'GET' }); | |
const terms = await response.json(); | |
return { | |
chunks: ['itineraries'], | |
title, | |
component: ( | |
<Layout> | |
<ItineraryListPage title={title} itineraries={terms} /> | |
</Layout> | |
), | |
}; | |
} | |
export default action; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import PropTypes from 'prop-types'; | |
import withStyles from 'isomorphic-style-loader/lib/withStyles'; | |
import s from './ItineraryListPage.css'; | |
import ItineraryTeaser from '../../components/ItineraryTeaser'; | |
import ItineraryListHeader from '../../components/ItineraryListHeader'; | |
import { JSON_API_URL } from '../../constants/env'; | |
class ItineraryListPage extends React.Component { | |
// @todo we should define all the propTypes | |
// including the relationships used for the image. | |
static propTypes = { | |
itineraries: PropTypes.shape({ | |
data: PropTypes.arrayOf( | |
PropTypes.shape({ | |
id: PropTypes.string.isRequired, | |
}).isRequired, | |
).isRequired, | |
included: PropTypes.arrayOf( | |
PropTypes.shape({ | |
id: PropTypes.string.isRequired, | |
}).isRequired, | |
).isRequired, | |
}).isRequired, | |
}; | |
getImageFromIncluded(imageId) { | |
let result = null; | |
const image = this.props.itineraries.included.filter( | |
obj => obj.id === imageId, | |
); | |
if (image[0]) { | |
result = `${JSON_API_URL}/${image[0].attributes.url}`; | |
} | |
return result; | |
} | |
/** | |
* Attaches the includes Url to the itineraries data. | |
* | |
* @returns {Array} | |
*/ | |
itinerariesWithIncludedUrl() { | |
const itinerariesWithIncluded = []; | |
this.props.itineraries.data.forEach(itinerary => { | |
const tmpItinerary = itinerary; | |
if (itinerary.relationships.field_image.data !== null) { | |
const iconImageId = itinerary.relationships.field_image.data.id; | |
tmpItinerary.iconImageUrl = this.getImageFromIncluded(iconImageId); | |
} | |
itinerariesWithIncluded.push(tmpItinerary); | |
}); | |
return itinerariesWithIncluded; | |
} | |
render() { | |
return ( | |
<div> | |
<div className={s.container}> | |
<ItineraryListHeader /> | |
<ul className={s.gridPage}> | |
{this.itinerariesWithIncludedUrl().map(itinerary => ( | |
<li key={itinerary.id}> | |
<ItineraryTeaser | |
destination={`/itinerary/${itinerary.id}`} | |
itinerary={itinerary} | |
/> | |
</li> | |
))} | |
</ul> | |
</div> | |
</div> | |
); | |
} | |
} | |
export default withStyles(s)(ItineraryListPage); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment