A Collection of Useful React Hooks for Geocoding Purposes and More
Tags: react, showdev, webdev, typescript
Published: 2019-12-31 17:01:09

For a project I'm currently involved in, we were looking for a geocoding service.

For those who don't know, geocoding is the process of converting an address like "Via Miguel Cervantes de Saavedra" into geographic coordinates (like latitude 40.841372 and longitude 14.2493221) and vice-versa. 🤓

There is a couple of different APIs available out there, like [Google Map Platforms](https://cloud.google.com/maps-platform/) and [OpenCage Geocoding API](https://opencagedata.com/).

However, for different reasons, none of them was suitable for this particular project. 🤷‍♂️

So a technology scouting started and took us far away from our offices, approximately near 38.7686466,-9.0954215. 🗺️

As a matter of fact, it all started during Web Summit 2019, which took place in Lisbon back this November.

To be honest, in that particular moment we were not looking for a Geocoding service, but as you may know, things happen when you least expect it (or maybe we had to expect it 😅).

The arena was really outstanding and there were a lot of thrilling activities to do and things to learn!

There is no better time than an event of this proportion to collect our beloved [~~hats~~](https://winterbash2019.stackexchange.com/) gadgets and stickers as well (the one that everyone at the office wants but only you have, AH! 😎).

Among the many stands, our attention was captured by one in particular...

We were here and they were HERE!

What a coincidence.😏

![HERE stand at WebSummit 2019](https://i.ibb.co/wrZCKb2/20191107-120142.jpg)

I started playing with the API immediately and I was amazed by how fast and precise the responses were, also when providing really small chunks of information. 😮 

We talked to a few people there who showed us some demo and gave us some information about the available services and the proposed plans.

Do you believe that the [Freemium plan](https://go.engage.here.com/freemium) gives you stunning 250K Transactions per month? 🤩

When I went back to Naples it was time to get my hands dirty!👨‍💻

## Time to code!

Do you recall the project I was working on?

We are using React.js, and I, in particular, am a big fan and an early adopter of hooks. 🎣

You might guess what happened later...

Of course one of the first things to do was to read the HERE API documentation and I immediately learned that there are two options:
    1. RESTFul API
    2. JS Client

But here is the catch! ☝️

Not every service is available through the JS Client but all of them are exposed as RESTful microservices.

For example, if one had to build an Autocomplete component or fetch Weather information around a location, the client would be not useful at all. 🙄

Obviously I decided to use the RESTFul API.

But this was not the only reason why I ditched the client. 
 
We made a big decision almost half a year ago and decided to use TypeScript in this project.

And I’ve to admit, that’s one of the best decisions we could make! 😍

Although it has a really steep learning curve (it can be a nightmare at first), once you are comfortable with it you only gain a lot of benefits.

It turned out that the client has no `@types` to be installed (AFAIK) and I was not very comfortable with the idea to work with it.

## use-here-api

All these reasons brought me to the creation of [use-here-api](https://github.com/CloudPower97/use-here-api), a collection of convenient hooks that let you easily integrate HERE RESTful API services in your React.js projects.

![React Hooks](https://www.dasithsblog.com/static/d3534521fb8d611c9a459334b78942f0/2d6d1/reacthooks.jpg)

At the moment the available hooks are:

- Geocoding and Search
  - [`useForwardGeocoding`](./docs/useForwardGeocoding.md) - Submit an address to request the corresponding geocoordinates. Addresses may use structured input or free-form search strings with complete or partial address information.
      The more detailed the address you submit, the higher the potential match accuracy.
  - [`useReverseGeocoding`](./docs/useReverseGeocoding.md) - Submit a geocoordinate and an optional radius to request the corresponding address.
  - [`useAutocomplete`](./docs/useAutocomplete.md) - Get better search suggestions for your addresses with fewer keystrokes.

- [`useWeather`](./docs/useWeather.md) - Give insights into real-time weather forecasts, alerts, and astronomical info for any location.
  
- Places
  - [`usePlacesAutosuggest`](./docs/usePlacesAutosuggest.md) - Provides you a lists of suggested search terms, instants results and refined search links related to a given (partial) search term and location context.
 This is used to help users save time, iterate on their searches, and get the results.

They are as easy to work with as this little snippet:

```tsx
import React, { FC, useState, useEffect } from 'react';
import { configureAuthentication, useForwardGeocoding } from '@cloudpower97/use-here-api';

const Demo: FC<any> = () => {
  const [searchtext, setSearchtext] = useState<string>(
    '200 S Mathilda Ave, Sunnyvale, CA'
  );

  configureAuthentication({
    app_id: '...',
    app_code: '...',
  });

  const [{ data, loading, error }, fetchLocation] = useForwardGeocoding();

  useEffect(() => {
    fetchLocation({
      searchtext,
      jsonattributes: 1,
    });
  }, [searchtext]);

  return (
    <>
      <div>
        <input
          placeholder="Enter an address"
          onChange={({ currentTarget: { value } }) => setSearchtext(value)}
          value={searchtext}          
        />       
      </div>
      {loading && !error && <p>Loading data...</p>}
      {error && <p>{error.message}</p>}
      {data && !loading && (
        <ul>
          {data.response.view[0]?.result.map(({ location }) => {
            const { address, navigationPosition } = location;
            return (
              <li key={location.locationId}>
                {address.label} - {navigationPosition[0].latitude},
                {navigationPosition[0].longitude}
              </li>
            );
          })}
        </ul>
      )}
    </>
  );
};
```

Of course, there is a lot of work still to do, and until we hit a 1.0 release the API is subject to changes and improvements. 🛠️

I invite you to contribute in any form to the project as you see it fit.

Oh, and if you find this project useful make sure to leave a star as well! 🤗

{% github https://github.com/CloudPower97/use-here-api %}

Thank you for reading this post and make it all the way down here!

See you next year! 🥳