Reactive Calculator
The ReactiveCalculator
provides real-time notifications for prayer times and related events. It initializes with the current date and time, offering both up-to-date prayer times and observables for event notifications. It also self-updates its internal configuration and prayer times so you always get real time up to date calculations, prayer times and notifications.
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
For configuration details, refer to the Config section.
Available Functions
getCurrentPrayerTime
Returns a TimeObject
with the name and Adhan time of the current prayer. If the invocation time is past Isha, the returned value would be { name: "none", time: null }
.
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
reactiveCalculator.getCurrentPrayerTime()
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
reactiveCalculator.getCurrentPrayerTime()
getNextPrayerTime
Returns a TimeObject
with the name and Adhan time of the next prayer. If the current prayer "isha"
, the returned value would be { name: "none", time: null }
.
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
reactiveCalculator.getNextPrayerTime()
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
reactiveCalculator.getNextPrayerTime()
getAllPrayerTimes
Returns an array of TimeObject
with prayer names and their corresponding time as a Javascript Date
object.
INFO
The array includes the sunrise time object.
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
reactiveCalculator.getAllPrayerTimes() // check the output tab
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
reactiveCalculator.getAllPrayerTimes() // check the output tab
getPrayerTime
getPrayerTime
returns a Javascript Date
object with the name and Adhan time of the specified prayer. Accepts prayer parameter of type PrayerNamesType
. Use the PrayerNames
enum for available prayer names.
import { Methods, ReactiveCalculator, PrayerNames } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
reactiveCalculator.getPrayerTime(PrayerNames.FAJR)
import { Methods, ReactiveCalculator, PrayerNames } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
reactiveCalculator.getPrayerTime(PrayerNames.FAJR)
getMiddleOfTheNightTime
and getLastThirdOfTheNightTime
Returns a TimeObject
representing the time of the middle and the last third of the night respectively based on the moon. Useful for Qiyam calculations.
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
reactiveCalculator.getMiddleOfTheNightTime()
reactiveCalculator.getLastThirdOfTheNightTime()
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
reactiveCalculator.getMiddleOfTheNightTime()
reactiveCalculator.getLastThirdOfTheNightTime()
adhanObserver
Returns an Observable
of type TimeEventObject
ie: Observable<TimeEventObject>
. You can subscribe to the observable for receiving real-time notifications of Adhan events.
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const subscription = reactiveCalculator.adhanObserver().subscribe({
next(value: TimeEventObject) {
console.log(`Time for ${value.name} prayer entered`)
},
error(err) {
console.error('An error occurred: ', err)
},
})
// cleanup when you need to..
subscription.unsubscribe()
reactiveCalculator.cleanup()
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const subscription = reactiveCalculator.adhanObserver().subscribe({
next(value: TimeEventObject) {
console.log(`Time for ${value.name} prayer entered`)
},
error(err) {
console.error('An error occurred: ', err)
},
})
// cleanup when you need to..
subscription.unsubscribe()
reactiveCalculator.cleanup()
iqamaObserver
Returns an Observable
of type TimeEventObject
ie: Observable<TimeEventObject>
. This method can be subscribed to for prayer Iqama times events.
import { Methods, ReactiveCalculator, TimeEventObject } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.SINGAPORE,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const subscription = reactiveCalculator.iqamaObserver().subscribe({
next(value: TimeEventObject) {
console.log(`Time for ${value.name} Iqama`)
},
error(err) {
console.error('An error occurred: ', err)
},
})
// cleanup when you need to..
subscription.unsubscribe()
reactiveCalculator.cleanup()
import { Methods, ReactiveCalculator, TimeEventObject } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.SINGAPORE,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const subscription = reactiveCalculator.iqamaObserver().subscribe({
next(value: TimeEventObject) {
console.log(`Time for ${value.name} Iqama`)
},
error(err) {
console.error('An error occurred: ', err)
},
})
// cleanup when you need to..
subscription.unsubscribe()
reactiveCalculator.cleanup()
TIP
The default time intervals in minutes between Adhan and Iqama are: { fajr: 20, dhuhr: 10, asr: 10, maghrib: 5, isha: 15 }
You can customize these intervals in the ReactiveCalculator
configuration. For more details, see the Config section.
qiyamTimesObserver
This method returns an Observable
of type TimeEventObject
ie: Observable<TimeEventObject>
. This method can be subscribed to for prayer Qiyam times events. (The middle of the night and the last third of the night).
import { Methods, ReactiveCalculator, TimesNames, TimeEventObject } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.SINGAPORE,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const subscription = reactiveCalculator.qiyamTimesObserver().subscribe({
next(value: TimeEventObject) {
if (value.name === TimesNames.MIDDLE_OF_THE_NIGHT) {
// notify Abu Bakr
}
if (value.name === TimesNames.LAST_THIRD_OF_THE_NIGHT) {
// notify Umar
}
},
error(err) {
console.error('An error occurred: ', err)
},
})
// cleanup when you need to..
subscription.unsubscribe()
reactiveCalculator.cleanup()
import { Methods, ReactiveCalculator, TimesNames, TimeEventObject } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.SINGAPORE,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const subscription = reactiveCalculator.qiyamTimesObserver().subscribe({
next(value: TimeEventObject) {
if (value.name === TimesNames.MIDDLE_OF_THE_NIGHT) {
// notify Abu Bakr
}
if (value.name === TimesNames.LAST_THIRD_OF_THE_NIGHT) {
// notify Umar
}
},
error(err) {
console.error('An error occurred: ', err)
},
})
// cleanup when you need to..
subscription.unsubscribe()
reactiveCalculator.cleanup()
prayerEventsObserver
This method returns an Observable
of type TimeEventObject
ie: Observable<TimeEventObject>
. This method is a shortcut for subscribing to all prayer events at once (Adhan, Iqama, Qiyam).
import { Methods, ReactiveCalculator, TimeEventObject, EventType } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.SINGAPORE,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const subscription = reactiveCalculator.prayerEventsObserver().subscribe({
next(value: TimeEventObject) {
if (value.type === EventType.ADHAN) {
// implement adhan notification
}
if (value.type === EventType.IQAMA) {
// implement iqama notification
}
if (value.type === EventType.TRANSIENT) {
// implement qiyam notification
}
},
error(err) {
console.error('An error occurred: ', err)
},
})
// cleanup when you need to..
subscription.unsubscribe()
reactiveCalculator.cleanup()
import { Methods, ReactiveCalculator, TimeEventObject, EventType } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.SINGAPORE,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const subscription = reactiveCalculator.prayerEventsObserver().subscribe({
next(value: TimeEventObject) {
if (value.type === EventType.ADHAN) {
// implement adhan notification
}
if (value.type === EventType.IQAMA) {
// implement iqama notification
}
if (value.type === EventType.TRANSIENT) {
// implement qiyam notification
}
},
error(err) {
console.error('An error occurred: ', err)
},
})
// cleanup when you need to..
subscription.unsubscribe()
reactiveCalculator.cleanup()
newSolarDayObserver
and newQiyamObserver
While exposed, these methods are used internally by the ReactiveCalculator
to update its internal state.
Exposing them was a design decision to offer more flexibility and customization back to the developers. You can subscribe to these observables to get notified when the solar day changes (time to calculate new prayer times) or when last third of the night is past (time to calculate new Qiyam times).
import { Methods, ReactiveCalculator, TimeEventObject } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.SINGAPORE,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const solarDaySubscription = reactiveCalculator.newSolarDayObserver().subscribe({
next(value: number) {
// recalculate prayer times for the new day
},
error(err) {
console.error('An error occurred: ', err)
},
})
const qiyamSubscription = reactiveCalculator.newQiyamObserver().subscribe({
next(value: TimeEventObject) {
// recalculate qiyam times for the new day
},
error(err) {
console.error('An error occurred: ', err)
},
})
import { Methods, ReactiveCalculator, TimeEventObject } from 'prayer-call'
// calculations for Cyberjaya
const reactiveCalculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.SINGAPORE,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const solarDaySubscription = reactiveCalculator.newSolarDayObserver().subscribe({
next(value: number) {
// recalculate prayer times for the new day
},
error(err) {
console.error('An error occurred: ', err)
},
})
const qiyamSubscription = reactiveCalculator.newQiyamObserver().subscribe({
next(value: TimeEventObject) {
// recalculate qiyam times for the new day
},
error(err) {
console.error('An error occurred: ', err)
},
})
getQiblaDirection
Returns a number
representing the Qibla direction in degrees from North.
By default this method will use the initialization coordinates but can optional accept a CoordinatesObject
.
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const calculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
calculator.getQiblaDirection() // will return: 292.6457605278075
const alAqsaCoordinates = {
latitude: 31.7782624,
longitude: 35.2335256,
}
calculator.getQiblaDirection(alAqsaCoordinates) // will return: 157.29924281528764
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const calculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
calculator.getQiblaDirection() // will return: 292.6457605278075
const alAqsaCoordinates = {
latitude: 31.7782624,
longitude: 35.2335256,
}
calculator.getQiblaDirection(alAqsaCoordinates) // will return: 157.29924281528764
getCalculationOptions
Returns the full configuration object currently in use.
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const calculator = new ReactiveCalculator({
date: new Date(2022, 1, 1),
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
calculator.getCalculationOptions()
// will return:
/*
{
date: 2022-01-31T16:00:00.000Z,
latitude: 2.9213,
longitude: 101.6559,
method: 'Malaysia',
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
iqama: { fajr: 20, dhuhr: 10, asr: 10, maghrib: 5, isha: 15 }
}
*/
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const calculator = new ReactiveCalculator({
date: new Date(2022, 1, 1),
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
calculator.getCalculationOptions()
// will return:
/*
{
date: 2022-01-31T16:00:00.000Z,
latitude: 2.9213,
longitude: 101.6559,
method: 'Malaysia',
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
iqama: { fajr: 20, dhuhr: 10, asr: 10, maghrib: 5, isha: 15 }
}
*/
setCalculationOptions
Allows you to update the calculator's configuration without creating a new instance. Accepts a newConfig
param of type Partial<ReactiveCalculationsConfig>
.
For configuration details, refer to the Config section.
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const calculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const alAqsaCoordinates = {
latitude: 31.7782624,
longitude: 35.2335256,
}
// now the prayer times are calculated for al-Aqsa
calculator.setCalculationOptions({
latitude: alAqsaCoordinates.latitude,
longitude: alAqsaCoordinates.longitude,
method: Methods.PALESTINE,
})
import { Methods, ReactiveCalculator } from 'prayer-call'
// calculations for Cyberjaya
const calculator = new ReactiveCalculator({
latitude: 2.9213,
longitude: 101.6559,
method: Methods.MALAYSIA,
adjustments: { dhuhr: 3, asr: 3, isha: 2 },
})
const alAqsaCoordinates = {
latitude: 31.7782624,
longitude: 35.2335256,
}
// now the prayer times are calculated for al-Aqsa
calculator.setCalculationOptions({
latitude: alAqsaCoordinates.latitude,
longitude: alAqsaCoordinates.longitude,
method: Methods.PALESTINE,
})
Cleanup: Why It's Important
The cleanup
method is crucial for resource management. When you initialize a ReactiveCalculator
, it starts various internal processes and subscriptions to provide real-time updates. These processes consume system resources and will continue to do so until explicitly stopped.
Invoking cleanup
will unsubscribe the calculator from all active observables, freeing up system resources and preventing memory leaks. This is especially important in long-running or resource-sensitive applications to ensure optimal performance.
// ...
// Invoking cleanup when the calculator is no longer needed
reactiveCalculator.cleanup() // clean up subscriptions
// ...
// Invoking cleanup when the calculator is no longer needed
reactiveCalculator.cleanup() // clean up subscriptions
DANGER
Neglecting to call cleanup can result in memory leaks, leading to decreased performance and potential application crashes. Always invoke cleanup when the calculator is no longer needed.