Services
Services in this project provide centralized logic for loading JSON content, navigating between pages, managing global state, accessing localStorage, and controlling UI elements like loaders and sidebars.
All services are located in:
ui-dev/src/app/services/
ConfigService
Path: services/config-service/
Centralized configuration service. Provides shared configuration values, endpoints, UI settings, and generally app-wide options.
import { ConfigService } from '../services/config-service/config.service';
constructor(private config: ConfigService) {}
ngOnInit() {
console.log(this.config.apiUrl);
}
GlobalFeaturesService
Path: services/global-features/
Exposes site-wide feature toggles (enable/disable sections), layout switches, and global UI control flags.
import { GlobalFeaturesService } from '../services/global-features/global-features.service';
constructor(private features: GlobalFeaturesService) {}
isEnabled() {
return this.features.showRightColumn;
}
LoaderService
Path: services/loader/
Controls the visibility of the loading component. Components subscribe to loading state changes.
import { LoaderService } from '../services/loader/loader.service';
constructor(private loader: LoaderService) {}
showLoader() {
this.loader.setLoading(true);
}
hideLoader() {
this.loader.setLoading(false);
}
LocalStorageService
Path: services/local-storage/
A wrapper around window.localStorage using typed interfaces and safer get/set methods.
import { LocalStorageService } from '../services/local-storage/local-storage.service';
constructor(private storage: LocalStorageService) {}
save() {
this.storage.set('visited', true);
}
NavigationService — Detailed Explanation
This service tracks user navigation history and handles intelligent “back” behavior for paginated routes. It is tightly coupled with the Router and query params.
Key Features
- Stores a complete stack of visited URLs
- Tracks which URLs include
?page= - Handles duplicate route events
- Removes mismatched URLs (where UI may have changed pages)
- Parses current page numbers
- Provides a custom
back()method superior to router.navigateBack()
History Tracking Logic
router.events → NavigationEnd
▼
activatedRoute.queryParams → read ?page=
▼
push URL into history[]
▼
remove duplicates
▼
clean out URLs without matching page params
Custom Back Navigation
If the previous URL contains ?page=, the service extracts:
- The base route
- The page number
/route?page=X
Example
/library?page=2
/library?page=3
/library?page=4
Back() → /library?page=3
Back() → /library?page=2
Back() → /library
This ensures the user moves backwards through pagination logically, not abruptly jumping to the starting route.
ProjectListService — Detailed Overview
This is the most complex service in the application. It controls:
- Caching (localStorage → prevent repeated API calls)
- Pagination logic
- Category loading
- API requests
- Total category counts
- Routing between paginated URLs
- Broadcasting updated project lists to components
Key BehaviorSubjects
totalItems$ // total number of pages
allProjects$ // project array for the current page
categoryType$ // current category ("all", "leadership", etc.)
pageDataObject$ // dynamic metadata per page (title, StackBlitz, GitHub)
The Heart of the Service: isThereCache()
This function decides whether to load paginated data from localStorage or fetch it from the Node API.
if (cached page exists)
load from storage
update totals
else
call API
cache result
API Fetching (getAllProjects)
Makes an API call to:
../api/compliance-library/?type=TYPE&page=PAGE&limit=LIMIT
Then fills:
this.projectArraythis._local.storage[type][pageNum]this._local.storage['totals']
Local JSON Mode (getLocalProjects)
Used when running without the API. Useful for ng serve development mode.
navigateToRoute()
Updates the URL with the correct ?page= parameter.
cacheCategoryTotals()
Stores "all", "leadership", "standards", and "security" counts into localStorage.
Why This Service Matters
Every component involved in:
- project lists
- category navigation
- pagination
- right-column
- related content
depends on this service to function properly.
SidebarService
Path: services/sidebar/
Controls the visibility and content of the secondary sidebar elements. Used by right-column, category-navigation, and content components.
import { SidebarService } from '../services/sidebar/sidebar.service';
constructor(private sidebar: SidebarService) {}
toggleSidebar() {
this.sidebar.toggle();
}
Service Relationships
page-content → navigation.service
→ loader.service
→ sidebar.service
category-navigation → navigation.service
→ sidebar.service
project-list → project-list.service
→ loader.service
content components → navigation.service
→ sidebar.service
This structure keeps components lightweight and readable.