How to build an auto-suggest field using React and Express

One of my latest projects is a map application that has a search form in it. In this form is a field where you can type in a few letters and it will bring up the cities in the US, along with the state abbreviation concatenated with it. In other words – an autocomplete field of US cities.

I’m using ReactJS for the front end, and ExpressJS for the back. I really like the fact that both ends is written in the same language – so you don’t have to switch context. JavaScript has come a long way – and I must say it has been pretty cool to work with.

The Express Backend

Let’s start with creating the backend. What we’re trying to do is a “mini” API of sorts. Where we can pass in a term, and will bring us results. Express is perfect for our scenario.

I found a couple of good resources that will contain the data that we’ll serve. For the US cities, I found this Gist which has them all, paired with the states their in:

But notice that the states are in full form. I like it better when they show the abbreviation. So here is another Gist that does that:

So I create a couple of constants so I can loop through and map them as we during search.

Then we create a function called search – where we accept the request and response from Express. Here we do the query and mapping as shown below:

We return the response object above as a JSON string. Which we can parse easily from our front end. Don’t forget to setup our route in Express:

So you see the first parameter in our .get function – is the actual route. This is so that we can do something like below in our endpoint:

All we need to do is make the “term” dynamic, and we should have different results. Now let’s move forward.

The React Front End

Okay, now we get to the meat of the application. React is a different way of looking at front end development. Everything is inside JavaScript – so there is really no “HTML”. Or at least, no .html files. I’m not going into detail on how that works, I’m just going to assume you know.

Let’s import react and axios.

Axios makes it easy for us to write AJAX calls. Then, let’s create our Form – and its a class component. Let’s call it “Search”. We’re using “Controlled Components” style – which has more flexibility when working with forms.

Now that we our form, let’s add our state. We need 2: “near” and “citySuggestions”.

Our state “near” – is what we’re putting in our input field. In React’s controlled components, we have to define input field values in state make it the single source of truth. This might be a little cumbersome – especially compared to other frameworks – where you can simply define a “model”.

On top of that, any mutations to the state has to be done through a handler. So let’s create that now:

So our nearChanged function is what mutates our “citySuggestions” state. And this is done through an AJAX call to our Express server. We’re also waiting until the length of the entered text is more than 3 – for a more valid search term. Otherwise, we set the citySuggestions to an empty array.

Now let’s add the actual field inside our form, including and binging onChange and other attributes.

We also added “this.citySuggest()” above – which is simply a function that return an un-ordered list of items. These items are the suggestions that came back from our AJAX call. Let’s move on to the actual function:

Each list item is simply mapped to each states “citySuggestions”. Also, we have attached a listener to it when it’s clicked. We call this event “cityClicked”. Notice that we use .bind(self,index), where “self” is really “this” – which we need inside our class to use, and “index” is to know which one is actually clicked.

Our cityClicked() function is quite simple. We simply look for the which citySuggestions item was clicked by the “index” that was passed. It’s actually in this function that we set specific values – such as hidden fields etc. But for now – we’re setting the “near” state as well. This is so our input field will reflect what was clicked from the list.

I added very minimal styling – which I’ll leave open to your taste. But for now, that’s a working input field.

Leave your thoughts below.

Leave a Comment.