Level 7 - Epilogue

Epilogue - The Front End

Teachers can use the Front End Template to demonstrate how we could use a React application to take search terms from users and display the results. The following steps will provide insight on how teachers can alter the template application to display results from your application.

There are two completed projects running on AWS that demonstrate what the finished product looks like:

Cheetah Search
Jerboa Search

One small change for the Spring Application

The way that this project and most major web applications are structured, is such that the backend and frontend are discrete applications. In order for our Spring application to accept requests from a different application, we need to enable CORS support. This is the case whether we have production applications running on entirely different instances, or even just when we run these applications locally but on different ports. Cross Origin Resource Sharing (CORS) is a mechanism that allows applications to accept requests that from a different domain. These requests are typically blocked, for security reasons. As an example that ignores some other security best-practices, your computer might have a cookie saved in the browser that contains the login credentials for your bank account. Someone could write some JavaScript on any website that grabs your cookies, logs into your bank account, and transfers all of your money to them. However, as previously mentioned, this request would (hopefully) be blocked by the bank's CORS policy, as it is programmatic request from a domain that they don't own. While they might have CORS enabled, it would only apply to domains which they own. While Spring allows us to specify domains for which we would like to enable CORS, you can simplify things and just enable CORS in your controller classes by adding the following annotation above your Controller classes' class declaration. If you wanted to specify which domains you would like to enable CORS support for, it would be simply a matter of adding parentheses that contain a domain String after the annotation.

@RestController
@CrossOrigin
public class LocController{
    //a bunch of code
}

Clone the Template Repository and Create a Branch

Clone the Front End Template repository and create a new branch that you will update to work with the Spring application.

Making it fit Your Application

To make this process as easy as possible, many of the fields that you need to change have been extracted into the properties.js file. You can easily set the course name, endpoint, description, Swagger URL, list of student names, and repository URL within that file.

The only changes that require going further into the code are those required to make each SearchResult component properly display the contents of each result from the request. For example, the Cheetah Search application retrieves a list of books, and displays a the title, authors, and link for each book. The Jerboa Search application retrieves a list of movies, and displays the title, overview, and release date for each movie. The SearchResult component needs to be altered slightly to reflect the difference in data that is received.

If you are running your application locally, you can use a endpoint URL of http://localhost:5000/<whatever your endpoint URL is>

Passing the Data to the SearchResult

The SearchOutput component takes the list of data that we received from the request to the Spring application, a creates a SearchResult component for each of the individuals pieces of data (each book, movie, etc). On line 22 of SearchOutput.js, we need to create a prop for each of fields within our JSON object, and set that equal to the field name within the JSON object. Note that these correspond directly to the list of fields that are contained with the Java object that the Spring application returns. For Cheetah Search, the code on line 22 of SearchOutput.js look like this:

 <SearchResult
         key={index}
         title={result.title}
         authors={result.authors}
         link={result.link}
 />

Displaying the Data Within the SearchResult

Now all that is left is use the props that have been passed in the SearchResult component and display them properly. The starting on line 7 of SearchResult.js is essentially HTML, so if you are familiar with that, you can play with the style of what is returned from the SearchResult to make it display exactly how you want. The Cheetah Search example is actually more complicated than most, as it returns a list of authors that are, in turn, mapped to an individual <p> tag:

<article className={classes.Result}>
    <h1>Title: {props.title}</h1>
    <h3 className={classes.Author}>
    {props.authors && props.authors.map((author, index) => (
        <p key={index}>{author}</p>
    ))}
    </h3>
    <a href={props.link} rel="noopener noreferrer" target="_blank">{props.link}</a>
</article>


We can also see the final prop, link, is displayed as a clickable link that opens a new page.

If your object doesn't return any lists, you could simplify the above code greatly. For example, the above code for a made up animal object may look like this:
<article className={classes.Result}>
    <h1>Species: {props.species}</h1>
    <h3>Number of legs: {props.numberOfLegs}<h3>
</article>

Running the Application

To run this application, you need to have yarn installed. From that point, you may need to run "yarn install" to install the project's dependencies. After that, "yarn start" will start the frontend application and automatically open it in your browser.

That's All!

If you set up the front end correctly, you should now be able to enter a search query and display results relevant to that term. After our long journey, we have seen not only how to create a production-quality Spring application that provides users with data based on a specific query, but now how we could display that information to a user with modern React application.

Oh no! My web page won't display any data :(

If you have the frontend running, but when you submit a search nothing shows up, or it appears to load forever, there are only a few things that could be going wrong. To find the cause, open up the JavaScript (or developer) console in your browser and submit your search again. If you see a message being displayed that mentions CORS, revisit the first step of this section and update your Spring application accordingly. If that doesn't seem to be the issue, open the "network" tab of the developer console and submit your search. The request that is failing will likely show up in red. Look at the status code for the request, and that will give you a good hint as to where the problem is occurring. If the status code is in the 400 range, that means there is an issue with the request you are making from the frontend application. Most likely, the URL and/or query parameters that you are attempting to submit are incorrect. If the status code is in the 500 range, that means there is an issue with the Spring application when it tries to complete the request. If that is the case, you should see a stack trace being printed out by your Spring application that will give you a hint as to why it is failing. If the request to the Spring application is succeeding, and you receive a 200 status code, then the issue lies with how you are handling the data once it is delivered to the frontend application. Revisit the previous steps and confirm that you are properly displaying the data on your page.