Guest User

Untitled

a guest
Nov 15th, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.91 KB | None | 0 0
  1. import React, {Component} from 'react';
  2. import axios from 'axios';
  3. import hash from 'object-hash';
  4.  
  5. const hasAxiosClient = (baseURL, delay = 0) => WrappedComponent => {
  6. class HasAxiosClient extends Component {
  7.  
  8. // Consumers can track the state of any request done in the hasAxiosClient HOC
  9. // Nice for "global" loaders - alternatively all requests returns a promise so you can handle
  10. // it individually. Think of this loading state property as an <ErrorBoundary>.
  11. state = {
  12. loading: false
  13. }
  14.  
  15. axiosInstance = axios.create({
  16. baseURL
  17. });
  18.  
  19. // Keep track of any requests in transit so we can prevent spamming requests
  20. requestCache = new Map();
  21.  
  22. constructor(props) {
  23. super(props);
  24. }
  25.  
  26. get = (path, params) =>
  27. this._request({
  28. url: path,
  29. method: 'get',
  30. params
  31. });
  32.  
  33. remove = (path, params) =>
  34. this._request({
  35. url: path,
  36. method: 'delete',
  37. params
  38. });
  39.  
  40. post = (path, data, params) =>
  41. this._request({
  42. url: path,
  43. method: 'post',
  44. data,
  45. params
  46. });
  47.  
  48. put = (path, data, params) =>
  49. this._request({
  50. url: path,
  51. method: 'put',
  52. data,
  53. params
  54. });
  55.  
  56. patch = (path, data, params) =>
  57. this._request({
  58. url: path,
  59. method: 'patch',
  60. data,
  61. params
  62. });
  63.  
  64. _request(config) {
  65. this.setState({loading: true});
  66.  
  67. const fullPath = `${this.axiosInstance.defaults.baseURL}/${config.url}`;
  68. // Unique cache key based on request method, url, query params and more
  69. const cacheKey = hash({path: fullPath, ...config});
  70.  
  71. // We dont have a request in transit already, go ahead and make one
  72. if(!this.requestCache.has(cacheKey)) {
  73.  
  74. this.requestCache.set(
  75. cacheKey,
  76. this.axiosInstance.request(config)
  77. // It's possible to set a delay for all requests when using this HOC, nice for debug / dummy data
  78. .then(response => this._delayResponse(response, delay))
  79. .then(data => {
  80. // Clear our request cache - we are done, let others do their stuff
  81. this.requestCache.delete(cacheKey);
  82. this.setState({loading: false});
  83. return data;
  84. })
  85. .catch(err => {
  86.  
  87. // TODO: delay error responses
  88. this.requestCache.delete(cacheKey);
  89. this.setState({loading: false});
  90.  
  91. return Promise.reject(err);
  92.  
  93. })
  94. );
  95.  
  96. }
  97.  
  98. return this.requestCache.get(cacheKey);
  99.  
  100. }
  101.  
  102. _delayResponse(response, delay = 0) {
  103. return new Promise(resolve => {
  104. setTimeout(() => {
  105. resolve(response.data || {});
  106. }, delay);
  107. });
  108. }
  109.  
  110. render() {
  111.  
  112. const {loading} = this.state;
  113.  
  114. const {
  115. get,
  116. remove,
  117. post,
  118. put,
  119. patch
  120. } = this;
  121.  
  122. return (
  123. <WrappedComponent
  124. loading={loading}
  125. get={get}
  126. delete={remove}
  127. post={post}
  128. put={put}
  129. patch={patch}
  130. />
  131. );
  132. }
  133. }
  134.  
  135. return HasAxiosClient;
  136. };
  137.  
  138. export default hasAxiosClient;
Add Comment
Please, Sign In to add comment