Skip to content

Chanda-Abdul/Frontend-Mentor-IP-address-tracker-Angular

Repository files navigation

Frontend Mentor - IP address tracker

Design preview for the IP address tracker coding challenge

This is a solution to the IP address tracker challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.

Table of contents

Overview

The challenge

Your challenge is to build out this IP Address Tracker app and get it looking as close to the design as possible.

Users should be able to:

  • View the optimal layout for each page depending on their device's screen size
    • Mobile: 375px
    • Desktop: 1440px
  • 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

Screenshots

Mobile @375px

No one asked but, Tablet @768px

Desktop @1140px

with Input Validation

valid IP address input

I used RegEx to validate the input,

checkIpAddressRegex = /\S+@\S+\.\S+/;
...
validateInput(ipOrDomain){
  ...
  this.checkIpAddressRegex.test(ipOrDomain)
  ...
}

if the input IS valid the user will see the "success" alert below

invalid IP address input

if the input IS NOT valid the user will see the "error" alert below

valid domain input

❗️the IP geolocation API by Abstract does not have a domain query parameter, so I skipped this for now.

I also used RegEx to check if the input is a valid domain,

  checkDomainRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9]
    [0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\
      .(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\
        .(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
        
  ...

  validateInput(ipOrDomain){
    ...
    (this.checkDomainRegex.test(ipOrDo
    
    main));
    ...
  }

if so the user will see the "warning" alert below

Links

My process

Design

  • I started by reviewing the starter design files that were included in this project. The Sass/CSS was pretty straightforward. styles.scss for the global styles, _variables.scss for re-useable styles, and style sheets for each component.
  • I created a new Angular project and decided on components that would be needed. For components I went with
    • <app> as the entry component. I wanted to keep the code and functionality to a minimum in this component. Within the this component we have
      • The <app-search-input> component, which captures the user's input. Once the input is submitted, it is sent to the GeoLocationService so that a new API/http request can be made and the data will be re-rendered.
      • The <app-display> component, to display the current IP Address, location, Timezone, and Internet Service Provider. This contains the
        • <app-map>component which handles the API/call for the mapping functionality, which could be moved to a Service later.

API Selection

Geolocation API

To get the IP Address locations, I decided to go with the IP geolocation API by Abstract because the IP Geolocation API by IPify has a very small lifetime limit of 1,000 πŸ†“ requests; compared to Abstract's 22,000 πŸ†“ requests per month and optional ip address query parameter.

GET request:

https://ipgeolocation.abstractapi.com/v1/

Input parameters:

api_key(required): 🀫

fields(optional): =ip_address,city,region_iso_code,postal_code,longitude,latitude,timezone,connection

ip_address(optional): ex. 210.138.184.59 Google Maps API

For the mapping API, I went with Maps JavaScript API. I've used LeafletJS before and I wanted to try something new, I also thought that a google API would pair well with Angular.

GET request:

http://maps.googleapis.com/maps/api/js

Input parameters:

key(required): 🀫

  • I also used a custom Marker and removed the disableDefaultUI controls.

Reactive Development with RxJs

This was a good project to practice Reactive development and RxJs/Observables. The data returned from the API calls are Observables.

Built with

APIs

Frameworks and Librarys

  • Angular (JavaScript framework)
  • sweetalert2 - A beautiful, responsive, customizable, accessible replacement for JavaScript’s popup boxes. I used this for the sweet input error alerts πŸ˜‹.
  • Figma collaborative web application for interface design.
  • Sass/CSS custom properties
    • Mobile-first workflow
    • Responsive Styling
    • Flexbox
  • Semantic HTML5 markup

What I learned

Observables and RxJs

BehaviorSubject - I knew that it would be best to use Observables for the API data. I decided to go with a BehaviorSubject because multiple components would need to subscribe to the API data and notified when there were changes.

this is what it looks like...

πŸ“‚ fetch.geolocation.service.ts

private geolocationResult!;

private geoBehaviorSubject = new BehaviorSubject(this.geolocationResult);

readonly geolocation$ = this.geoBehaviorSubject.asObservable();

...

fetchGeolocation(ipAddress?): void {
  this.http.get<Geolocation>(
    `${this.geoURL}?api_key=${environment.IP_GEOLOCATION_API_KEY}`
    + (ipAddress ? `&ip_address=${ipAddress}` : ""),
    {
      params: {
        fields: 'ip_address,city,country,continent,region_iso_code,postal_code,
        longitude,latitude,timezone,connection'
      }
    })
    .subscribe(
      res => {
        this.geoBehaviorSubject.next(res);
      }
    )
}

πŸ“‚ display.component.ts

  geolocation$ = this.fetchGeolocationService.geolocation$;
  geolocation: Geolocation;
  ...

  this.fetchGeolocationService.fetchGeolocation();
  ...

  this.geolocation$.subscribe(res => this.geolocation = res); 

πŸ“‚ display.component.html

  <div *ngIf="geolocation$ | async as geolocation">
    ...
    <li>
      <h2>Timezone</h2>
      <p>
        {{geolocation.timezone.abbreviation}} 
        {{this.formatTimezone(geolocation.timezone.gmt_offset)}}:00
        </p>
    </li>
    ...

Selecting an API

The most challenging part, for the APIs, was just selecting which two APIs would be best for this project.

For the Geolocation API, I started with the recommended, IP Geolocation APIby IPify , but I quickly learned that the lifetime request limit is pretty low. So I looked into a few other geolocation/ip address APIs and there weren't very many free APIs that would also give me the data I need, and a decent request amount, while being easily incorparated into an Angular project. I ended up going with the IP geolocation API by Abstract

For the mapping API, I skipped LeafletJS, because I've used it before and I wanted to try something new, and it also doesn't seem to work well with Angular at the moment. I went with the Maps JavaScript API, but i'm not sure if this is the best long-term option.

Continued development

  • implement search by domain input functionality, may need to use a different API?

Useful resources

Author

Acknowledgments