IP address tracker, full stack app (TypeScript frontend, Express backend).

Locate any IP address or domain on a Leaflet map! Implemented with object oriented TypeScript.

Screenshot of my implementation of the IP address tracker app on desktop.

Overview

Locate any IP address or domain name!

How to run the project

  1. git clone HTTPS_REPO_URL MY-FOLDER-NAME
  2. cd MY-FOLDER-NAME
  3. npm install
  4. npm start
  5. Visit http://localhost:1234 with a browser to view the frontend.
  6. Use the backend repository to made the app fully functional.

Features

  • Responsive design.
  • Accessible.
  • Locates any IP address and domain name and displays its information in a readable table.

Technologies

  • HTML
  • CSS
  • TypeScript
  • Leaflet
  • Node & Express microservice
  • Geolocation APIs (Ipgeolocation.io)

Description

This app is an IP address tracker built with HTML, CSS, and TypeScript. It is a challenge created by Frontend Mentor.

Your users should be able to:

  • View the optimal layout for each page depending on their device’s screen size
  • See hover states for all interactive elements on the page
  • See their own IP address on the map on the initial page load
  • Search for any IP addresses or domains and see the key information and location

IP Address tracker challenge by Frontend Mentor

How I built this project

Screenshot of the IP address tracker app on mobile.

HTML/CSS

  1. First built the UI with a mobile first approach. The design has two breakpoints: at 375px and 1440px. See the style guide.

Better development with TypeScript

When planning this project, it became clear that a robust solution needed to be inspired from OOP concepts, where separate objects are responsible for simple tasks and interact if needed. TypeScript helped as it simplified the implementation of classes (for example, it allows the use of keyword that don’t exist in JavaScript, such as private).

I implemented the following classes, then called their public methods in app.ts when a 'submit' or 'DOMContentLoaded' event occurred:

  • Request information to the geolocation API with SearchLocator.
  • Populate the table with PopulateTable.
  • Integrate Leaflet with AddressMapControl.
// app.ts
"use-strict";
import SearchLocator from "./SearchLocator";
import AddressMapControl from "./AddressMapControl";
import PopulateTable from "./PopulateTable";

const appMap = new AddressMapControl();
const searchLocator = new SearchLocator();
const infoDisplay = new PopulateTable();

export type IpAddressData = {
	ip: string;
	isp: string;
	city: string;
	district: string;
	zipcode: string;
	latitude: number;
	longitude: number;
	time_zone: { offset: number };
};

/**
 * Locates and displays the information found about the client.
 * Called when the page is first loaded.
 */
const displayData = async (search = "") => {
	let json = await searchLocator.getSearchData(search);

	// If json is undefined, it means there was a problem processing the request. There's no need to keep executing the function, hence the return statement. An alert is also displayed to inform the user.
	if (!json) return alert(json.message || "Could not locate this search.");

	// Populate the ".search + table" element with the relevant data
	infoDisplay.populateTable({
		ip: json.ip,
		isp: json.isp,
		city: json.city,
		district: json.district,
		zipcode: json.zipcode,
		time_zone: json.time_zone,
	});
	// Update the map so it displays the new location and moves the marker to point to it
	appMap.updateMap([json.latitude, json.longitude]);
};

window.addEventListener("DOMContentLoaded", async () => {
	displayData();

	const searchElement = document.querySelector(".search");
	searchElement.addEventListener("submit", async function (e) {
		e.preventDefault();

		const search = e.target["searchedAddress"].value;

		// If the field is empty, the value of ip in the URL is === "", therefore the API will return information about the client.
		if (search === "") displayData();
		// Otherwise, the search can be either an IP address, a domain name, or neither (an invalid input). The server will process the search input and return a response used in displayData
		displayData(search);
	});
});

Doing this, I avoided:

  • Writing extra code just to create new tiles/layers for the map and then having to clean up after every search.
  • Writing my own, potentially buggy code by taking advantage of the interfaces already available.
  • Having one large code file which would have made debugging more difficult.

I also managed to make this app functional for free.

Recommended technologies and tools

  • VS Code type hints.
  • TypeScript.
  • The Leaflet library.
  • IP-API.com to get a domain’s IP.
  • ipgeolocation.io to get any IP address information needed by the app.

Status

The app works. But I am still reviewing the code.

Planned changes

  • [x] Make the app work when the user searches a domain name.
  • [ ] Improve the code structure.

Sources

Useful references

Author

Leave a Reply

Your email address will not be published. Required fields are marked *