src_hooks_useLandmarks.ts.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1">
  6. <title> src/hooks/useLandmarks.ts</title>
  7. <script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
  8. <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  9. <script src="./build/entry.js"></script>
  10. <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  11. <!--[if lt IE 9]>
  12. <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  13. <![endif]-->
  14. <link href="https://fonts.googleapis.com/css?family=Roboto:100,400,700|Inconsolata,700" rel="stylesheet">
  15. <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
  16. <link type="text/css" rel="stylesheet" href="https://jmblog.github.io/color-themes-for-google-code-prettify/themes/tomorrow-night.min.css">
  17. <link type="text/css" rel="stylesheet" href="styles/app.min.css">
  18. <link type="text/css" rel="stylesheet" href="styles/iframe.css">
  19. <link type="text/css" rel="stylesheet" href="">
  20. <script async defer src="https://buttons.github.io/buttons.js"></script>
  21. </head>
  22. <body class="layout small-header">
  23. <div id="stickyNavbarOverlay"></div>
  24. <div class="top-nav">
  25. <div class="inner">
  26. <a id="hamburger" role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
  27. <span aria-hidden="true"></span>
  28. <span aria-hidden="true"></span>
  29. <span aria-hidden="true"></span>
  30. </a>
  31. <div class="logo">
  32. </div>
  33. <div class="menu">
  34. <div class="navigation">
  35. <a
  36. href="index.html"
  37. class="link"
  38. >
  39. API Documentation
  40. </a>
  41. </div>
  42. </div>
  43. </div>
  44. </div>
  45. <div id="main">
  46. <div
  47. class="sidebar "
  48. id="sidebarNav"
  49. >
  50. <nav>
  51. <h2><a href="index.html">Documentation</a></h2><div class="category"><h3>Interfaces</h3><ul><li><a href="AddLandmarkProps.html">AddLandmarkProps</a></li><li><a href="CommentProps.html">CommentProps</a></li><li><a href="IdToken.html">IdToken</a></li><li><a href="IntroProps.html">IntroProps</a></li><li><a href="Landmark.html">Landmark</a></li><li><a href="LandmarkDetailsProps.html">LandmarkDetailsProps</a></li><li><a href="LandmarkPinProps.html">LandmarkPinProps</a></li><li><a href="LMComment.html">LMComment</a></li><li><a href="ProfileProps.html">ProfileProps</a></li><li><a href="RegisterProps.html">RegisterProps</a></li><li><a href="UserProfile.html">UserProfile</a></li></ul><h3>Components</h3><ul><li><a href="App.html">App</a></li><li><a href="Atlas.html">Atlas</a></li><li><a href="Comment.html">Comment</a></li><li><a href="PrimaryButton.html">PrimaryButton</a></li><li><a href="Profile.html">Profile</a></li><li><a href="SecondaryButton.html">SecondaryButton</a></li></ul><h3>Global</h3><ul><li><a href="global.html#IconStrings">IconStrings</a></li></ul></div><div class="category"><h2>Hooks</h2><h3>Namespaces</h3><ul><li><a href="useAuth.html">useAuth</a></li><li><a href="useLandmarks.html">useLandmarks</a></li><li><a href="useProfile.html">useProfile</a></li></ul></div><div class="category"><h2>Map</h2><h3>Interfaces</h3><ul><li><a href="UserLocation.html">UserLocation</a></li></ul><h3>Components</h3><ul><li><a href="AddLandmark.html">AddLandmark</a></li><li><a href="LandmarkDetails.html">LandmarkDetails</a></li><li><a href="LandmarkPin.html">LandmarkPin</a></li><li><a href="Map.html">Map</a></li></ul></div><div class="category"><h2>Navigation</h2><h3>Components</h3><ul><li><a href="AuthorizedNavigator.html">AuthorizedNavigator</a></li><li><a href="UnauthorizedNavigator.html">UnauthorizedNavigator</a></li></ul><h3><a href="global.html">Global</a></h3></div><div class="category"><h2>Stores</h2><h3>Classes</h3><ul><li><a href="AuthStore.html">AuthStore</a></li></ul></div><div class="category"><h2>Unauthorized</h2><h3>Components</h3><ul><li><a href="Intro.html">Intro</a></li><li><a href="UnauthorizedLayout.html">UnauthorizedLayout</a></li></ul><h3>Components / Registration</h3><ul><li><a href="RegisterMain.html">RegisterMain</a></li></ul></div>
  52. </nav>
  53. </div>
  54. <div class="core" id="main-content-wrapper">
  55. <div class="content">
  56. <header class="page-title">
  57. <p>Source</p>
  58. <h1>src/hooks/useLandmarks.ts</h1>
  59. </header>
  60. <section>
  61. <article>
  62. <pre class="prettyprint source linenums"><code>// This file houses crud methods to interact with landmarks on the server. They are generally called by react query mutations.
  63. import axios, { AxiosRequestConfig } from "axios"
  64. import { Region } from "react-native-maps";
  65. import { QueryClient, useMutation, useQuery, useQueryClient } from "react-query";
  66. import { API_URL, reportAxiosError as reportAxiosError } from "../globals"
  67. import { authStore } from "../stores/AuthStore";
  68. import { useAuth } from "./useAuth";
  69. /**
  70. * Interface representing a landmark's comment.
  71. */
  72. export interface LMComment {
  73. /**
  74. * The comment's id.
  75. */
  76. id: string,
  77. /**
  78. * The id of the user who posted the comment
  79. */
  80. poster: string,
  81. /**
  82. * The text content of the comment
  83. */
  84. text: string
  85. /**
  86. * The landmark that this comment is associated with.
  87. */
  88. landmark: Landmark
  89. }
  90. /**
  91. * Interface representing a landmark object
  92. */
  93. export interface Landmark {
  94. /**
  95. * The id of the landmark.
  96. */
  97. id?: string | null,
  98. /**
  99. * The rating of the landmark.
  100. */
  101. rating?: number | null,
  102. /**
  103. * The id of the user who created the landmark.
  104. */
  105. user?: string | null,
  106. /**
  107. * The longitude of the landmark's location.
  108. */
  109. longitude?: number | null,
  110. /**
  111. * The latitude of the landmark's location.
  112. */
  113. latitude?: number | null,
  114. /**
  115. * The landmark's title.
  116. */
  117. title?: string | null,
  118. /**
  119. * The landmark's description.
  120. */
  121. description?: string | null,
  122. /**
  123. * User [comments]{@link LMComment} associated with this landmark.
  124. */
  125. comments?: LMComment[] | null,
  126. /**
  127. * An integer representing the type of this landmark.
  128. */
  129. landmark_type?: number | null, // for working with existing database schema, should be changed
  130. /**
  131. * A Date object representing when this landmark was created.
  132. */
  133. time?: Date | null
  134. }
  135. /**
  136. * A custom hook containing [react-query]{@link https://react-query.tanstack.com/} queries and mutations and other logic related to interacting with {@link Landmark} objects.
  137. * @category Hooks
  138. * @namespace useLandmarks
  139. */
  140. export const useLandmarks = (region: Region | undefined) => {
  141. const { refreshAccessToken } = useAuth();
  142. /**
  143. * The local instance of the [react-query QueryClient]{@link https://react-query.tanstack.com/reference/QueryClient#_top}.
  144. * @memberOf useLandmarks
  145. */
  146. let queryClient: QueryClient;
  147. try {
  148. queryClient = useQueryClient()
  149. } catch (error) {
  150. console.log("Something went wrong when retrieving query client:")
  151. console.log(error)
  152. }
  153. /**
  154. * The callback responsible for retrieving {@link Landmark} from the API, used by the [react-query useQuery]{@link https://react-query.tanstack.com/reference/useQuery#_top} hook.
  155. * * @memberOf useLandmarks
  156. */
  157. const getLandmarks = async (region: Region | undefined) => {
  158. // if (region) {
  159. const config: AxiosRequestConfig = {
  160. method: 'GET',
  161. // url: `${API_URL}/api/landmarks/?lat=${region.latitude}&amp;long=${region.longitude}&amp;lat_delta=${region.latitudeDelta}&amp;long_delta=${region.longitudeDelta}`,
  162. url: `${API_URL}/api/landmarks/`,
  163. headers: { "Authorization": "Bearer " + authStore.accessToken, }
  164. }
  165. try {
  166. const response = await axios(config);
  167. return response.data;
  168. } catch (error) {
  169. if (error.response.status == 401) {
  170. try {
  171. await refreshAccessToken()
  172. const response = await axios({...config, headers: { "Authorization": "Bearer " + authStore.accessToken }});
  173. return response.data;
  174. } catch (error) {
  175. // refreshAccessToken will report errors
  176. }
  177. }
  178. reportAxiosError('Something went wrong when retrieving landmarks', error)
  179. throw new Error;
  180. }
  181. // }
  182. // else {
  183. // return [];
  184. // }
  185. }
  186. /**
  187. * The callback responsible for adding a new {@link Landmark} to the server, used by the [react-query useMutation]{@link https://react-query.tanstack.com/reference/useMutation#_top} hook.
  188. * * @memberOf useLandmarks
  189. */
  190. const createLandmark = async (landmarkValue: Landmark | undefined): Promise&lt;Landmark | undefined> => {
  191. const config: AxiosRequestConfig = {
  192. method: 'POST',
  193. data: landmarkValue,
  194. url: API_URL + `/api/landmark/`,
  195. headers: { "Authorization": "Bearer " + authStore.accessToken, }
  196. }
  197. try {
  198. const response = await axios(config);
  199. return response.data;
  200. } catch (error) {
  201. if (error.response.status == 401) {
  202. try {
  203. await refreshAccessToken()
  204. const response = await axios({...config, headers: { "Authorization": "Bearer " + authStore.accessToken }});
  205. return response.data;
  206. } catch (error) {
  207. // refreshAccessToken will report errors
  208. }
  209. }
  210. reportAxiosError('Something went wrong when retrieving landmarks', error)
  211. throw new Error;
  212. }
  213. }
  214. /**
  215. * The callback responsible for updating a {@link Landmark} on the server, used by the [react-query useMutation]{@link https://react-query.tanstack.com/reference/useMutation#_top} hook.
  216. * * @memberOf useLandmarks
  217. */
  218. const editLandmark = async (landmarkValue: Landmark) => {
  219. const config: AxiosRequestConfig = {
  220. method: 'PUT',
  221. data: landmarkValue,
  222. url: API_URL + `/api/landmark/`,
  223. headers: { "Authorization": "Bearer " + authStore.accessToken, }
  224. }
  225. console.log(landmarkValue)
  226. try {
  227. const response = await axios(config);
  228. return response.data;
  229. } catch (error) {
  230. if (error.response.status == 401) {
  231. try {
  232. await refreshAccessToken()
  233. const response = await axios({...config, headers: { "Authorization": "Bearer " + authStore.accessToken }});
  234. return response.data;
  235. } catch (error) {
  236. // refreshAccessToken will report errors
  237. }
  238. }
  239. reportAxiosError('Something went wrong when retrieving landmarks', error)
  240. throw new Error;
  241. }
  242. }
  243. /**
  244. * The callback responsible for deleting a {@link Landmark} from the server, used by the [react-query useMutation]{@link https://react-query.tanstack.com/reference/useMutation#_top} hook.
  245. * * @memberOf useLandmarks
  246. */
  247. const removeLandmark = async (id?: string | null) => {
  248. const config: AxiosRequestConfig = {
  249. method: 'DELETE',
  250. url: API_URL + `/api/landmark/${id}`,
  251. headers: { "Authorization": "Bearer " + authStore.accessToken, }
  252. }
  253. try {
  254. const response = await axios(config);
  255. return response.data;
  256. } catch (error) {
  257. if (error.response.status == 401) {
  258. try {
  259. await refreshAccessToken()
  260. // add new access token to header
  261. const response = await axios({...config, headers: {"Authorization": "Bearer " + authStore.accessToken}});
  262. return response.data;
  263. } catch (error) {
  264. // refreshAccessToken will report errors
  265. }
  266. }
  267. reportAxiosError('Something went wrong when retrieving landmarks', error)
  268. throw new Error;
  269. }
  270. }
  271. // get-all query
  272. const { data: landmarks, status: getLandmarksStatus, refetch: refetchLandmarks } = useQuery&lt;Landmark[], Error>(['getLandmarks', region], () => getLandmarks(region), {
  273. placeholderData: () => queryClient.getQueryData('getLandmarks'),
  274. staleTime: 1000,
  275. refetchInterval: 30000,
  276. refetchOnReconnect: true,
  277. refetchOnMount: false
  278. })
  279. // mutations
  280. const { status: addLandmarkStatus, mutateAsync: addLandmarkAsync, reset: resetAddLm, data: newLandmark } = useMutation(createLandmark, {
  281. onSuccess: data => {
  282. queryClient.invalidateQueries('getLandmarks')
  283. },
  284. })
  285. const { status: updateLandmarkStatus, mutateAsync: updateLandmark, reset: resetUpdateLm } = useMutation(editLandmark, {
  286. onSuccess: () => queryClient.invalidateQueries('getLandmarks'),
  287. onError: () => queryClient.invalidateQueries('getLandmarks'),
  288. })
  289. const { status: deleteLandmarkStatus, mutateAsync: deleteLandmark, reset: resetDeleteLm } = useMutation(removeLandmark, {
  290. onSuccess: () => queryClient.invalidateQueries('getLandmarks'),
  291. onError: () => queryClient.invalidateQueries('getLandmarks'),
  292. })
  293. return {
  294. landmarks, getLandmarksStatus, refetchLandmarks, //reading
  295. addLandmarkAsync, resetAddLm, addLandmarkStatus, newLandmark, // creating
  296. updateLandmark, resetUpdateLm, updateLandmarkStatus, // updating
  297. deleteLandmark, resetDeleteLm, deleteLandmarkStatus, // deleting
  298. }
  299. }
  300. </code></pre>
  301. </article>
  302. </section>
  303. </div>
  304. <footer class="footer">
  305. <div class="content has-text-centered">
  306. <p>Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.7</a></p>
  307. <p class="sidebar-created-by">
  308. <a href="https://github.com/SoftwareBrothers/better-docs" target="_blank">BetterDocs theme</a> provided with <i class="fas fa-heart"></i> by
  309. <a href="http://softwarebrothers.co" target="_blank">SoftwareBrothers - JavaScript Development Agency</a>
  310. </p>
  311. </div>
  312. </footer>
  313. </div>
  314. <div id="side-nav" class="side-nav">
  315. </div>
  316. </div>
  317. <script src="scripts/app.min.js"></script>
  318. <script>PR.prettyPrint();</script>
  319. <script src="scripts/linenumber.js"> </script>
  320. </body>
  321. </html>