🪟 Windows TippsPixel-Smartphones haben soeben ein riesiges Update erhalten(17.09.2026 um 10:32 Uhr)
🪟 Windows TippsAus alt mach (fast wie) neu: Stadionbeschallung Aachener Tivoli(17.09.2026 um 10:30 Uhr)
🪟 Windows ServerLenovo modernisiert Virtualisierungsinfrastruktur(17.09.2026 um 09:06 Uhr)
🤖 Android TippsAus alt mach (fast wie) neu: Stadionbeschallung Aachener Tivoli(17.09.2026 um 10:30 Uhr)
🕵️ SicherheitslückenCVE-2026-81165 | Drupal Blazy Module up to 3.0.18 improper authorization(17.09.2026 um 10:33 Uhr)
🪟 Windows TippsPixel-Smartphones haben soeben ein riesiges Update erhalten(17.09.2026 um 10:32 Uhr)
🪟 Windows TippsAus alt mach (fast wie) neu: Stadionbeschallung Aachener Tivoli(17.09.2026 um 10:30 Uhr)
🪟 Windows ServerLenovo modernisiert Virtualisierungsinfrastruktur(17.09.2026 um 09:06 Uhr)
🤖 Android TippsAus alt mach (fast wie) neu: Stadionbeschallung Aachener Tivoli(17.09.2026 um 10:30 Uhr)
🕵️ SicherheitslückenCVE-2026-81165 | Drupal Blazy Module up to 3.0.18 improper authorization(17.09.2026 um 10:33 Uhr)
🔧 Programmierung 🕛 vor 6 Monaten 5 Min Lesezeit
0

Angular Bootstrap

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

, I’ve refined a method that makes the application "smart" from millisecond zero by moving the logic outside the Angular lifecycle.






1. Hot Config (JSON-based)



Instead of hardcoding values in environment files (which require a rebuild for every change), we use a standalone app-config.json. This allows for "Hot Configuration"—changing API endpoints or feature flags on the fly.




CODE
{
"appName": "RAG System",
"apiUrl": "http://localhost:3000/api/v1",
"logMode": "console",
"siteMode": "development",
"version": "1.0.0",
"langs": [
{ "code": "en", "label": "ENG", "description": "English", "langEn": "English" },
{ "code": "it", "label": "ITA", "description": "Italiano", "langEn": "Italian" }
],
"google": {
"clientId": "YOUR_GOOGLE_CLIENT_ID",
"redirectUri": "http://localhost:4200",
"button": { "theme": "outline", "size": "large", "text": "continue_with", "logo_alignment": "left" },
"analyticsId": "YOUR_GOOGLE_ANALYTICS_ID"
},
"uploadConfig": { "maxFileSize": 50, "maxFileCount": 5, "acceptedFileTypes": "*/*", "allowMultiple": false },
"menus": {
"guest": [
{ "label": "home", "icon": "home", "route": "/home" },
{ "label": "Login", "icon": "login", "route": "/login" }
],
"user": [
{ "label": "Home", "icon": "home", "route": "/welcome" }
],
"admin": [
{ "label": "_DIVIDER_" },
{ "label": "Config", "icon": "settings", "route": "/admin-config" }
]
}
}










2. The Static StoreService



To avoid the "chicken and egg" problem of Dependency Injection, I use a Static StoreService. By using static properties, the configuration becomes a global "Source of Truth" that is available even before Angular's DI container is fully ready.




CODE
import { Injectable } from "@angular/core";
import { BehaviorSubject } from "rxjs";
import { I18nLang, IAppConfig, IMenuItem, SiteModeType } from "../../Models/config.model";

/**
* The app configuration is loaded when angular starts in main.ts
* This service provides access to the configuration
* and manages application state in localStorage/sessionStorage
*/

@Injectable({
providedIn: "root",
})
export abstract class StoreService {
private static PREFIX: string = "MYAPP
private static CONFIG = {} as IAppConfig;

// Token change observable
private static tokenSubject = new BehaviorSubject<string>(
"");
public static tokenChange$ = StoreService.tokenSubject.asObservable();

constructor() {}

static set(key: string, value: any, persistent: boolean = false) {
key = this.PREFIX + key;
if (persistent) localStorage.setItem(key, value);
else sessionStorage.setItem(key, value);
}

static get(key: string): any {
key = this.PREFIX + key;
return localStorage.getItem(key)
? localStorage.getItem(key)
: sessionStorage.getItem(key);
}

static remove(key: string) {
key = this.PREFIX + key;
localStorage.removeItem(key);
sessionStorage.removeItem(key);
}
static clear() {
localStorage.clear();
sessionStorage.clear();
}

static getAll() {
const allItems = { ...localStorage, ...sessionStorage };
const filteredItems: { [key: string]: string } = {};
for (const key in allItems) {
if (key.startsWith(this.PREFIX)) {
filteredItems[key.replace(this.PREFIX,
"")] = allItems[key];
}
}
return filteredItems;
}

// TOKENS SECTION
static setJwtToken(token: string) {
if (!token) {
this.remove(
"auth_token");
this.tokenSubject.next(
""); // Emit empty token (logout)
return;
}
this.set(
"auth_token", token);
this.tokenSubject.next(token); // Emit new token (login/refresh)
}

static getJwtToken(): string {
return this.get(
"auth_token") || "";
}

// CONFIG SECTION
static setConfig(config: IAppConfig) {
this.CONFIG = config;
}

private static getConfig(): IAppConfig {
return this.CONFIG;
}

static getApiUrl(): string {
return this.getConfig().apiUrl;
}
// add static functions or properties for every options you need
}










3. The "Pre-Flight" Boot in main.ts



This is the "smart" part. Instead of letting Angular start and then asking for the config, we fetch the config in main.ts and then trigger the bootstrap process.




CODE
import { provideZoneChangeDetection } from "@angular/core";
/// <reference types="@angular/localize" />
import { bootstrapApplication } from "@angular/platform-browser";
import { appConfig } from "./app/app.config";
import { AppComponent } from "./app/app.component";
import { StoreService } from "./app/Core/services/store.service";

// Load configuration before bootstrapping the application
const loadConfig = async () => {
try {
const dt = new Date().getMilliseconds();
const response = await fetch(`./assets/config/app-config.json?ver=${dt}`);

if (!response.ok) {
throw new Error(
`Failed to load configuration: ${response.status} ${response.statusText}`,
);
}

const config = await response.json();
StoreService.setConfig(config);

// Bootstrap application after config is loaded (or failed to load)
bootstrapApplication(AppComponent, {
...appConfig,
providers: [provideZoneChangeDetection(), ...appConfig.providers],
}).catch((err) => console.error("Application bootstrap failed:", err));
} catch (error) {
console.error(
"Fatal error: Application cannot start without configuration:",
error,
);
}
};
// Execute the configuration loading
loadConfig();






Why is this better?

Zero Flickering: No "loading" spinners while waiting for settings.

No Undefined Errors: You don't need to check if(config) in every constructor.

Environment Agnostic: The same build works in Dev, Staging, and Prod just by swapping the JSON file.



Conclusion:

Bootstrapping shouldn't be an afterthought. By moving your configuration logic to the very edge of your application's entry point, you create a more robust, flexible, and predictable system.



What you think about this approach? Write your comments.



This is my first post so be kind. :)



References:

Vollständiger Original-Artikel
Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Arbeitsschutzgesetz: Der rechtliche Rahmen für Arbeitsschutz in Deutschland
1 Quelle
Harbour Masters release 'PaperBoat' their Paper Mario 64 PC port
1 Quelle
Minecraft Java Edition 26.3 'Wilderness Bound' update released
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Angular Bootstrap

Thematisch verwandte Begriffe: Angular, Bootstrap · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...