Book Image

Advanced JavaScript

By : Zachary Shute
3 (1)
Book Image

Advanced JavaScript

3 (1)
By: Zachary Shute

Overview of this book

If you are looking for a programming language to develop flexible and efficient applications, JavaScript is an obvious choice. Advanced JavaScript is a hands-on guide that takes you through JavaScript and its many features, one step at a time. You'll begin by learning how to use the new JavaScript syntax in ES6, and then work through the many other features that modern JavaScript has to offer. As you progress through the chapters, you’ll use asynchronous programming with callbacks and promises, handle browser events, and perform Document Object Model (DOM) manipulation. You'll also explore various methods of testing JavaScript projects. In the concluding chapters, you'll discover functional programming and learn to use it to build your apps. With this book as your guide, you'll also be able to develop APIs using Node.js and Express, create front-ends using React/Redux, and build mobile apps using React/Expo. By the end of Advanced JavaScript, you will have explored the features and benefits of JavaScript to build small applications.
Table of Contents (9 chapters)

Chapter 6: JavaScript Ecosystem


Activity 6 – Building a Frontend with React

The frontend team working on your note-taking app from Exercise 35 has unexpectedly quit. You must build the frontend for this application using React. Your frontend should have two views: a Home view and an Edit view. Create a React component for each view. The Home view should have a button that changes the view to the Edit view. The Edit view should have a button that switches back to the Home view, a text input that contains the note text, a load button that calls the API load route, and a save button that calls the API save route. A Node.js server has been provided. Write your React code in activities/activity6/activity/src/index.js. When you are ready to test your code, run the build script (defined in package.json) before starting the server. You can reference the index.html file from Exercise 35 for hints on how to call the API routes.

To build a working React frontend and integrate it with a Node.js express server, follow these steps:

  1. Begin working in "activity/activity6/activity". Run npm install to install the required dependencies.

  2. In src/index.js, create React components called Home and Editor.

  3. Add a constructor to the App react component. In the constructor:

    Take in the props variable. Call super and pass props into super.

    Set the state object in the this scope. It must have a property called view with the value home.

  4. Add a changeView method to the app.

    The changeView method should take in a parameter called view.

    Update the state with setState and set the view property of the state equal to the provided parameter view.

    In the constructor, add a line that sets this.changeView equal to this.changeView.bind(this).

  5. In App’s render function, create a conditional rendering based on the value of this.state.view that does the following:

    If state.view is equal to home, show the home view. Otherwise, show the editor view.

    Pass the changeView function as a parameter to both views, which are <Editor changeView={this.changeView}/> and <Home changeView={this.changeView}/>.

  6. In the Home component, add a goEdit() function, which calls the changeView function passed in through props (this.props.changeView). and passes in the string editor to the changeView function.

  7. Create the render function in the Home component:

    Return a JSX expression.

    To the returned JSX expression, add a div that contains a title heading title of the app Note Editor App, and add a button that changes the view to the Edit view.

    The button should call the goEdit function on click. Be sure to properly bind the this state to the goEdit function.

  8. Add a constructor to the Editor component:

    Take in the props parameter

    Call super and pass in the props variable.

    Set the state variable in the this scope equal to the {value: ‘’} object.

  9. Add a function called handleChage to Editor:

    Takes in an argument, e, that represents the event object.

    Update the state with setState to set the state property value equal to the event target’s value:

    this.setState( { value: e.target.value } );
  10. Create a save function in Editor that makes an HTTP request to the API save route.

    Create a new XHR request and save it into the xhttp variable.

    Set the xhttp property onreadystatechange to a function that checks if this.readyState is equal to 4. If it is not, then return. Also, check if this.status is equal to 200. If it is not, then throw an error.

    Open the xhr request by calling the open function on xhttp. Pass in the parameters POST, /save, and true.

    Set the request header Content-Type to application/json;charset=UTF-8 by calling the setRequestHeader on the xhttp object. Pass in the values specified.

    Send the JSON data of the text input with xhttp.send.

    The value to which, we must send is stored in this.state. Stringify the value before sending it.

  11. Create a load function in Editor that makes an HTTP request to the API load route.

    Create a new XHR request and save it into the xhttp variable.

    Save the this scope into a variable called that so that it can be used inside the xhr request.

    Set the xhttp property onreadystatechange to a function that checks if this.readyState is equal to 4. If it isn’t, then return. It then checks if this.status is equal to 200. If it is not, then throw an error. It calls the setState function on the React component’s scope, which is saved in the that variable.

    Pass in an object with the key value equal to the parsed response of the request. Parse the HTTP response value from the this.response variable with the JSON.parse function.

    Open the HTTP request by calling the open function on the xhttp variable. Pass in the parameters GET, /load, and true.

    Send the XHR request by calling the send() method on the xhttp object.

  12. Create a goHome function in Editor.

    Call the changeView function that was passed in through the React element properties object (this.props.changeView()).

    Pass in the string home.

  13. Create the render function in Editor.

    Add a button that, once clicked, calls the goHome function that contains the text Back to home. It calls the goHome function on the click event. Make sure to properly bind the this scope to the function.

    Add a text input that contains the note text. The text input loads its value from the state.value field. The text field calls the handleChange function on a change event. Make sure to properly bind the this scope to the handleChange function.

    Add a button to load the note data from the server that contains the text Load. It calls the load function on the click event. Be sure to properly bind the this scope to the load function call.

    Add a button to save the note data to the server that contains the text Save. It calls the save function on the click event. Be sure to properly bind the this scope to the save function call.

    Be sure to bind the this state properly to all listeners.

  14. Test the code when ready by doing the following:

    Running npm run build in the root project folder to transpile the code from JSX.

    Running npm start to start the server.

    Loading the URL specified when the server start (127.0.0.1:PORT).

    Testing the view changes by clicking the Edit and Back to home buttons.

    Testing the save functionality by entering text into the text input, saving it, and checking the text file that was created in the folder to see if it matches.

    Testing the load functionality by entering text into the text file, loading it, and making sure that the value in the text input matches the value in text file.

A condensed snippet is provided in the following snippet. Refer to activities/activity6/solution/src/index.js for the full solution code.

Index.js
class Editor extends React.Component {
 constructor( props ) { ... }
 handleChange( e ) { ... }
 save() { ... }
 load() { ... }
 goHome() { ... }
 render() {
   return (
     <div>
       <button type="button" onClick={this.goHome.bind( this )}>Back to home</button>
       <input type="text" name="Note Text" value={this.state.value} onChange={this.handleChange.bind( this )}/>
       <button type="button" onClick={this.load.bind( this )}>Load</button>
       <button type="button" onClick={this.save.bind( this )}>Save</button>
     </div>
   );
 }
}
class Home extends React.Component {
 goEdit() { ... }
 render() {
   return (
     <div>
       <h1>Note Editor App</h1>
       <button type="button" onClick={this.goEdit.bind( this )}>Edit Note</button>
     </div>
   );
 }
}
//{…}

Snippet 6.42: React component

Outcome:

Take a look at the output screenshots here:

Figure 6.13 : Edit view

Figure 6.14 : Server view

Figure 6.15 : Running the server to test code

You have successfully built a working React frontend and integrated it with a Node.js express server.