Introduction

Welcome to the third lesson of our course, where we will focus on handling user input and making API calls in our AI Short Story Generator web application.

In previous lessons, we set up the basic HTML structure and styled the interface to make it visually appealing. However, our application is still static — clicking buttons doesn't do anything, and there's no way to switch between tabs or generate stories. This is where JavaScript comes in. JavaScript is the programming language that brings web pages to life by adding interactivity and dynamic behavior.

Now, we will dive into the functionality that allows users to interact with the client-side application and generate stories. This lesson will guide you through implementing tab navigation, creating a story generation function, and making API calls to interact with the backend. By the end of this lesson, you will have a solid understanding of how to handle user input and integrate API calls into your web application.

Implementing Tab Navigation

Our application has two main tabs: "Generate Story" and "View History." We need to implement a function that will show the selected tab and hide the others when a user clicks on a tab button.

Let's create a file named script.js in the static folder of our Flask application. This is the same folder where we placed our style.css file in the previous lesson.

Let's start by implementing tab navigation, which allows users to switch between different sections of the application. We will write the openTab function in script.js.

First, we need to gather all elements with the class tab-content. This will allow us to loop through each element and hide them initially. Here's how you can do it:

In this code snippet, document.querySelectorAll('.tab-content') selects all elements with the class tab-content. We then use the forEach method to loop through each element and set its display style to 'none', effectively hiding all tabs.

Next, we need to display the selected tab. We can achieve this by using document.getElementById to select the element with the provided tabName and set its display style to 'block':

This line of code selects the element with the ID matching tabName and sets its display style to 'block', making it visible to the user.

This approach is also backward compatible and scalable. If you decide to add more .tab-content divs in the future (for example, to introduce new tabs), you won't need to change this function. It will automatically hide all tab content sections and only display the one corresponding to the selected tab. This makes it easy to extend your application with additional tabs without modifying your JavaScript logic.

By combining these steps, we create a function that effectively manages tab navigation, allowing users to switch between different sections of the application.

Creating the Basic Skeleton for the `generateStory` Function

Now, let's create the basic skeleton for the generateStory function. This function will handle user input and prepare the application for generating a story.

First, we declare the generateStory function:

Inside this function, we need to retrieve and store references to several DOM elements. These elements include prompt, style, loading-message, generate-button, and story-container. Here's how you can do it:

In this code snippet, we use document.getElementById to select each element by its ID and store the references in constants. This allows us to easily access and manipulate these elements later in the function.

Adding Input Validation and Initial UI Updates

Next, we will add input validation and initial UI updates inside the generateStory function. This ensures that the user provides the necessary input before generating a story.

First, we check if the prompt input is empty. If it is, we show an alert and exit the function early:

This code checks if promptInput is empty. If it is, an alert is displayed with the message "Please enter a prompt," and the function exits early using return.

Next, we update the UI to indicate that the story generation process has started. We show the loading message, hide the generate button, and clear any previous story content:

These lines of code set the display style of loadingMessage to 'block', making it visible, and set the display style of generateButton to 'none', hiding it. We also clear the innerHTML of storyContainer to remove any previous story content.

Introducing API Calls with Fetch

Now, let's introduce API calls using the Fetch API. We will send a POST request to /api/generate_story to generate a story based on the user's input.

First, we construct the fetch statement:

In this code snippet, we use the fetch function to send a POST request to /api/generate_story. We specify the request method as 'POST' and set the Content-Type header to 'application/json'. The request body is constructed using JSON.stringify, which converts the user's input into a JSON string.

Handling API Responses and Finalizing the Functionality

Finally, let's handle the API response and finalize the functionality of the generateStory function. We will extend the fetch promise chain to process the response and update the UI accordingly.

First, we add a then callback to parse the JSON response:

This line of code processes the response by calling response.json(), which parses the JSON data returned by the server.

Next, we update the UI based on the response:

In this code snippet, we hide the loading message and display the generate button again. We then check if the response contains an error. If it does, we display an alert with the error message. Otherwise, we create a pre element, set its textContent to the generated story, and append it to storyContainer.

Finally, we add a catch block to handle any errors that occur during the fetch process:

This code snippet ensures that if an error occurs, the loading message is hidden, the generate button is displayed, and an alert is shown to the user. We also log the error to the console for debugging purposes.

Summary and Preparation for Practice

In this lesson, we covered how to handle user input and make API calls in our AI Short Story Generator web application. We implemented tab navigation, created the basic skeleton for the generateStory function, added input validation and initial UI updates, introduced API calls using the Fetch API, and handled API responses to finalize the functionality. These skills are essential for building a functional and interactive web application.

Now that you have learned these concepts, you are ready to apply them in the practice exercises that follow this lesson. These exercises will reinforce your understanding and help you build a fully functional AI Short Story Generator. Good luck, and enjoy the hands-on experience!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal