{"componentChunkName":"component---src-templates-assignment-template-js","path":"/practicals/practical03","webpackCompilationHash":"041090671d318979d692","result":{"data":{"markdownRemark":{"htmlAst":{"type":"root","children":[{"type":"element","tagName":"h4","properties":{"id":"goals"},"children":[{"type":"element","tagName":"a","properties":{"href":"#goals","ariaLabel":"goals permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Goals"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Convert Film Explorer to use a RESTful API to fetch data"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Practice using "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"fetch"}]},{"type":"text","value":" and Promises"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"See how the CRA development server can be integrated with another content server during development."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Today, you will be converting the "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/csci312-f19/example-filmexplorer-standalone"},"children":[{"type":"text","value":"standalone version of Film Explorer"}]},{"type":"text","value":" to use "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"fetch"}]},{"type":"text","value":" to load its data. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"prerequisites"},"children":[{"type":"element","tagName":"a","properties":{"href":"#prerequisites","ariaLabel":"prerequisites permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Prerequisites"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Click through to the GitHub "},{"type":"element","tagName":"a","properties":{"href":"https://classroom.github.com/a/nM5tWNjt"},"children":[{"type":"text","value":"classroom assignment"}]},{"type":"text","value":" to create your private repository. Then clone that newly created repository to your local computer as you have done previously."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Install the package dependencies by running "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm install"}]},{"type":"text","value":" inside the root\ndirectory of the newly cloned repository. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You may see warnings like the following. These can be ignored for this practical."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"npm WARN ts-pnp@1.0.1 requires a peer of typescript@* but none was installed.\nnpm WARN jest-styled-components@6.3.1 requires a peer of styled-components@^2.0.0 || ^3.0.2 but none was installed."}]}]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Before you make any changes, create a feature branch named \"use-fetch\" to segregate your modifications from the master branch:"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"git checkout -b use-fetch"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h1","properties":{"id":"fetching-data-with-ajax"},"children":[{"type":"element","tagName":"a","properties":{"href":"#fetching-data-with-ajax","ariaLabel":"fetching data with ajax permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Fetching Data with AJAX"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This version of Film Explorer, much like Simplepedia is making use of webpack to load the data via an "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" statement. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" filmData "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./films.json'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"While this works, it is atypical. It can cause long initial load times and worse, it means the user only works with a local version of the data, so changes don't persist (try rating a few films and then reloading the page). Your task today is to adapt the standalone Film Explorer to fetch its data from the Film Explorer API and persist the ratings."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"proxying"},"children":[{"type":"element","tagName":"a","properties":{"href":"#proxying","ariaLabel":"proxying permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Proxying"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You will be communicating with a server running on basin at\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"http://basin.cs.middlebury.edu:5042"}]},{"type":"text","value":". The REST interface can be found at\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"/api/films"}]},{"type":"text","value":", which can be optionally followed by an id. The full API is:"}]},{"type":"text","value":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"},{"type":"element","tagName":"table","properties":{},"children":[{"type":"element","tagName":"thead","properties":{},"children":[{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"th","properties":{},"children":[{"type":"text","value":"Endpoint"}]},{"type":"element","tagName":"th","properties":{},"children":[{"type":"text","value":"Method"}]},{"type":"element","tagName":"th","properties":{},"children":[{"type":"text","value":"Action"}]}]}]},{"type":"element","tagName":"tbody","properties":{},"children":[{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"/api/films"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"GET"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Fetch the entire movie collection as a JSON array"}]}]},{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"/api/films/"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"id"}]}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"GET"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Fetch the movie with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"id"}]},{"type":"text","value":" as JSON"}]}]},{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"/api/films/"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"id"}]}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"PUT"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Update the movie with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"id"}]},{"type":"text","value":" (the new JSON-serialized movie object should be in the request body)"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You can interact with this API directly in your browser by visiting "},{"type":"element","tagName":"a","properties":{"href":"http://basin.cs.middlebury.edu:5042/api/films"},"children":[{"type":"text","value":"http://basin.cs.middlebury.edu:5042/api/films"}]},{"type":"text","value":", to see a full list of the movies, or "},{"type":"element","tagName":"a","properties":{"href":"http://basin.cs.middlebury.edu:5042/api/films/11"},"children":[{"type":"text","value":"http://basin.cs.middlebury.edu:5042/api/films/11"}]},{"type":"text","value":" to see the movie with an "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"id"}]},{"type":"text","value":" of 11 (Star Wars). "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"CRA supports "},{"type":"element","tagName":"a","properties":{"href":"https://facebook.github.io/create-react-app/docs/proxying-api-requests-in-development#docsNav"},"children":[{"type":"text","value":"proxying"}]},{"type":"text","value":" API requests in development. That is, the development server (which you started with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm start"}]},{"type":"text","value":") will proxy any requests that aren't for static assets to another port or server. This helps us mimic in development the typical production setup in which the React app is served from the same host and port as the back-end implementation, and thus you can write "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"fetch('/api/films')"}]},{"type":"text","value":"\n(instead of "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"fetch('http://basin.cs.middlebury.edu:5042/api/films')"}]},{"type":"text","value":")."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To enable proxying to another server in development, you can add a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"\"proxy\""}]},{"type":"text","value":" field to your "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":" file, e.g.:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"json"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-json"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-json"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"\"proxy\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"http://basin.cs.middlebury.edu:5042\""}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Do this now. Remember that JSON key-value pairs need to be separated by commas. Thus depending where you add the above line among the top-level fields in your "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":" file, you may need to add a comma before or after. Once you have updated the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":" file, start the development server with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm start"}]},{"type":"text","value":". If you have already started the development server you will need to restart it anytime you make changes to the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":" file (the auto-reload for the development server or the test runner can't detect changes in "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":")."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":" You may see errors like this in the console:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"Could not proxy request /sockjs-node/086/t4nmjsb1/websocket from localhost:3000 to http://basin.cs.middlebury.edu:5042."}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This seems to have something to do with the internals of the react development server and does not seem to actually effect the running of the application."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"fetching-the-films"},"children":[{"type":"element","tagName":"a","properties":{"href":"#fetching-the-films","ariaLabel":"fetching the films permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Fetching the Films"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Following the example in class, adapt the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmExplorer"}]},{"type":"text","value":" component (in "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmExplorer.js"}]},{"type":"text","value":") to fetch its data from the server API. Specifically:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Step one"}]},{"type":"text","value":": Comment out the line "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"import filmData from './films.json';"}]},{"type":"text","value":" as we will no longer load the movies directly."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Step two"}]},{"type":"text","value":": Replace the simple call to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"setFilms"}]},{"type":"text","value":" with the fetch call shown in lecture."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/api/films/'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"response"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"ok"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"throw"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"statusText"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"data"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setFilms"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"List"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"catch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// eslint-disable-line no-console"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Launch the development server with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm start"}]},{"type":"text","value":". Make sure you can successfully load the movie data from the server."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"updating-the-movie-rating"},"children":[{"type":"element","tagName":"a","properties":{"href":"#updating-the-movie-rating","ariaLabel":"updating the movie rating permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Updating the Movie Rating"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In the standalone Film Explorer the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"setRating"}]},{"type":"text","value":" method in the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"FilmExplorer"}]},{"type":"text","value":" component uses "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"map()"}]},{"type":"text","value":" to create a new list in which the film object being rated is replaced with a new one with a new rating. Your next task will be to modify this function to persist changes back to the server."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Rather than starting by updating the objects and the List that encloses it, we will first create a modified version of the film, and send it to the server. The server will update its record and send the film's data back. Once the response has been received, you can modify the state with the new record. By using the data returned from the server, we are giving the server the opportunity to validate and possibly further modify the data (in this case, the data is not being further modified, but we will see instances when this is important later)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The steps in your new "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"setRating"}]},{"type":"text","value":" method (replacing all of the existing code):"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Step one"}]},{"type":"text","value":": Comment out the body of the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"setRating"}]},{"type":"text","value":" function. We will want to refer back to this later. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Step two"}]},{"type":"text","value":": Find the full record for the film being modified. Since the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"setRating"}]},{"type":"text","value":" method only has the movie's id, you will need to use the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"find"}]},{"type":"text","value":" method on the List to obtain the complete film object. While "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"films"}]},{"type":"text","value":" is an Immutable.List object, you will find that the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"find"}]},{"type":"text","value":" function works the same as "},{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find"},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"Array.find"}]}]},{"type":"text","value":", which has better documentation."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Step three"}]},{"type":"text","value":": Create an updated film object with the new rating. Recall that you don't want to modify state, so make a copy of the movie using the spread pattern, i.e."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" newFilm "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":"oldFilm"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" rating"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" rating"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Step four"}]},{"type":"text","value":": Construct your PUT request to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"`/api/films/${filmid}`"}]},{"type":"text","value":" (URL created with string interpolation). By default "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"fetch"}]},{"type":"text","value":" uses GET. To create a PUT request, supply an optional "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"init"}]},{"type":"text","value":" argument specifying the method, body (serialized JSON representation of the new movie object) and headers specifying that the client is sending JSON\n("},{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch"},"children":[{"type":"text","value":"docs"}]},{"type":"text","value":"):"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"/api/films/"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"filmid"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    method"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'PUT'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    body"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","constant"]},"children":[{"type":"text","value":"JSON"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"stringify"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"newFilm"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    headers"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Headers"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Content-type'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'application/json'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Step five"}]},{"type":"text","value":": Use a Promise to read the response. This response will be in JSON, just as it was for the initial "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"fetch"}]},{"type":"text","value":". You can copy and paste the code you used for the full collection of data with respect to the chained promises that receive the response and then parse it."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Step six"}]},{"type":"text","value":": Update the state with the new data. If you copied and pasted the response above, the code will attempt to change the state variable "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"films"}]},{"type":"text","value":" to the new data, which we don't want because we only have a single film now. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Instead, use the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"map"}]},{"type":"text","value":" pattern from the commented out code to create a new List, replacing the old film record with the new one. You do not need to use the spread syntax, just return the new film record at the appropriate moment."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Step seven"}]},{"type":"text","value":": Try it out. Rate some things. You should see that they will persist when you reload the page now. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Note that you are all sharing the same server now, so when you make a change, you are actually changing the rating for everyone. However, since we don't poll for changes, and we only receive data about films that we just changed, you won't see the effect of this unless you reload the page."}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"finishing-up"},"children":[{"type":"element","tagName":"a","properties":{"href":"#finishing-up","ariaLabel":"finishing up permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Finishing Up"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To finish up, we are going to merge the changes you made back into the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"master"}]},{"type":"text","value":" branch. Rather than doing this directly on the command line, we are going to make use of GitHub's \"pull request\" (PR) mechanism. This is about building habits that will be useful when we get to working on teams. The PR signals that you are ready to merge into the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"master"}]},{"type":"text","value":"  branch and gives other team members an opportunity to review your changes before "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"master"}]},{"type":"text","value":" is updated."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Add and commit your changes to your "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"use-fetch"}]},{"type":"text","value":" branch. Push those changes GitHub on the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"use-fetch"}]},{"type":"text","value":" branch."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"git push origin use-fetch"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Open your repository at GitHub and create a pull request (PR) to merge the changes from your newly pushed "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"use-fetch"}]},{"type":"text","value":" branch onto the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"master"}]},{"type":"text","value":" branch. You should be able to create the PR on the main page of your repository or alternately you can create a PR from the \"Pull request\" tab."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Navigate to the page for your PR. Here you will see some notification indicating if the branch can be cleanly merged into the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"master"}]},{"type":"text","value":" branch. Make sure it indicates that a good merge can be made. press the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"Merge"}]},{"type":"text","value":" button to merge your changes. Once you have merged the changes you can delete the feature branch on GitHub using the button that replaces the 'Merge' button."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Clean up your local repository after the merge. Return to the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"master"}]},{"type":"text","value":" branch on your local computer, pull the changes from GitHub pruning deleted remote tracking references. Then delete your local branch. To avoid mistakes when deleting branches, add the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"--dry-run"}]},{"type":"text","value":" option to the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"--prune"}]},{"type":"text","value":" option, e.g. "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"git pull --prune --dry-run"}]},{"type":"text","value":" to double check before actually pruning anything. The command sequence is:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"git checkout master\ngit pull --prune\ngit branch -d use-fetch"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Finally, submit your repository on Gradescope."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"grading"},"children":[{"type":"element","tagName":"a","properties":{"href":"#grading","ariaLabel":"grading permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Grading"}]},{"type":"text","value":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"},{"type":"element","tagName":"table","properties":{},"children":[{"type":"element","tagName":"thead","properties":{},"children":[{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"th","properties":{},"children":[{"type":"text","value":"Points"}]},{"type":"element","tagName":"th","properties":{},"children":[{"type":"text","value":"Requirement"}]}]}]},{"type":"element","tagName":"tbody","properties":{},"children":[{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"✓/✗"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Use "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"fetch"}]},{"type":"text","value":" to fetch data"}]}]},{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"✓/✗"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Update "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"setRating"}]},{"type":"text","value":" to persist changes on the server"}]}]},{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"✓/✗"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Passes all ESLint checks"}]}]}]}]}],"data":{"quirksMode":false}},"frontmatter":{"dueDate":"2019-10-02 5p","path":"/practicals/practical03","title":"CS 312 - Practical Three","name":"Practical 3"},"parent":{"__typename":"File","id":"a710ff2c-38ba-59a0-b589-53b2c0edaa14","name":"practical03-fetch","modifiedTime":"Oct 1 2019 18:33"}}},"pageContext":{"isCreatedByStatefulCreatePages":false}}}