TypeScript Section 13 – “Select & Share a Place” App


TypeScript

Updated Mar 14th, 2022

Use a 3rd-party Library to send request and render a map with Google maps.

Enter address, convert to coordinates and show the coordinates on a map with the google maps JS SDK.

In the “index.html” file we add a form with no action and input and a button

Add very simple CSS for the map and the form. Center with flex.

Fetch what the user looks up

In the “app.js” we need to check for the form submission by adding a listener to the form and preventing the default and then get access to the address with getElementById.

TS does not like the “value” so use “type-casting”

Set up a google API Key: Geocoding API. We provide and address and gte back coordinates. Need a Google account and a credit card. Generous free tier. We want the “Maps” and “Places” features so check these boxes.

Copy the key and store in a constant variable in your project.

Install “Axios” to send the requests (can use in JS and TS).

npm install --save axios

Import in. We get auto-completion when we start using so we can tell the developers have support for TS out of the box (built-in translations).

axios.get(`http://fromGoogle${apiKey}khgvhgkvghkvaddress=${encodeURI(enteredAddressConstant)}`).then(
  response => {console.log(response)
  }).catch(err => console.log(err))

We need to convert the address into a URL-compatible string with built-in “encodeURI()” method.

Find the “location” key and how you need to drill in to find

const coordinates = response.data.results[0].geometry.location

We are not getting auto-completion right now but we can tell TS the “type” for the response we get back.

axios.get<{results: {geometry: {location: {lat: number, lng: number}}}[]}>(`http://fromGoogle${apiKey}khgvhgkvghkvaddress=${encodeURI(enteredAddressConstant)}`).then(
  response => {console.log(response)
  }).catch(err => console.log(err))

Now we get auto-completion.

We could put this in our own “type-alias” and then refer to that making the code cleaner.

type GoogleGeocodingResponse = {
  results: {geometry: {location: {lat: number, lng: number}}},
  status: "OK" | "ZERO_RESULTS"
}
axios.get<GoogleGeocodingResponse>(`http://fromGoogle${apiKey}khgvhgkvghkvaddress=${encodeURI(enteredAddressConstant)}`)
.then(response => {

  if (response.data.status !== "OK") {
    throw new Error("There was an error.")
  } else {
    const coordinates = response.data.results[0].geometry.location
  }
})
.catch(err => {
  console.log(err))
}

Rendering a Map with Google Maps

We will use the Google Maps JavaScript API

Add script in the “index.html” file above our script. Add the “async” and “defer” keywords. Swap out the API KEY portion of the URL and get rid of “& callback =initMap” at the end of the URL.

We do not install from NPM because it is not published to NPM we are using the CDN.

We will have a problem

Can use “declare var google: any” to tell TS this will exist and we no longer get errors. We can also get a marker.

Render the map in the right place, looking for an element with an id of “map”

Not optimal at this point, we are not getting any type support.

search for “types google maps” and we find many packages for this. We can add “types” package from “npm” even though we didn’t install google maps on “npm.”

npm install --save-dev @types/googlemaps

Restart and now we can remove “declar var” line and it still compiles and we get auto-completion.