How to Create Instant Search with Vue.js and Axios

Vue.js is a framework with high potential. It’s easy to learn, fast, and light in terms of bytes. I started my journey writing about Vue.js with How To Build Your First Vue.js Application. Now, I’m going to continue with this article about how to make an instant search input box to filter data that comes from Lorem Picsum Web API.

You’ll find the final result in my repository.

Ingredients

  • Vue.js library: Our Javascript framework
  • Axios library: Promise based HTTP client, we’ll use it to call Lorem Picsum Web API
  • Public Lorem Picsum API url: https://picsum.photos/v2/list?page=2&limit=10
  • The file that will compose our application:index.html file, app.js, style.css

First Steps

First of all, let’s check what the output of Lorem Picsum Web API is:

[
	{
		"id": "10",
		"author": "Paul Jarvis",
		"width": 2500,
		"height": 1667,
		"url": "https://unsplash.com/photos/6J--NXulQCs",
		"download_url": "https://picsum.photos/id/10/2500/1667"
	},
	{
		"id": "100",
		"author": "Tina Rataj",
		"width": 2500,
		"height": 1656,
		"url": "https://unsplash.com/photos/pwaaqfoMibI",
		"download_url": "https://picsum.photos/id/100/2500/1656"
	}
]

The Web API returns a JSON array that represents a list of images with an URL, an author, and an ID. Those are the properties that will define our application model.

Then, develop the simple application skeleton, with a header, an input text box, a list of images, and author names. At first, it looks like this:

The body of this webpage is very simple:

<header>
  <h1>Photo finder</h1>
</header>

<div id="app-instasearch">

  <div class="input-container">
    <input type="text" placeholder="Type a name" />
  </div>

  <ul>

    <li class="photo">
      <img src="" />
      <span class="author">Some names</span>
    </li>

  </ul>

</div>

<script src="app.js"></script>

With a very easy work of CSS, the style of the images list is:

.photo {
	list-style: none;
	display: grid;
	grid-template-columns: 200px auto;
	margin-top: 20px;
	align-items: center;
	background-color: #e9edf0;
	padding: 30px 50px;
	border-radius: 5px;
	border: 1px solid #e3e3e3;
}

.author {
	font-size: 25px;
	margin-left: 20px;
	color: #75818e;
}

.photo img {
	border-radius: 5px;
	width: 200px;
}

And the style of the input box:

.input-container {
	border-radius: 5px;
	background: #677482;
	padding: 10px;
}

.input-container input {
	border: none;
	background: transparent;
	color: white;
	padding: 6px 15px;
	font-size: 18px;
}

::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
  color: #a6b0ba;
  opacity: 1; /* Firefox */
}

Vue.js Integration

It’s time to add dynamicity to our little application:

Define a new Vue application:

var instasearchApp = new Vue({
	
	el: '#app-instasearch',
	
	data: { 
		authorNameSearchString: "",
		photoFeed: null
	}
  
 }

As you can see, we binded the application to the element #app-instasearch, and we defined two properties:

  • authorNameSearchString: It will contain the search string bound to our input box
  • photoFeed: It will contain the array of images after download

In the JSON we read earlier, we learned what the properties are that represent our model. And so, the next step is to add all the Vue bindings to our HTML file.

The input box binding to our authorNameSearchString:

<div class="input-container">
  <input type="text" placeholder="Type a name" v-model="authorNameSearchString" />
</div>

The main list binding:

<li class="photo" v-for="photo in filteredPhotoFeed" v-bind:key="photo.id">
  <img v-bind:src="photo.download_url" />
  <span class="author">{{ photo.author }}</span>
</li>
  • v-for=”photo in filteredPhotoFeed”: Makes Vue able to repeat an li for each element in the filteredPhotoFeed array
  • v-bind:key=”photo.id”: It’s important to choose a key to uniquely represent an image in order to be able to animate the list
  • v-bind:src=”photo.download_url”: Without this, we won’t see the image
  • {{ photo.author }}: To print the author name near each photo

Mounted Functions

In Vue.js, you can add mounted functions, which are just hooks that will be called after that the Vue instance is loaded and bound to the interface. In this case, we need to fetch data from the Web API, and this is the right place.

mounted() {
  axios
    .get('https://picsum.photos/v2/list?page=2&limit=10')
    .then(response => {
      this.photoFeed = response.data;
    })
    .catch(error => console.log(error))
}

In this example, we’re using Axios to make the HTTP call and manage its callbacks. In particular, we’ll use the JSON response data to our application photoFeed array, and we’ll write to the output console the eventual errors.

Computed Properties

Computed properties are cached Vue application properties, and they’re only re-computed on reactive dependency changes. Note that if a certain dependency is out of the instance’s scope (i.e. not reactive), the computed property will not be updated.

In this case, we’ll use them to apply the instant search filter.

computed: {

  filteredPhotoFeed: function () {

    var photos = this.photoFeed;
    var authorNameSearchString = this.authorNameSearchString;

    if(!authorNameSearchString){
      return photos;
    }

    searchString = authorNameSearchString.trim().toLowerCase();

    photos = photos.filter(function(item){
      if(item.author.toLowerCase().indexOf(authorNameSearchString) !== -1){
        return item;
      }
    })

    return photos;
  }
}

Firstly, we check for no input by not considering null or empty strings. Then, we need to return an array of photos filtered with the search string. To do this, we use the filter method and the indexOf function as a predicate to choose only the photos with an author that’s contained within the search string.

Every time the input string changes, this property gets re-computed and the interface updates.

This is a little demo of the final result, with the addition of some animations to the list to make it fancier. You can find the whole code here.

Thank you for reading…

#Vuejs #Vue #JavaScript #Web Development #Axios

How to Create Instant Search with Vue.js and Axios
1 Likes61.40 GEEK