Skip to content

Commit f11143b

Browse files
author
The Buildbot
committed
1 parent bb14dce commit f11143b

File tree

59 files changed

+482
-78
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+482
-78
lines changed

404.html

Lines changed: 3 additions & 3 deletions
Large diffs are not rendered by default.

assets/data/bloglist.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

assets/data/posts/2018-05-angular6.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

assets/data/posts/2024-10-28-resource-api.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

assets/data/posts/2024-10-resource-api.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

assets/data/posts/errata-3a.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

assets/data/posts/errata-4a.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"slug":"errata-4a","html_url":"https://github.com/angular-buch/website-articles/blob/gh-pages/blog/errata-4a/README.md","html":"<p>Für die 4. Auflage haben wir das Buch vollständig überarbeitet und viele Fehler beseitigt.\nDas 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.</p>\n<p><strong>Haben Sie Fragen oder Hinweise, oder haben Sie einen Fehler im Buch gefunden?\nBitte zögern Sie nicht, und schreiben Sie uns eine E-Mail: <a href=\"mailto:&#x74;&#x65;&#x61;&#x6d;&#64;&#x61;&#x6e;&#103;&#x75;&#108;&#x61;&#114;&#x2d;&#98;&#x75;&#99;&#104;&#x2e;&#99;&#111;&#109;\">&#x74;&#x65;&#x61;&#x6d;&#64;&#x61;&#x6e;&#103;&#x75;&#108;&#x61;&#114;&#x2d;&#98;&#x75;&#99;&#104;&#x2e;&#99;&#111;&#109;</a></strong></p>\n<blockquote>\n<p><strong>Dies ist das Errata-Verzeichnis für die 4. Auflage (2023). Wenn Sie die ältere 3. Auflage besitzen, lesen Sie bitte die <a href=\"/blog/errata-3a\">Errata zur 3. Auflage</a>.</strong></p>\n</blockquote>\n<hr>\n<h3 id=\"52-projekt-anlegen\">5.2 Projekt anlegen</h3>\n<p>Zum Beginn des Buchs legen wir gemeinsam das Beispielprojekt mithilfe des Befehls <code>ng new</code> an.\nSeit Angular 17 werden neue Anwendungen standardmäßig mit Standalone Components generiert.\nDas Beispielprojekt setzt jedoch zunächst auf NgModules und wird erst später auf Standalone Components migriert.</p>\n<p>Damit die Beispiele im Buch weiterhin mit dem generierten Code übereinstimmen, müssen Sie die Option <code>standalone</code> beim Erzeugen des Projekts explizit deaktivieren:</p>\n<pre><code class=\"language-sh\">ng new book-monkey --routing <span class=\"hljs-attribute\">--style</span>=css <span class=\"hljs-attribute\">--prefix</span>=bm <span class=\"hljs-attribute\">--standalone</span>=<span class=\"hljs-literal\">false</span>\n</code></pre>\n<p>Übrigens: Die Option <code>routing</code> ist seit Angular 17 per Default aktiviert, sie muss also nicht mehr manuell mit angegeben werden.</p>\n<h3 id=\"204-asynchroner-validator-und-methode-checkavailable\">20.4 Asynchroner Validator und Methode <code>checkAvailable()</code></h3>\n<p>Im Abschnitt 20.4 entwickeln wir auf den Seiten 395 und 396 einen asynchronen Validator.\nDie Validatormethode haben wir im Listing 20-12 <code>usernameAvailable()</code> genannt.\nBei der Verwendung im darauf folgenden Listing 20-13 auf Seite 396 haben wir aber fälschlicherweise den Namen <code>checkAvailable()</code> genutzt.</p>\n<p>Korrekt muss das Listing 20-13 also lauten:</p>\n<pre><code class=\"language-ts\">form = <span class=\"hljs-keyword\">new</span> FormGroup({\n username: <span class=\"hljs-keyword\">new</span> FormControl(<span class=\"hljs-string\">&#x27;&#x27;</span>, {\n validators: [Validators.<span class=\"hljs-keyword\">required</span>],\n asyncValidators: [\n inject(UsernameValidatorService).usernameAvailable()\n ]\n })\n});\n</code></pre>\n<h3 id=\"267-fehlerhafte-cypress-tests\">26.7 Fehlerhafte Cypress-Tests</h3>\n<h4 id=\"test-1-should-not-show-the-administration-form-when-not-logged-in\">Test 1: <code>should not show the administration form when not logged in</code></h4>\n<p>In diesem Test selektieren wir den Login-/Logout-Button in der Navigation.\nWir haben diesen Button allerdings in ein <code>div</code>-Element geschachtelt, deshalb funktioniert der abgedruckte Selektor <code>div &gt; nav</code> nicht.</p>\n<p>Stattdessen sollten wir den Test so formulieren:</p>\n<pre><code class=\"language-ts\">cy.<span class=\"hljs-keyword\">get</span>(<span class=\"hljs-string\">&#x27;nav button&#x27;</span>)\n .<span class=\"hljs-keyword\">as</span>(<span class=\"hljs-string\">&#x27;loginLogoutBtn&#x27;</span>)\n <span class=\"hljs-comment\">// ...</span>\n</code></pre>\n<h4 id=\"test-2-should-not-open-the-results-box-on-server-errors\">Test 2: <code>should not open the results box on server errors</code></h4>\n<p>Dieser Test soll nachweisen, dass die Suchergebnisbox nicht geöffnet wird, wenn der Server einen Fehler liefert – der Test schlägt allerdings fehl.\nGrund dafür ist die Implementierung im <code>BookStoreService</code>: In Abschnitt 15.15 haben wir hier den RxJS-Operator <code>catchError</code> verwendet, um Fehler abzufangen:</p>\n<pre><code class=\"language-ts\">getAllSearch(term: <span class=\"hljs-built_in\">string</span>): Observable&lt;Book[]&gt; {\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">this</span>.http.get&lt;Book[]&gt;(<span class=\"hljs-string\">`<span class=\"hljs-subst\">${<span class=\"hljs-built_in\">this</span>.apiUrl}</span>/books/search/<span class=\"hljs-subst\">${term}</span>`</span>).pipe(\n catchError(<span class=\"hljs-function\"><span class=\"hljs-params\">err</span> =&gt;</span> {\n <span class=\"hljs-built_in\">console</span>.error(err);\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">of</span>([]);\n })\n );\n}\n</code></pre>\n<p>Die Komponente erhält also bei einem Serverfehler ein leeres Array mit Suchergebnissen.\nDie Ergebnisbox ist dann trotzdem sichtbar, und der Cypress-Test schlägt fehl.</p>\n<p>Wir empfehlen Ihnen, das <code>catchError</code> in der Methode <code>getAllSearch()</code> wieder zu entfernen.\nDann verhält sich die Komponente so, wie wir es im Test beschrieben haben.</p>\n<h3 id=\"3235-ngrx-feature-anlegen\">32.3.5 NgRx: Feature anlegen</h3>\n<p>Der im Buch abgedruckte Befehl, um ein Feature mithilfe der Schematics von NgRx anzulegen, erzeugt den folgenden Fehler:</p>\n<pre><code>Specified module path <span class=\"hljs-regexp\">/src/</span>app<span class=\"hljs-regexp\">/books/</span>store<span class=\"hljs-regexp\">/books/</span>books does not exist\n</code></pre>\n<p>Der Hintergrund: In den neueren Versionen der Feature-Schematics ist die Option <code>entity</code> per Default aktiviert.\nDas führt dazu, dass ein <code>EntityAdapter</code> für das Feature generiert wird, wie wir es weiter hinten im Buch in Abschnitt 32.5.3 beschrieben haben.\nIn dieser Konstellation kann das Skript den verschachtelten Feature-Namen nicht korrekt auswerten.</p>\n<p>Um das Problem zu lösen, muss die Option <code>entity</code> expliziert deaktiviert werden.\nDas erzeugte Ergebnis entspricht dann dem Code, der im Buch abgedruckt ist.</p>\n<p><strong>Neuer Befehl:</strong></p>\n<pre><code class=\"language-sh\"><span class=\"hljs-comment\">ng</span> <span class=\"hljs-comment\">g</span> <span class=\"hljs-comment\">feature</span> <span class=\"hljs-comment\">books/store/book</span> --<span class=\"hljs-comment\">module</span> <span class=\"hljs-comment\">books/books</span> --<span class=\"hljs-comment\">api</span> --<span class=\"hljs-comment\">entity=false</span> --<span class=\"hljs-comment\">defaults</span>\n</code></pre>\n<h3 id=\"33-server-side-rendering-und-pre-rendering-mit-angular-17\">33 Server-Side Rendering und Pre-Rendering mit Angular 17</h3>\n<p>Mit Angular 17 wurde der Build-Prozess für Server-Side Rendering und Pre-Rendering angepasst.\nAb sofort wird das neue Paket <code>@angular/ssr</code> verwendet, um SSR in der Anwendung einzurichten.\nDer Build für alle drei Aspekte (Browser, Server, Pre-Rendering) wird nun in einem Schritt vom neuen Application Builder ausgeführt.</p>\n<p>Die Unterschiede zum gedruckten Buch haben wir in einem separaten Blogartikel zusammengefasst:</p>\n<p><strong><a href=\"/blog/2023-11-ssr-bm\">Book Monkey v5: Server-Side Rendering mit Angular 17</a></strong></p>\n","meta":{"title":"Errata zur 4. Auflage","author":"Angular Buch Team","mail":"[email protected]","published":"2023-04-27T00:00:00.000Z","lastModified":"2024-03-22T00:00:00.000Z","keywords":["Angular","Errata","Fehlerverzeichnis","4. Auflage"],"language":"de"}}
1+
{"slug":"errata-4a","html_url":"https://github.com/angular-buch/website-articles/blob/gh-pages/blog/errata-4a/README.md","html":"<p>Für die 4. Auflage haben wir das Buch vollständig überarbeitet und viele Fehler beseitigt.\nDas 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.</p>\n<p><strong>Haben Sie Fragen oder Hinweise, oder haben Sie einen Fehler im Buch gefunden?\nBitte zögern Sie nicht, und schreiben Sie uns eine E-Mail: <a href=\"mailto:&#x74;&#x65;&#97;&#x6d;&#64;&#97;&#x6e;&#x67;&#117;&#x6c;&#x61;&#x72;&#x2d;&#x62;&#117;&#99;&#104;&#46;&#x63;&#111;&#x6d;\">&#x74;&#x65;&#97;&#x6d;&#64;&#97;&#x6e;&#x67;&#117;&#x6c;&#x61;&#x72;&#x2d;&#x62;&#117;&#99;&#104;&#46;&#x63;&#111;&#x6d;</a></strong></p>\n<blockquote>\n<p><strong>Dies ist das Errata-Verzeichnis für die 4. Auflage (2023). Wenn Sie die ältere 3. Auflage besitzen, lesen Sie bitte die <a href=\"/blog/errata-3a\">Errata zur 3. Auflage</a>.</strong></p>\n</blockquote>\n<hr>\n<h3 id=\"52-projekt-anlegen\">5.2 Projekt anlegen</h3>\n<p>Zum Beginn des Buchs legen wir gemeinsam das Beispielprojekt mithilfe des Befehls <code>ng new</code> an.\nSeit Angular 17 werden neue Anwendungen standardmäßig mit Standalone Components generiert.\nDas Beispielprojekt setzt jedoch zunächst auf NgModules und wird erst später auf Standalone Components migriert.</p>\n<p>Damit die Beispiele im Buch weiterhin mit dem generierten Code übereinstimmen, müssen Sie die Option <code>standalone</code> beim Erzeugen des Projekts explizit deaktivieren:</p>\n<pre><code class=\"language-sh\">ng new book-monkey --routing <span class=\"hljs-attribute\">--style</span>=css <span class=\"hljs-attribute\">--prefix</span>=bm <span class=\"hljs-attribute\">--standalone</span>=<span class=\"hljs-literal\">false</span>\n</code></pre>\n<p>Übrigens: Die Option <code>routing</code> ist seit Angular 17 per Default aktiviert, sie muss also nicht mehr manuell mit angegeben werden.</p>\n<h3 id=\"204-asynchroner-validator-und-methode-checkavailable\">20.4 Asynchroner Validator und Methode <code>checkAvailable()</code></h3>\n<p>Im Abschnitt 20.4 entwickeln wir auf den Seiten 395 und 396 einen asynchronen Validator.\nDie Validatormethode haben wir im Listing 20-12 <code>usernameAvailable()</code> genannt.\nBei der Verwendung im darauf folgenden Listing 20-13 auf Seite 396 haben wir aber fälschlicherweise den Namen <code>checkAvailable()</code> genutzt.</p>\n<p>Korrekt muss das Listing 20-13 also lauten:</p>\n<pre><code class=\"language-ts\">form = <span class=\"hljs-keyword\">new</span> FormGroup({\n username: <span class=\"hljs-keyword\">new</span> FormControl(<span class=\"hljs-string\">&#x27;&#x27;</span>, {\n validators: [Validators.<span class=\"hljs-keyword\">required</span>],\n asyncValidators: [\n inject(UsernameValidatorService).usernameAvailable()\n ]\n })\n});\n</code></pre>\n<h3 id=\"267-fehlerhafte-cypress-tests\">26.7 Fehlerhafte Cypress-Tests</h3>\n<h4 id=\"test-1-should-not-show-the-administration-form-when-not-logged-in\">Test 1: <code>should not show the administration form when not logged in</code></h4>\n<p>In diesem Test selektieren wir den Login-/Logout-Button in der Navigation.\nWir haben diesen Button allerdings in ein <code>div</code>-Element geschachtelt, deshalb funktioniert der abgedruckte Selektor <code>div &gt; nav</code> nicht.</p>\n<p>Stattdessen sollten wir den Test so formulieren:</p>\n<pre><code class=\"language-ts\">cy.<span class=\"hljs-keyword\">get</span>(<span class=\"hljs-string\">&#x27;nav button&#x27;</span>)\n .<span class=\"hljs-keyword\">as</span>(<span class=\"hljs-string\">&#x27;loginLogoutBtn&#x27;</span>)\n <span class=\"hljs-comment\">// ...</span>\n</code></pre>\n<h4 id=\"test-2-should-not-open-the-results-box-on-server-errors\">Test 2: <code>should not open the results box on server errors</code></h4>\n<p>Dieser Test soll nachweisen, dass die Suchergebnisbox nicht geöffnet wird, wenn der Server einen Fehler liefert – der Test schlägt allerdings fehl.\nGrund dafür ist die Implementierung im <code>BookStoreService</code>: In Abschnitt 15.15 haben wir hier den RxJS-Operator <code>catchError</code> verwendet, um Fehler abzufangen:</p>\n<pre><code class=\"language-ts\">getAllSearch(term: <span class=\"hljs-built_in\">string</span>): Observable&lt;Book[]&gt; {\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-built_in\">this</span>.http.get&lt;Book[]&gt;(<span class=\"hljs-string\">`<span class=\"hljs-subst\">${<span class=\"hljs-built_in\">this</span>.apiUrl}</span>/books/search/<span class=\"hljs-subst\">${term}</span>`</span>).pipe(\n catchError(<span class=\"hljs-function\"><span class=\"hljs-params\">err</span> =&gt;</span> {\n <span class=\"hljs-built_in\">console</span>.error(err);\n <span class=\"hljs-keyword\">return</span> <span class=\"hljs-keyword\">of</span>([]);\n })\n );\n}\n</code></pre>\n<p>Die Komponente erhält also bei einem Serverfehler ein leeres Array mit Suchergebnissen.\nDie Ergebnisbox ist dann trotzdem sichtbar, und der Cypress-Test schlägt fehl.</p>\n<p>Wir empfehlen Ihnen, das <code>catchError</code> in der Methode <code>getAllSearch()</code> wieder zu entfernen.\nDann verhält sich die Komponente so, wie wir es im Test beschrieben haben.</p>\n<h3 id=\"3235-ngrx-feature-anlegen\">32.3.5 NgRx: Feature anlegen</h3>\n<p>Der im Buch abgedruckte Befehl, um ein Feature mithilfe der Schematics von NgRx anzulegen, erzeugt den folgenden Fehler:</p>\n<pre><code>Specified module path <span class=\"hljs-regexp\">/src/</span>app<span class=\"hljs-regexp\">/books/</span>store<span class=\"hljs-regexp\">/books/</span>books does not exist\n</code></pre>\n<p>Der Hintergrund: In den neueren Versionen der Feature-Schematics ist die Option <code>entity</code> per Default aktiviert.\nDas führt dazu, dass ein <code>EntityAdapter</code> für das Feature generiert wird, wie wir es weiter hinten im Buch in Abschnitt 32.5.3 beschrieben haben.\nIn dieser Konstellation kann das Skript den verschachtelten Feature-Namen nicht korrekt auswerten.</p>\n<p>Um das Problem zu lösen, muss die Option <code>entity</code> expliziert deaktiviert werden.\nDas erzeugte Ergebnis entspricht dann dem Code, der im Buch abgedruckt ist.</p>\n<p><strong>Neuer Befehl:</strong></p>\n<pre><code class=\"language-sh\"><span class=\"hljs-comment\">ng</span> <span class=\"hljs-comment\">g</span> <span class=\"hljs-comment\">feature</span> <span class=\"hljs-comment\">books/store/book</span> --<span class=\"hljs-comment\">module</span> <span class=\"hljs-comment\">books/books</span> --<span class=\"hljs-comment\">api</span> --<span class=\"hljs-comment\">entity=false</span> --<span class=\"hljs-comment\">defaults</span>\n</code></pre>\n<h3 id=\"33-server-side-rendering-und-pre-rendering-mit-angular-17\">33 Server-Side Rendering und Pre-Rendering mit Angular 17</h3>\n<p>Mit Angular 17 wurde der Build-Prozess für Server-Side Rendering und Pre-Rendering angepasst.\nAb sofort wird das neue Paket <code>@angular/ssr</code> verwendet, um SSR in der Anwendung einzurichten.\nDer Build für alle drei Aspekte (Browser, Server, Pre-Rendering) wird nun in einem Schritt vom neuen Application Builder ausgeführt.</p>\n<p>Die Unterschiede zum gedruckten Buch haben wir in einem separaten Blogartikel zusammengefasst:</p>\n<p><strong><a href=\"/blog/2023-11-ssr-bm\">Book Monkey v5: Server-Side Rendering mit Angular 17</a></strong></p>\n","meta":{"title":"Errata zur 4. Auflage","author":"Angular Buch Team","mail":"[email protected]","published":"2023-04-27T00:00:00.000Z","lastModified":"2024-03-22T00:00:00.000Z","keywords":["Angular","Errata","Fehlerverzeichnis","4. Auflage"],"language":"de"}}

assets/scully-routes.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{"route":"/"},{"route":"/material"},{"route":"/material/3"},{"route":"/material/4"},{"route":"/material/archiv"},{"route":"/impressum"},{"route":"/datenschutz"},{"route":"/autoren"},{"route":"/blog"},{"route":"/updates"},{"route":"/kaufen"},{"route":"/blog/2024-06-angular18"},{"route":"/blog/2024-05-modern-angular-bm"},{"route":"/blog/2023-11-ssr-bm"},{"route":"/blog/2023-11-angular17"},{"route":"/blog/2023-05-angular16"},{"route":"/blog/errata-4a"},{"route":"/blog/2023-02-neu-vierte-auflage"},{"route":"/blog/2022-12-changelog-vierte-auflage"},{"route":"/blog/2022-11-use-define-for-class-fields"},{"route":"/blog/2022-11-angular15"},{"route":"/blog/2022-06-bm4-update"},{"route":"/blog/2022-06-angular14"},{"route":"/blog/2021-11-angular13"},{"route":"/blog/2021-06-angular12"},{"route":"/blog/errata-3a"},{"route":"/blog/2020-11-twa"},{"route":"/blog/2020-11-angular11"},{"route":"/blog/2020-10-neu-dritte-auflage"},{"route":"/blog/2020-08-changelog-dritte-auflage"},{"route":"/blog/2020-06-angular10"},{"route":"/blog/2020-02-angular9"},{"route":"/blog/2019-12-docker3-multi-stage-build"},{"route":"/blog/2019-12-docker2-build-once-run-anywhere"},{"route":"/blog/2019-12-docker1-simple-case"},{"route":"/blog/2019-12-docker0-intro"},{"route":"/blog/2019-07-progressive-web-app"},{"route":"/blog/2019-06-das-neue-buch"},{"route":"/blog/2019-06-changelog-zweite-auflage"},{"route":"/blog/2019-06-ngrx8"},{"route":"/blog/2019-06-angular8"},{"route":"/blog/2018-10-angular7"},{"route":"/blog/2018-05-angular6"},{"route":"/blog/2017-12-ng5-i18n"},{"route":"/blog/2017-12-book-monkey-upgrade"},{"route":"/blog/2017-12-angular5"},{"route":"/blog/2017-11-httpclient"}]
1+
[{"route":"/"},{"route":"/material"},{"route":"/material/3"},{"route":"/material/4"},{"route":"/material/archiv"},{"route":"/impressum"},{"route":"/datenschutz"},{"route":"/autoren"},{"route":"/blog"},{"route":"/updates"},{"route":"/kaufen"},{"route":"/blog/2024-06-angular18"},{"route":"/blog/2024-10-resource-api"},{"route":"/blog/2024-05-modern-angular-bm"},{"route":"/blog/2023-11-ssr-bm"},{"route":"/blog/2023-11-angular17"},{"route":"/blog/2023-05-angular16"},{"route":"/blog/errata-4a"},{"route":"/blog/2023-02-neu-vierte-auflage"},{"route":"/blog/2022-12-changelog-vierte-auflage"},{"route":"/blog/2022-11-use-define-for-class-fields"},{"route":"/blog/2022-11-angular15"},{"route":"/blog/2022-06-bm4-update"},{"route":"/blog/2022-06-angular14"},{"route":"/blog/2021-11-angular13"},{"route":"/blog/2021-06-angular12"},{"route":"/blog/errata-3a"},{"route":"/blog/2020-11-twa"},{"route":"/blog/2020-11-angular11"},{"route":"/blog/2020-10-neu-dritte-auflage"},{"route":"/blog/2020-08-changelog-dritte-auflage"},{"route":"/blog/2020-06-angular10"},{"route":"/blog/2020-02-angular9"},{"route":"/blog/2019-12-docker3-multi-stage-build"},{"route":"/blog/2019-12-docker2-build-once-run-anywhere"},{"route":"/blog/2019-12-docker1-simple-case"},{"route":"/blog/2019-12-docker0-intro"},{"route":"/blog/2019-07-progressive-web-app"},{"route":"/blog/2019-06-das-neue-buch"},{"route":"/blog/2019-06-changelog-zweite-auflage"},{"route":"/blog/2019-06-ngrx8"},{"route":"/blog/2019-06-angular8"},{"route":"/blog/2018-10-angular7"},{"route":"/blog/2018-05-angular6"},{"route":"/blog/2017-12-ng5-i18n"},{"route":"/blog/2017-12-book-monkey-upgrade"},{"route":"/blog/2017-12-angular5"},{"route":"/blog/2017-11-httpclient"}]

0 commit comments

Comments
 (0)