fetchEvent.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import * as React from 'react';
  2. import {Client} from 'app/api';
  3. import {Event} from 'app/types/event';
  4. import withApi from 'app/utils/withApi';
  5. export type ChildrenProps = {
  6. isLoading: boolean;
  7. error: null | string;
  8. event: Event | undefined;
  9. };
  10. type Props = {
  11. api: Client;
  12. orgSlug: string;
  13. eventSlug: string;
  14. children: (props: ChildrenProps) => React.ReactNode;
  15. };
  16. type State = {
  17. tableFetchID: symbol | undefined;
  18. } & ChildrenProps;
  19. class FetchEvent extends React.Component<Props, State> {
  20. state: State = {
  21. isLoading: true,
  22. tableFetchID: undefined,
  23. error: null,
  24. event: undefined,
  25. };
  26. componentDidMount() {
  27. this.fetchData();
  28. }
  29. componentDidUpdate(prevProps: Props) {
  30. const orgSlugChanged = prevProps.orgSlug !== this.props.orgSlug;
  31. const eventSlugChanged = prevProps.eventSlug !== this.props.eventSlug;
  32. if (!this.state.isLoading && (orgSlugChanged || eventSlugChanged)) {
  33. this.fetchData();
  34. }
  35. }
  36. fetchData() {
  37. const {orgSlug, eventSlug} = this.props;
  38. // note: eventSlug is of the form <project-slug>:<event-id>
  39. const url = `/organizations/${orgSlug}/events/${eventSlug}/`;
  40. const tableFetchID = Symbol('tableFetchID');
  41. this.setState({isLoading: true, tableFetchID});
  42. this.props.api
  43. .requestPromise(url, {
  44. method: 'GET',
  45. })
  46. .then(data => {
  47. if (this.state.tableFetchID !== tableFetchID) {
  48. // invariant: a different request was initiated after this request
  49. return;
  50. }
  51. this.setState({
  52. isLoading: false,
  53. tableFetchID: undefined,
  54. error: null,
  55. event: data,
  56. });
  57. })
  58. .catch(err => {
  59. this.setState({
  60. isLoading: false,
  61. tableFetchID: undefined,
  62. error: err?.responseJSON?.detail ?? null,
  63. event: undefined,
  64. });
  65. });
  66. }
  67. render() {
  68. const {isLoading, error, event} = this.state;
  69. const childrenProps: ChildrenProps = {
  70. isLoading,
  71. error,
  72. event,
  73. };
  74. return this.props.children(childrenProps);
  75. }
  76. }
  77. export default withApi(FetchEvent);