Errata zur 4. Auflage
27.04.2023
Für die 4. Auflage haben wir das Buch vollständig überarbeitet und viele Fehler beseitigt. Das war durch wertvolle Hinweise unserer Leserinnen und Leser möglich. Dennoch: Ein gedrucktes Buch ist niemals fehlerfrei, und natürlich hat sich auch in der 4. Auflage der Fehlerteufel eingeschlichen.
Haben Sie Fragen oder Hinweise, oder haben Sie einen Fehler im Buch gefunden? Bitte zögern Sie nicht, und schreiben Sie uns eine E-Mail: [email protected]
Dies ist das Errata-Verzeichnis für die 4. Auflage (2023). Wenn Sie die ältere 3. Auflage besitzen, lesen Sie bitte die Errata zur 3. Auflage.
5.2 Projekt anlegen
Zum Beginn des Buchs legen wir gemeinsam das Beispielprojekt mithilfe des Befehls ng new
an.
Seit Angular 17 werden neue Anwendungen standardmäßig mit Standalone Components generiert.
Das Beispielprojekt setzt jedoch zunächst auf NgModules und wird erst später auf Standalone Components migriert.
Damit die Beispiele im Buch weiterhin mit dem generierten Code übereinstimmen, müssen Sie die Option standalone
beim Erzeugen des Projekts explizit deaktivieren:
ng new book-monkey --routing --style=css --prefix=bm --standalone=false
Übrigens: Die Option routing
ist seit Angular 17 per Default aktiviert, sie muss also nicht mehr manuell mit angegeben werden.
5.3 Statische Assets einbinden
Im Abschnitt 5.3 auf Seite 64 erläutern wir, dass statische Assets aus dem Ordner src/assets
automatisch eingebunden werden.
In neu angelegten Projekten existiert dieser Ordner nicht mehr. Stattdessen werden statische Dateien, die beim Build mit ausgeliefert werden sollen, im neuen Ordner public
abgelegt.
Wenn wir diese Dateien einbinden, muss der Ordnerpfad nicht mehr angegeben werden. Legen wir die Datei icon.png
in den Ordner public
, wird sie aus der Anwendung heraus wie folgt eingebunden:
<img src="icon.png" alt="Icon">
5.5 @import
in SCSS ist deprecated
In Abschnitt 5.5 binden wir das Paket book-monkey5-styles
ein, um die globalen Stylesheets zu nutzen.
Dafür verwenden wir das Statement @import
in der Datei styles.css
.
Wir haben im BookMonkey zwar reines CSS eingesetzt, für die Praxis empfehlen wir aber eher, auf den Präprozessor SCSS zu setzen.
Dort funktioniert @import
grundlegend auch – das Statement wurde allerdings als deprecated markiert. @import
verweist in SCSS nur noch auf reine CSS-Imports.
Arbeiten wir mit SCSS, wird @use
empfohlen, um andere Dateien einzubinden.
// styles.scss (!)
@use 'book-monkey5-styles/index.css';
Nutzen wir nur reines CSS für das Styling der Anwendung, ist @import
weiterhin möglich – Sie müssen für die Arbeit mit dem Buch hier also zunächst nichts ändern.
20.4 Asynchroner Validator und Methode checkAvailable()
Im Abschnitt 20.4 entwickeln wir auf den Seiten 395 und 396 einen asynchronen Validator.
Die Validatormethode haben wir im Listing 20-12 usernameAvailable()
genannt.
Bei der Verwendung im darauf folgenden Listing 20-13 auf Seite 396 haben wir aber fälschlicherweise den Namen checkAvailable()
genutzt.
Korrekt muss das Listing 20-13 also lauten:
form = new FormGroup({
username: new FormControl('', {
validators: [Validators.required],
asyncValidators: [
inject(UsernameValidatorService).usernameAvailable()
]
})
});
26.7 Fehlerhafte Cypress-Tests
Test 1: should not show the administration form when not logged in
In diesem Test selektieren wir den Login-/Logout-Button in der Navigation.
Wir haben diesen Button allerdings in ein div
-Element geschachtelt, deshalb funktioniert der abgedruckte Selektor div > nav
nicht.
Stattdessen sollten wir den Test so formulieren:
cy.get('nav button')
.as('loginLogoutBtn')
// ...
Test 2: should not open the results box on server errors
Dieser Test soll nachweisen, dass die Suchergebnisbox nicht geöffnet wird, wenn der Server einen Fehler liefert – der Test schlägt allerdings fehl.
Grund dafür ist die Implementierung im BookStoreService
: In Abschnitt 15.15 haben wir hier den RxJS-Operator catchError
verwendet, um Fehler abzufangen:
getAllSearch(term: string): Observable<Book[]> {
return this.http.get<Book[]>(`${this.apiUrl}/books/search/${term}`).pipe(
catchError(err => {
console.error(err);
return of([]);
})
);
}
Die Komponente erhält also bei einem Serverfehler ein leeres Array mit Suchergebnissen. Die Ergebnisbox ist dann trotzdem sichtbar, und der Cypress-Test schlägt fehl.
Wir empfehlen Ihnen, das catchError
in der Methode getAllSearch()
wieder zu entfernen.
Dann verhält sich die Komponente so, wie wir es im Test beschrieben haben.
32.3.5 NgRx: Feature anlegen
Der im Buch abgedruckte Befehl, um ein Feature mithilfe der Schematics von NgRx anzulegen, erzeugt den folgenden Fehler:
Specified module path /src/app/books/store/books/books does not exist
Der Hintergrund: In den neueren Versionen der Feature-Schematics ist die Option entity
per Default aktiviert.
Das führt dazu, dass ein EntityAdapter
für das Feature generiert wird, wie wir es weiter hinten im Buch in Abschnitt 32.5.3 beschrieben haben.
In dieser Konstellation kann das Skript den verschachtelten Feature-Namen nicht korrekt auswerten.
Um das Problem zu lösen, muss die Option entity
expliziert deaktiviert werden.
Das erzeugte Ergebnis entspricht dann dem Code, der im Buch abgedruckt ist.
Neuer Befehl:
ng g feature books/store/book --module books/books --api --entity=false --defaults
33 Server-Side Rendering und Pre-Rendering mit Angular 17
Mit Angular 17 wurde der Build-Prozess für Server-Side Rendering und Pre-Rendering angepasst.
Ab sofort wird das neue Paket @angular/ssr
verwendet, um SSR in der Anwendung einzurichten.
Der Build für alle drei Aspekte (Browser, Server, Pre-Rendering) wird nun in einem Schritt vom neuen Application Builder ausgeführt.
Die Unterschiede zum gedruckten Buch haben wir in einem separaten Blogartikel zusammengefasst:
Suggestions? Feedback? Bugs? Please fork/edit this page on Github.