# Exercise: Load a Partial View with fetch

Give BooksPlus a search that updates as you type. Move the results into a partial view, add an action that returns just that partial, and write the JavaScript that fetches it on every keystroke, while the plain search form keeps working.

Journeyman · ASP.NET Core · JavaScript · Updated October 30, 2026

BooksPlus's search page makes you type, press **Search**, and wait for a whole new page. You'll make it search **as you type**: the results under the box change with every letter, and the page never reloads.

## Get the exercise code

Open this lesson's GitHub repository, [github.com/ask-codey/exercise-load-a-partial-view-with-fetch](https://github.com/ask-codey/exercise-load-a-partial-view-with-fetch), also linked from the **Exercise** box beside the lesson. Click **Code**, then **Download ZIP**, and unzip it into your `bootcamp` folder. Or clone it with Git. Then open `BooksPlusWeb.slnx` in Visual Studio.

It's the BooksPlus app from *Exercise: MVC with Dapper*, finished. It uses your own **BooksPlus** database; if yours has another name, change the connection string in `appsettings.json`.

| File | What you'll do |
|---|---|
| `Views/Books/Search.cshtml` | Move the results into a partial, and load the script |
| `Views/Books/_SearchResults.cshtml` | Create it: the results, on their own |
| `Controllers/BooksController.cs` | Add an action that returns only the results |
| `wwwroot/js/search.js` | Write the live search. Its requirements are in the comment at the top. |
| `BooksPlusWeb.Tests` | Tests that start the app and request its pages |

## What to do

1. **The partial.** Move the results part of `Search.cshtml`, the *"28 books match"* line and the list, into a new partial view, `Views/Books/_SearchResults.cshtml`. On the search page, render it with `<partial>` inside `<div id="search-results">`.
2. **The action.** Add `GET /books/search/results?q=...` to `BooksController`. It returns only the partial, with `PartialView`; with no text, the partial shows nothing at all.
3. **The script.** Give the search box the id `q`, load `~/js/search.js` in the page's `Scripts` section, and write the live search: on every change to the box, fetch the results for its text and swap them in. Fewer than 2 letters clears the results.

Run the tests with **Test > Run All Tests**. Then run the app, open the Search page, and check that:

- typing *SQL* shows *28 books match "SQL"* and the list, without pressing **Search**;
- each letter typed or deleted updates the results;
- deleting back to one letter clears them;
- *zzz* shows *0 books match "zzz"*;
- clicking a result opens that book;
- pressing **Enter**, or **Search**, still works the old way.

## Hints

- **A partial shares its page's `ViewData`**, so `_SearchResults` can read `ViewData["SearchText"]`. Set it in the new action too, as `Search` already does.
- **The `input` event** fires on every change to a text box: typing, deleting, pasting.
- **`encodeURIComponent(text)`** makes any text safe in an address: without it, a search for *C#* would lose its `#`, which means something else in a URL.
- **`response.text()`** reads the partial's HTML, and **`innerHTML`** puts it in the page.
- **Fast typists** can make answers arrive out of order. You don't need to handle that here, but think about how you might: what if each request remembered the text it was for?

## When you're done

Every test passes, and the search page feels instant. Open the browser's **Network** tab (**F12**) and type *postgres*: one small request per letter from the second one on, each answering with just the results.

## Submit your exercise

The exercise is how you finish this lesson. When your work is done, put it on GitHub in a repo of your own, then submit that repo's address here.

1. On GitHub, click **+**, then **New repository**. Name it (for example `exercise-load-a-partial-view-with-fetch`), choose **Public**, and click **Create repository**. Leave out the README: your folder already has one.
2. In a terminal in your exercise folder (Git Bash on Windows), send your work to your new repo. If you downloaded the ZIP:

   ```bash
   git init -b main
   git add .
   git commit -m "My solution"
   git remote add origin https://github.com/your-name/exercise-load-a-partial-view-with-fetch.git
   git push -u origin main
   ```

   If you cloned the starter instead, point your copy at your own repo, then commit and push:

   ```bash
   git remote set-url origin https://github.com/your-name/exercise-load-a-partial-view-with-fetch.git
   git add .
   git commit -m "My solution"
   git push -u origin main
   ```

3. Paste your repo's address, such as `https://github.com/your-name/exercise-load-a-partial-view-with-fetch`, into **Submit your exercise** on this page. The site checks that the repo is public and holds your commits, and then the lesson is complete.

Changed something after you submitted? Push it, and submit again: your latest submission is the one that counts.

## So what

You turned a page that reloads into one that answers as you type, with one partial view, one action and a few lines of JavaScript. And the old search still works underneath, for anyone whose JavaScript doesn't run.

## Key terms

- Partial View
- PartialView()
- [Fetch API](https://www.ask-codey.com/glossary/fetch-api)
- [innerHTML](https://www.ask-codey.com/glossary/innerhtml)

## Related

- [Using the fetch API](https://www.ask-codey.com/lessons/mvc-partials-with-fetch-using-the-fetch-api)
- [Exercise: MVC with Dapper](https://www.ask-codey.com/lessons/exercise-mvc-with-dapper)

Source: https://www.ask-codey.com/lessons/exercise-load-a-partial-view-with-fetch
