Home  /  Blog  /  Prayer Times Angular

Add Prayer Times to Your Angular App

Angular8 min readOctober 2026

This post walks you through building a prayer times Angular service and component from scratch. You will get an Angular service that calls UmmahAPI, a typed interface, and a clean component template that reacts to the data automatically.

What You Need Before Starting

You need Node.js 18 or later and the Angular CLI installed. If you do not have the CLI yet, install it globally:

npm install -g @angular/cli

Then create a new project or use one you already have:

ng new prayer-app --standalone
cd prayer-app

The --standalone flag sets up the project to use standalone components, which is the default in Angular 17 and 18. The examples below use this approach. If your project still uses NgModules, the service code is identical. Only the bootstrap and import sections differ.

Register HttpClient in Your App Config

Angular's HTTP client is not available by default. You need to register it in app.config.ts. Open that file and add provideHttpClient():

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideHttpClient(),
  ],
};

That one line makes HttpClient injectable anywhere in your app. You do not need to import HttpClientModule in a module when using standalone components with provideHttpClient().

Define a TypeScript Interface for the Response

UmmahAPI returns Fajr, Sunrise, Dhuhr, Asr, Maghrib, and Isha as string fields. Create a file at src/app/models/prayer-times.model.ts to hold the shape of that data:

export interface PrayerTimes {
  Fajr: string;
  Sunrise: string;
  Dhuhr: string;
  Asr: string;
  Maghrib: string;
  Isha: string;
}

export interface PrayerTimesResponse {
  date: string;
  location: {
    latitude: number;
    longitude: number;
  };
  times: PrayerTimes;
}

Having these types means TypeScript will catch typos in your template and service. It also gives you autocomplete in your editor.

Build the Prayer Times Service

Create a service with the CLI:

ng generate service services/prayer-times

Now open src/app/services/prayer-times.service.ts and write the service. It takes a latitude and longitude, calls UmmahAPI, and returns an Observable of the typed response:

import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { PrayerTimesResponse } from '../models/prayer-times.model';

@Injectable({
  providedIn: 'root',
})
export class PrayerTimesService {
  private baseUrl = 'https://ummahapi.com/api/prayer-times';

  constructor(private http: HttpClient) {}

  getToday(lat: number, lng: number): Observable<PrayerTimesResponse> {
    const params = new HttpParams()
      .set('lat', lat.toString())
      .set('lng', lng.toString());

    return this.http.get<PrayerTimesResponse>(this.baseUrl, { params });
  }

  getMonth(
    lat: number,
    lng: number,
    month: number,
    year: number
  ): Observable<PrayerTimesResponse[]> {
    const params = new HttpParams()
      .set('lat', lat.toString())
      .set('lng', lng.toString())
      .set('month', month.toString())
      .set('year', year.toString());

    return this.http.get<PrayerTimesResponse[]>(this.baseUrl, { params });
  }
}

The service has two methods. getToday fetches today's prayer times for a given location. getMonth fetches all days in a given month. Both return Observables, so the component decides when to subscribe.

Tip. You can get a free API key at ummahapi.com/register. Add it as an x-api-key header using an HTTP interceptor if you want to avoid the rate limit on shared IP addresses.

Create the Prayer Times Component

Generate a standalone component:

ng generate component components/prayer-times --standalone

Open src/app/components/prayer-times/prayer-times.component.ts. The component will use the browser's Geolocation API to get the user's position, then call the service:

import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PrayerTimesService } from '../../services/prayer-times.service';
import { PrayerTimesResponse } from '../../models/prayer-times.model';

@Component({
  selector: 'app-prayer-times',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './prayer-times.component.html',
})
export class PrayerTimesComponent implements OnInit {
  data: PrayerTimesResponse | null = null;
  loading = true;
  error: string | null = null;

  constructor(private prayerTimesService: PrayerTimesService) {}

  ngOnInit(): void {
    if (!navigator.geolocation) {
      this.error = 'Geolocation is not supported by your browser.';
      this.loading = false;
      return;
    }

    navigator.geolocation.getCurrentPosition(
      (position) => {
        const { latitude, longitude } = position.coords;
        this.prayerTimesService.getToday(latitude, longitude).subscribe({
          next: (res) => {
            this.data = res;
            this.loading = false;
          },
          error: () => {
            this.error = 'Could not load prayer times. Please try again.';
            this.loading = false;
          },
        });
      },
      () => {
        this.error = 'Location access was denied.';
        this.loading = false;
      }
    );
  }
}

The component starts in a loading state. When the geolocation comes back, it calls the service and subscribes. The next callback stores the result. The error callback stores an error message. The template reads these three properties directly.

Write the Component Template

Open prayer-times.component.html and bind to those three properties:

<div class="prayer-times-wrapper">

  <div *ngIf="loading" class="state-msg">
    Loading prayer times...
  </div>

  <div *ngIf="error" class="state-msg error">
    {{ error }}
  </div>

  <div *ngIf="data && !loading" class="prayer-card">
    <h2>Prayer Times</h2>
    <p class="date">{{ data.date }}</p>

    <ul class="times-list">
      <li>
        <span class="name">Fajr</span>
        <span class="time">{{ data.times.Fajr }}</span>
      </li>
      <li>
        <span class="name">Sunrise</span>
        <span class="time">{{ data.times.Sunrise }}</span>
      </li>
      <li>
        <span class="name">Dhuhr</span>
        <span class="time">{{ data.times.Dhuhr }}</span>
      </li>
      <li>
        <span class="name">Asr</span>
        <span class="time">{{ data.times.Asr }}</span>
      </li>
      <li>
        <span class="name">Maghrib</span>
        <span class="time">{{ data.times.Maghrib }}</span>
      </li>
      <li>
        <span class="name">Isha</span>
        <span class="time">{{ data.times.Isha }}</span>
      </li>
    </ul>
  </div>

</div>

The *ngIf directives handle the three states cleanly. You only see one block at a time: loading, error, or the actual prayer times list.

Use the Component in Your App

Add the component to your main app component or any route component. Open app.component.ts and import it:

import { Component } from '@angular/core';
import { PrayerTimesComponent } from './components/prayer-times/prayer-times.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [PrayerTimesComponent],
  template: `
    <main>
      <app-prayer-times />
    </main>
  `,
})
export class AppComponent {}

Run the app with ng serve and visit http://localhost:4200. Your browser will ask for location permission. Once granted, the prayer times for your current location will appear.

Using the Async Pipe Instead of Manual Subscribe

If you prefer a more reactive style, you can skip the manual subscribe and use Angular's async pipe instead. This approach handles unsubscribing automatically and is useful when you want the component to stay thin.

Update the component class to expose an Observable directly:

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Observable } from 'rxjs';
import { PrayerTimesService } from '../../services/prayer-times.service';
import { PrayerTimesResponse } from '../../models/prayer-times.model';

@Component({
  selector: 'app-prayer-times-async',
  standalone: true,
  imports: [CommonModule],
  template: `
    <ng-container *ngIf="prayerTimes$ | async as data; else loading">
      <h2>Prayer Times</h2>
      <p>{{ data.date }}</p>
      <ul>
        <li>Fajr: {{ data.times.Fajr }}</li>
        <li>Dhuhr: {{ data.times.Dhuhr }}</li>
        <li>Asr: {{ data.times.Asr }}</li>
        <li>Maghrib: {{ data.times.Maghrib }}</li>
        <li>Isha: {{ data.times.Isha }}</li>
      </ul>
    </ng-container>
    <ng-template #loading>Loading...</ng-template>
  `,
})
export class PrayerTimesAsyncComponent {
  prayerTimes$: Observable<PrayerTimesResponse>;

  constructor(service: PrayerTimesService) {
    // Mecca coordinates as a fixed fallback
    this.prayerTimes$ = service.getToday(21.42, 39.82);
  }
}

Here the component passes Mecca's coordinates directly (latitude 21.42, longitude 39.82). The async pipe subscribes when the component mounts and unsubscribes when it destroys. You do not need to manage that lifecycle yourself.

Tip. For a quick no-code solution, check out the UmmahAPI embeddable widgets. They include a ready-made prayer times widget you can drop into any page with one line of HTML.

Add an API Key Header

The free tier works without a key. But once your app goes live, add a free API key so you get unlimited requests. The cleanest way to do this in Angular is an HTTP interceptor. Create one with the CLI:

ng generate interceptor interceptors/api-key

Then write the interceptor:

import { HttpInterceptorFn } from '@angular/common/http';

export const apiKeyInterceptor: HttpInterceptorFn = (req, next) => {
  const apiReq = req.clone({
    setHeaders: {
      'x-api-key': 'YOUR_API_KEY_HERE',
    },
  });
  return next(apiReq);
};

Register it in app.config.ts:

import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { apiKeyInterceptor } from './interceptors/api-key.interceptor';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideHttpClient(withInterceptors([apiKeyInterceptor])),
  ],
};

Every HTTP request your app makes will now include the key automatically. You can get a key for free at ummahapi.com/register. See the full API docs for all available headers and options.

FAQ

How do I fetch prayer times in an Angular app?

Use Angular's HttpClient inside a service to call the UmmahAPI endpoint GET https://ummahapi.com/api/prayer-times?lat=&lng=. Inject the service into your component and subscribe to the returned Observable, or bind it directly using the async pipe in the template.

Do I need an API key to use UmmahAPI for prayer times?

No. You can start without a key. The free tier allows 5,000 requests every 15 minutes. Registering for a free key at ummahapi.com/register removes that rate limit completely.

Which Angular version does this code work with?

The examples use standalone components and provideHttpClient(), which are available from Angular 15 onward. The same patterns work in Angular 16, 17, and 18. For older versions using NgModules, import HttpClientModule in your root module instead of using provideHttpClient().

Can I get a full month of prayer times in one request?

Yes. Add month and year query parameters to the same endpoint: GET /api/prayer-times?lat=21.42&lng=39.82&month=10&year=2026. The service's getMonth() method in the examples above handles this for you. The response is an array of daily prayer time objects.

Free Prayer Times API for Your App

UmmahAPI gives you prayer times, Quran data, Hadith, Qibla, and more through a single free API.

Read the docs