Skip to content

Die Angular Chuck Norris Challenge ist dein erster Einstieg in die Angular Webapp Entwicklung 🚀.

License

Notifications You must be signed in to change notification settings

innFactory/angular-chuck-norris

Repository files navigation

Project Logo

Start 🚀

Die Angular Chuck Norris Challenge ist dein erster Einstieg in die Angular Webapp Entwicklung. Erledige alle Challenges, damit Chuck Norris .. und die innFactory stolz auf dich sind! Im Rahmen des Projekts wirst du das Frontend einer 404 Not-Found Seite gestalten, mehr ĂŒber das Global State Management und die reaktive Programmierung in Angular erfahren, selbst eine Katzenbild-API anbinden und als Bonus Aufgabe deine Daten in einer selbst aufgesetzten, externen Datenbank speichern.


Ⅰ. Challenge đŸŽ–ïž - Start

Ⅰ.Ⅰ. GitHub Account

Jeder geschriebene Programmcode muss auch gespeichert und weitergegeben werden können. GitHub ist eine ĂŒbergreifende Entwicklerplattform die das ermöglicht und auch dieses Projekt speichert. Du wirst spĂ€ter nicht nur deinen Programmcode mit anderen Kollegen in Projekten teilen (=to publish), sondern in sogenannten Code-Reviews gegenseitig den Code ĂŒberprĂŒfen und verbessern. Code-Reviews wirst du beim Angular Chuck Norris Projekts noch nicht machen.

  • Erstelle dir, falls du noch keinen hast, zunĂ€chst einen eigenen Github Account . Dieser wird dich bei der innFactory und im spĂ€teren Entwickler-Leben noch oft begleiten đŸ€©.

Ⅰ.Ⅱ. Entwickeln aus der Entwicklungsumgebung

Softwareentwickler benötigen einen Ort an dem sie den Programmcode ansehen, schreiben und verĂ€ndern können. Dieser Ort ist die sogenannte Entwicklungsumgebung, auf englisch "Integrated Development Environment", abgekĂŒrzt IDE. FĂŒr die Angular Chuck Norris App benutzen du als IDE am Besten VS Code.

Ⅰ.ⅱ. Webapp kopieren

In GitHub online gespeicherte Software muss zum Bearbeiten erst lokal auf deinem PC kopiert werden (=to clone). Das geht ebenfalls ganz einfach mit VS Code. VS Code kommt standardmĂ€ĂŸig mit einer Anbindung fĂŒr GitHub, dem "Source Control Management".

  • Öffne den Tab des Source Control und wĂ€hle "Clone Repository". Gebe nun die URL des Repositories https://github.com/innFactory/angular-chuck-norris ein und wĂ€hle einen beliebigen Speicherort auf deinem PC.

Source Control View

Ⅰ.Ⅳ. Nodejs installieren

Die meisten Webapp Projekte haben AbhĂ€ngigkeiten an andere Bibliotheken in Form von Paketen. Diese können mit dem Node Package Manager von Nodejs unkompliziert installiert werden. Installiere dir hierfĂŒr nun Nodejs und fĂŒhre Node und NPM zum Test im Terminal in VS Code aus.

  • Installiere die Nodejs ĂŒber den Installer Nodejs Download.

  • PrĂŒfe ob die Befehle nodeund npm in deinem System global funktionieren.

  • Öffne dazu in VS Code das Terminal ĂŒber die obere Leiste View -> Terminal.

  • Gebe im Terminal die folgenden Befehle ein. Nacheinander solltest du die aktuell installierte Version sehen.

      node --version
      # Ausgabe z.B. "v22.18.0".
    
      npm --version
      # Ausgabe z.B. "10.9.3".
    
      npx --version
      # Ausgabe z.B. "10.9.3".
  • Mache dich ĂŒber die weiteren Funktionen von NPM vertraut https://docs.npmjs.com/about-npm.

Ⅰ.â…€. AbhĂ€ngigkeiten installieren

Nun musst du dir die AbhĂ€ngigkeiten bzw. Dependencies nur noch installieren. Keine Sorge, die sind in der Datei package.json bereits vollstĂ€ndig aufgelistet und können ohne weiteres ĂŒber einen Konsolenbefehl installiert werden.

  • Gebe in die Konsole npm install ein und und warte bis alle erfolgreich heruntergeladen sind.
  • Ein neuer Ordner node_modules/ mit allen externen Bibliotheken, wird nun im Projekt automatisch erstellt.

Ⅰ.â…„. Webapp starten

Nun kannst du das Webprojekt aus der Konsole starten mit npm start.

  • Öffne den Browser auf http://localhost:4200 und du solltest die Webapp sehen.

  • In der Konsole kannst du den laufenden, lokalen Client sehen.

    ~/code/intern/angular-chuck-norris
    npm start
    > [email protected] start
    > ng serve
    Initial chunk files | Names Raw size
    main.js main 116.17 kB
    styles.css I styles 10.13 kB
    | Initial total | 126.30 kB
    Application bundle generation complete. [2.387 seconds]
    Watch mode enabled. Watching for file changes...
    NOTE: Raw file sizes do not reflect development server per-request transformations.
    10:03:05 AM [vitel (client) Re-optimizing dependencies because vite config has changed
    Local: http://localhost: 4200/
    press h + enter to show help
    

Ⅰ.Ⅹ. Einstieg in die App

Jede Angular Komponente in deiner Webapp besteht aus einem Logik-, einem Struktur- und einem Stylingteil. FĂŒhle dich nicht ĂŒberfordert von all den verschiedenen Sprachen und Frameworks. Du bekommst eine Schritt fĂŒr Schritt EinfĂŒhrung in die Angular Welt.

  • Sehe dir exemplarisch einmal die "AboutSection" Komponente genauer an. Navigiere in in den Pfad src/components/about-section/ und sehe dir die Dateien an.

    Datei Function
    about-section.ts Logikteil in TypeScript
    about-section.html Strukturteil in HTML
    about-section.scss Stylingteil in SCSS
  • Schließe das interaktive Angular Einstiegs Tutorial im Browser ab. Nimm dir hierfĂŒr gerne etwas Zeit ⌛.

Ⅰ.Ⅷ. Kennenlernen mit Chuck Norris

Im Browser siehst du die Vorstellung von Chuck Norris. Weiter unten siehst du die "AboutSection". Dessen Struktur ist in der Markupsprache HTML verfasst. Im Folgenden erweiterst du diese bestehende Angular Komponente.

  • Sieh dir die Struktur der "HomePage" src/pages/home/ und der darin eingebundenen "AboutSection" src/components/about-section/ einmal genauer an.
  • Der Text "Ich bin Chuck Norris, ein Schauspieler und Kampfsportler.." ist in einem HTML <p> Paragraphen Element eingeschlossen bzw. gewrapped. So verfasst man Text in HTML.
  • Lese hier ĂŒber das Paragraphen Element auf der offiziellen HTML Dokumentation MDN Webdocs P Element
  • Recherchiere auf diesem Wikipedia Eintrag ĂŒber Chuck Norris selbst erfundene KampfkĂŒnste und fĂŒge in der "AboutSection" weitere Fakten ĂŒber Chuck Norris hinzu. Die Änderungen erscheinen beim Speichern automatisch im Browser.

Ⅱ. Challenge đŸŽ–ïž - Leseratte

Ⅱ.Ⅰ. Offiziell ist am Besten - Angular Doku

FĂŒr jedes Framework und jede Sprache gibt es eine offizielle Dokumentation. Als Entwickler ist es am Besten, dich in der Doku deiner Sprache zurechtzufinden. Alle Neuerungen und Updates stehen hier immer zuerst.

Ⅱ.Ⅱ. Komponenten Bibliothek - Angular Material

Angular hat eine eigene UI-Komponenten Bibliothek, die du optional verwenden kannst. Sie ermöglicht dir eine Auswahl an erweiterten Button, Input, Tabellen-Komponenten uvm. die du einfach einbinden kannst. Angular Material ist im Projekt bereits hinzugefĂŒgt und du kannst es einfach verwenden.

  • Sieh dir die verfĂŒgbaren Angular Material Komponenten an.
  • Um Angular Material Komponenten zu verwenden sind 3 Schritte wichtig. Hier das Beispiel der Dokumentation.
    • Der Import ĂŒber "imports { ... } from 'angular/material/...";
    • Die Angabe bei "imports: []" im Dekorator.
    • Die Verwendung im HTML

Ⅱ.ⅱ. Typensicher unterwegs - TypeScript

TypeScript ist eine von Microsoft entwickelte Programmiersprache, die JavaScript erweitert und statische Typisierung bietet. Angular Anwendungen werden in TypeScript geschrieben. Hier sind einige Vorteil von TypeScript gegenĂŒber JavaScript.

  • Statische Typisierung: Erkenne Fehler zur Entwicklungszeit und definiere Typen fĂŒr Variablen und Funktionen.
  • ModularitĂ€t: Teile deinen Code in Module fĂŒr bessere Struktur und Wartbarkeit.
  • Erweiterte Funktionen: Nutze Interfaces und Enums, um komplexe Datenstrukturen zu modellieren.
  • Überfliege die TypeScript Dokumentation zu den wichtigsten Datentypen.
  • Sieh dir die innFactory Best Practices zu TypeScript an.

Ⅱ.Ⅳ. Der Baustein des Internets - HTML

HTML wird verwendet, um die Struktur und den Inhalt von Webseiten zu definieren. Als Markupsprache beschreibt es grob zusammengefasst die Eigenschaften und den Aufbau jeder Website.

  • Elemente werden durch Tags definiert. Z.B. ein Button mit dem <button></button>-Tag.
  • Attribute: HTML-Elemente können Attribute enthalten. Z.B. ein <a></a> Link-Tag mit dem href-Attribut.
      <a href="https://beispiel.de/">Besuche meine Website</a>
  • Semantische HTML-Elemente wie <header></header>, <footer></footer>, <article></article> und <section></section> um Struktur des Inhalts klarer zu machen.
  • Weitere Ressourcen: Du kannst mehr ĂŒber HTML lernen, indem du die offizielle MDN-Webdokumentation besuchst, die detaillierte Informationen und Beispiele bietet.

Ⅱ.â…€. Schön soll es auch sein - SCSS

Da TypeScript das Programmverhalten und HTML den Website Aufbau ĂŒbernimmt, benötigst du in der Webentwicklung noch eine weitere Technik, damit die Seiten auch wirklich schön werden. Farben, Schriftarten, AbstĂ€nde uvm. werden ĂŒber CSS definiert. Damit CSS eine noch bessere Wiederverwendbarkeit bekommt gibt es die CSS Erweiterung SCSS.

Ⅱ.â…„. Hilfreiche Tipps fĂŒr diese Challenge

Hier findest du noch eine Auflistung an Tipps die Besonders fĂŒr Einsteiger hilfreich sind und dich vor ewigem RĂ€tseln und Fehlersuchen bewahren sollen, wenn du mal nicht weiterkommst.

  • Hast du Alle Dateien gespeichert? Wenn du vergisst eine Datei mit Ctrl + S zu speichern merkst du es meist nicht direkt. Wenn du auf sonderbare Fehler triffst, ist es hilfreich das gesamte Projekt ĂŒber File -> Save All zu speichern.

  • Manchmal wirst du beim Entwickeln Syntaxfehler bekommen, die dann live in dieser Konsole angezeigt werden. Normalerweise sollten sich die Konsole beim Speichern einer Datei automatisch verĂ€ndern. Es kann jedoch auch helfen den Client mit q oder Ctrl + C zu beenden und dann neu zu starten. Das kannst du beliebig oft machen und hat keine Auswirkungen.

  • In der Challenge wirst du oftmals aufgefordert Angular Komponenten / Dateien anzupassen. VS Code stellt mehrere Tools zur VerfĂŒgung, damit du diese im Projekt findest. Über die Suchleiste oben, kannst du nach Dateien suchen. Gib dort z.B. einmal "home-page" ein. In VS Code kannst du außerdem ĂŒber Edit -> Find in Files global nach Programmcode suchen. Suche z.B. einmal nach "console.log('Willkommen in den DevTools!');".

  • Oftmals wirst du auf Komponenten oder externe Bibliotheken zugreifen. Hast du sie nicht importiert, werden sie in VS Code rot unterringelt (= Linting). Hovere mit der Maus darĂŒber. Klicke auf Quick Fix ... und dann auf den richtigen Importpfad der Bibliothek. Verwendest du hier den falschen Import, funktioniert die Logik ggf. nicht richtig.

    VS Code Quick Fix

Ⅱ.â…„. Fertig! 😼‍💹

Das war aber eine Menge Input. Jetzt wird programmiert! Mache mit der ⅱ. Challenge weiter.


ⅱ. Challenge đŸŽ–ïž - Los geht's!

ⅱ.Ⅰ. Chuck Norris macht keine Fehler

Im Gegensatz zu Chuck Norris, machen wir Entwickler Fehler. Das gehört einfach zum Lernprozess dazu 🧐.

  • Versuche im Browser eine Seite zu öffnen die es in unserer Webapp noch nicht gibt z.B. http://localhost:4200/diese-seite-gibts-ganz-bestimmt.
  • Was siehst du? Eine leere Seite nur mit Header und Footer? Wie langweilig! In unserem src/pages/ Ordner fehlt noch eine "NotFoundPage".
  • In Angular erstellst du neue Komponenten am Besten aus der Kommandozeile.
  • Öffne die Konsole und fĂŒhre nun den Befehl npx ng generate component ../pages/not-found-page aus. Im src/pages/ Ordner sollte nun eine neue Angular Komponente "NotFoundPage" erscheinen.
  • Angular kommt standardmĂ€ĂŸig mit einer Routing Bibliothek. Diese ist in der Datei app.routes.ts konfiguriert.
  • FĂŒge als neuen Pfad die neue "NotFoundPage" Komponente hinzu. Beim Pfad verwendest du **. Das steht beim Angular Routing fĂŒr alle nicht-angegebenen Pfade.
  • Teste alles erneut aus. Du solltest den Text "not-found-page works!" sehen.

ⅱ.Ⅱ. Schönheit ist nicht alles - aber auch wichtig

"Es gibt keinen Schönheitswettbewerb mit Chuck Norris, denn alle wissen, dass er der einzige Gewinner wÀre."

GlĂŒckwunsch! Du hast soeben dein erste Angular Komponente entwickelt. Kannst du Chuck Norris aber auch im Witze-Duell schlagen❔


Ⅳ. Challenge đŸŽ–ïž - Lieblingswitz

Ⅳ.Ⅰ. Übersicht

In der Folgenden Challenge lernst du das Konzept der Angular Services am Beispiel des bereits bestehenden "FavouriteChuckJokesService" kennen. Im Anschluss erstellst du eine Komponente, mit der du eigene Witze eingeben kannst. Dabei kommst du auch mit der Bibliothek "Angular Material" in BerĂŒhrung. SpĂ€ter wirst du auch etwas ĂŒber den Verwendungszweck der reaktiven Angular Signals lernen.

  • Sieh dir die "JokesPage" einmal an. Gibst du einen Witz ein und klickst auf den "FAVORISIEREN" Button, erscheint er in der "FavouritesPage" bzw. der "JokeTable".
  • Das macht das Global State Management ĂŒber sogenannte Services in Angular möglich.
  • Sieh dir den Code zur "ChuckJokesCard" Komponente, zum "FavouriteChuckJokesService" Service und die "updateChucksJokeTableData()" Methode in "JokesTable" genauer an.
  • Die Methode lĂ€dt die im "FavouriteChuckJokesService" gespeicherten Witze jedes mal, bei Aufruf der in die Tabelle. Probiere es gerne selbst aus indem du neue Chuck Norris Witze lĂ€dst und favorisierst.

Ⅳ.Ⅱ. Witze-Wettbewerb

Damit du mit Chuck Norris in Konkurrenz treten kannst, wirst du nun auch eine Eigene-Witze Eingabefeld implementieren.

  • Generiere passend zur Komponente "ChuckJokesCard" ĂŒber die Konsole eine neue "OwnJokesCard".
  • FĂŒge die Komponente im HTML der "JokesPage" hinzu.
  • Kannst du analog zur "ChuckJokesCard" die "GenerationCard" im HTML der "OwnJokesCard" wiederverwenden? Diese Wiederverwendung ist die Angular Content Projection. Diese Syntax ist bereits etwas komplexer und du musst sie noch nicht ganz verstehen.
  • FĂŒge in die neue "OwnJokesCard" einen Input und einen Favorisieren Button auf der Witze Seite unterhalb der Chuck's Witze Komponente hinzu.
  • Hilfreiche Dokus dazu findest du hier zum Input und hier zum Button.

Ⅳ.ⅱ. Services in Angular

Nun hast du ein Frontend mit Eingabefeld und Button. Die Eingabe musst du nun an die Tabelle der "JokesTable" weitergeben. Diese globale VerknĂŒpfung von Daten heißt auch "Global State Management" und ist in verschiedenen Frameworks unterschiedlich aufgebaut. In Angular geht dies ĂŒber Services.

  • Sieh dir dazu die offizielle Dokumentation an und schließe das Angular Services Tutorial ab.
  • Sieh dir den "FavouriteChuckJokesService" und seine Verwendung in "ChuckJokesCard" und der "JokesTable" genauer an.
  • Implementiere nun auch einen "FavouriteOwnJokesService". Das geht auch ĂŒber den npx ng generate service ../shared/services/(name) Befehl.
  • Der Service soll auch nur ĂŒber die "add()", "remove()" und "getAll()" Methoden verwendbar sein.
  • FĂŒge in der "OwnJokesCard" eine neue Methode fĂŒr das favorisieren hinzu. Gebe den neuen, eigenen Witz ĂŒber die "add()" Methode an den Service.
  • Passe die "JokesTable" so an, dass im Konstruktor nun auch deine Eigenen Witze mitgeladen werden. Dazu kannst du eine neue Methode "updateOwnJokesTableData()" erstellen.

Ⅳ.Ⅳ. Echt peinlich: Unlustiger Witz

Im Anschluss wirst du die "JokesTable" erweitern. Du hast versehentlich einen peinlichen Witz favorisiert? Hoffentlich sehen das nicht Toni, Maxi und Tobi! 😅 In der Tabelle gibt es bereits einen Löschen Button. Aber dessen Funktion ist leider noch nicht implementiert.

  • Implementiere die "deleteRow()" Methode und greife auf die "remove()" Methoden deiner Services "FavouriteChuckJokesService" und "FavouriteOwnJokesService" zu.
  • FĂ€llt dir auf, dass die Löschung in der Tabelle erst aktualisiert wird, wenn du auf den "AKTUALISIEREN" Button klickst, oder auf eine andere Seite z.B. "Start" und wieder zurĂŒckwechselst?

Ⅳ.â…€. Die Macht der Signals

Die Tabellendaten aktualisieren sich nur manuell. Der Grund dafĂŒr ist, dass jemand dem Datenobjekt "tableData" mitteilen muss, dass sich die Witze der Services geĂ€ndert haben. Um dies eleganter zu gestalten, gibt es in Angular die Verwendung des reaktiven Programmierstils. Das geht mit sogenannten Signals.

  • Lies dir den Eintrag ĂŒber Signals in der offiziellen Angular Dokumentation durch.

  • Sieh dir den "FavouriteChuckJokesSignalService" an. Als Hilfestellung ist er im Projekt bereits implementiert. Bemerkst du die wesentlichen Unterschiede zum "FavouriteChuckJokesService"?

    • Das private Datenobjekt "data", ein verĂ€nderbares Signal vom Typ "WriteableSignal", ist hier eine Funktion und auf dessen Inhalt wird mit "data()" zugegriffen. ZusĂ€tzlich gibt es das neue, öffentliche Datenobjekt "$data". Es ist ein "read-only", berechnetes (=computed) Signal ebenfalls vom Typen "Signal".
  • Importiere zunĂ€chst an allen Stellen statt des bisherigen "FavouriteChuckJokesService" den bisher noch nicht verwendeten "FavouriteChuckJokesSignalService".

  • Jetzt wird es interessant: Anstatt "tableData" im Konstruktor mit den Services zu aktualisieren, wird es sich in Zukunft als "computed" Signal von selbst berechnen.

  • Entferne den Programmcode fĂŒr den "constructor()" und die update Funktionen aus der "JokesTable".

  • Entferne die aktuelle "tableData" Zuweisung und erstelle sie stattdessen als computed Datenobjekt. Hier eine Vorlage dafĂŒr:

    protected tableData = computed<JokeTableRow[]>(() => {
    const data: JokeTableRow[] = [];
    
        // Hier musst du nun data mit dem Signal $data aus dem "FavouriteChuckJokesSignalService" befĂŒllen
    
        return data;
    
    }
    
  • Da "tableData" nun ein Signal ist, musst du ĂŒberall dort, wo es bisher verwendet wird anstelle von "tableData" mit "tableData()" darauf zugreifen.

Wenn alles implementiert ist, aktualisieren sich die Tabellendaten nun, bei Klick auf den Löschen Button von selbst đŸ€Ż. Allerdings werden jetzt die eigenen Witze nicht mehr angezeigt. So gewinnst du leider keinen Wettbewerb gegen Chuck Norris.. đŸ€·â€â™‚ïž

Ⅳ.â…„. Hello World Signal-Service

  • Erstelle einen neuen "FavouriteOwnJokesSignalService". Die Methoden "add()", "remove()" und "getAll()" mĂŒssen angepasst werden. Orientiere dich dabei am "FavouriteChuckJokesSignalService".
  • Die Methode "setFromDatabase()" kannst du bis Challenge â…„ ersteinmal ignorieren.
  • Tausche auch den vorherigen Service ĂŒberall durch den neuen Signal Service aus.
  • ErgĂ€nze nun das "tableData" Signal der "JokesTable" Komponente auch mit dem "$data" Signal aus deinem neuen "FavouriteOwnJokesSignalService".

Probiere es gleich im Browser aus. Ab sofort berechnet sich das "tableData" Datenobjekt, bei jeglicher VerÀnderung des Eigenen und des Chucks Witze Signal Services von selbst neu. Die Tabelle aktualisiert sich im Frontend damit automatisch bzw. reaktiv.

Ⅳ.Ⅹ. Sauberkeit ist die halbe Miete

Der "AKTUALISIEREN" Button wird jetzt nicht mehr benötigt. Es folgt den Best Practices als Entwickler, unbenutzten Programmcode oder veraltete Features immer direkt zu entfernen um das Projekt simpel und verstÀndlich zu halten.

  • Entferne nun den "AKTUALISIEREN" Button und seine Funktion. Er wird nicht mehr benötigt. Herzlichen GlĂŒckwunsch, du hast diese Challenge geschafft! Das muss gefeiert werden đŸ„ł!
  • Suche zum Abschluss der Challenge im Internet z.B. auf Witze.net Flachwitze nach den peinlichsten Flachwitzen und fĂŒge Sie als eigene Witze hinzu.
  • NatĂŒrlich kannst du sie nun auch schnellstmöglich wieder löschen, bevor andere sie lesen.
  • Wenn du es jetzt aber nicht mehr abwarten kannst Bilder von sĂŒĂŸen Katzen zu sehen, dann mache direkt mit der â…€. Challenge weiter..

â…€. Challenge đŸŽ–ïž - Achtung SĂŒĂŸe Katzenbilder!

â…€.Ⅰ. Neue Katzen Seite

Nun wird das Projekt um eine Katzen Seite erweitert. Sie wird zufÀllig neue Katzenbilder aus dem Web laden, die du dann auch favorisieren kannst.

  • Erstelle im src/pages/ Ordner eine neue Komponente "CatsPage". Nutze dafĂŒr ebenfalls die Generierung aus der Konsole.
  • Erweitere die Routes Datei um einen neuen "cats" Pfad der auf die neue Komponente verweist. Du solltest sie jetzt im Browser öffnen können.
  • Damit die Seite auch per Header aufrufbar ist, musst du sie in der Navigation Komponente im HTML erweitern.
  • Damit ist die Seite fertig konfiguriert 🎉.

â…€.Ⅱ. Implementierung der Katzen Seite

Die Katzenseite soll ein Bild und zwei Buttons z.B. "NEU" und "FAVORISIEREN" beinhalten, um die Katze spÀter neu zu generieren und zu favorisieren. Konzentriere dich erst einmal auf das HTML und CSS. Du kannst wie bei den Witzen die GenerationCard Komponente wiederverwenden.

â…€.ⅱ. Ansehen der Chuck Norris Witze API

Eine Programmierschnittstelle auch kurz API ermöglicht in der Softwareentwicklung den einfachen Zugriff auf externen Programmcode. Mit den Chuck Norris Witzen ist bereits eine online API implementiert.

  • Sieh dir den JokeApiService im Projekt an. Die URL zur API befindet sich in der src/app/app.constants.ts Datei.
  • Rufe die API per Link im Browser auf https://api.chucknorris.io/jokes/random. Was siehst du?
  • Du siehst die JSON Antwort der API.
  • Aktualisiere die Seite neu. Was verĂ€ndert sich?
  • Der HTTP Zugriff auf die API erfolgt in Angular 20 vorzugsweise mit dem HttpClient und RxJS Observables. Sieh dir die offizielle Dokumentation zu den beiden an.
  • Verstehst du den Zugriff auf den Service und die reaktive Resource in der ChuckJokesCard Komponente?
  • Da TypeScript empfiehlt alle Datenobjekte zu typisieren, ist im Projekt auch die JSON RĂŒckgabe typisiert. Das Modell siehst du in src/models/api-response-chuck-joke.ts.

â…€.ⅱ. Anbindung an die Katzen API

Bei Klick auf den "NEU" Button soll in Zukunft ein zufÀlliges Katzenbild geladen werden. Dazu kannst du die Katzen API aus dem Web benutzen. Sie liefert dir jeweils eine neue Katzenbild URL, die du dann im "src" Attribut des Bildes verwendest.

  • Sieh dir die JSON der Katzen API im Browser an https://cataas.com/cat?json=true.
  • Du kannst auch den Inhalt des "url" keys einmal im Browser öffnen. Du siehst jeweils eine neue zufĂ€llige Katze.
  • Erstelle nun einen "CatApiService" passend zum "JokeApiService". Greife dann auf die reaktive Resource zu. Du kannst dich wieder an der "ChuckJokesCard" orientieren.
  • Typisiere die JSON RĂŒckgabe. Dazu erstellst du eine neue Datei unter src/models/ und markierst den Typen z.B. "CatData" mit "export type" als im Projekt global benutzbar.
  • Implementiere eine neue "urlCatPicture()" Methode in der "CatsPage", die jeweils die URL des "CatApiService" zurĂŒckgibt.
  • Orientiere dich dabei einfach an der Methode "jokeDisplayed()" der "ChuckJokesCard".
  • Implementiere eine "fetchNewCat()" Methode, die die Resource neu lĂ€dt. Rufe sie ĂŒber den "NEU" Button auf.
  • Verwende anstelle des "cat-placeholder.png" Bildes nun die zufĂ€llige URL.
  • Auf das "src" Attribut des Image greifst du von nun an mit eckigen Klammern zu. So markierst du in Angular HTML dynamische, sich verĂ€ndernde Attribute.
    <img [src]="urlCatPicture" />
    

Super, du hast soeben erfolgreich eine API angebunden. Bei Klick auf den "NEU" Button sollte jeweils ein neues Katzenbild erscheinen. Wie niedlich!

â…€.Ⅳ. Katzen Contest

Du hast es vielleicht schon erraten 😄.. Im Anschluss wirst du analog zur Witzetabelle eine neue Katzentabelle erstellen. Dort erscheinen dann die favorisierten Katzen.

  • Erstelle eine neue "CatsTable" Komponente. Kopiere einige Teile der "JokesTable". Der Syntax hierfĂŒr ist komplex, du kannst die sie auch in der Angular Material Dokumentation nachschlagen.
  • Binde die "CatsTable" Komponente auch in die "FavouritesPage" ein. Sie wird nun auch auf der Seite sichtbar.
  • Aus der Signal Challenge kennst du bereits den "FavouriteChuckJokesSignalService". Erstelle einen neuen "FavouriteCatsSignalService".
  • Er speichert anstelle von "JokeData" Daten vom Typen "CatData".
  • Nun musst du auch in der "CatsTable" Komponente die Tabellendaten als "computed" berechnen, damit sich die favorisierten oder gelöschten Katzen URLs reaktiv aktualisieren.

â…„. Challenge đŸŽ–ïž - Nur Speicherbares ist Wahres

â…„.Ⅰ. Übersicht

Die Angular Chuck Norris Webapp verfĂŒgt bereits ĂŒber weitreichende Features! Du hast bereits eine weitere online API angebunden, auf der Startseite wird ĂŒber Chuck Norris selbst erfundenen KampfkĂŒnste berichtet 😎. Es gibt die Möglichkeit Witze und Katzen Favoriten hinzuzufĂŒgen und zu löschen. Sogar eigene Witze können mit denen von Chuck Norris in Konkurrenz treten. Durch die reaktive Programmierung werden die Änderungen unmittelbar in den Tabellen aktualisiert. Mit der Verwendung von Services auf die von ĂŒberall aus zugegriffen werden kann, folgst du den Best Practices der Modularisierung!

Einen Nachteil hat unsere App bisher noch. Klickst du den Refresh Button im Browser, gehen alle favorisierten Witze und Katzen fĂŒr den Benutzer verloren. Wie schön wĂ€re es, wenn du ĂŒber Wochen und Monate die Besten Witze speichern und die Liste damit erweitern könntest đŸ€©.

Eine solche zuverlĂ€ssige Option, um Daten zu speichern und darauf jederzeit und von ĂŒberall aus zugreifen zu können, ist die Verwendung einer "Cloud Datenbank". Im Folgenden wirst in einem bereits im Projekt integrierten Cloud Service anmelden. SpĂ€ter wirst du das Projekt mit einer selbsterstellten, kostenlosen Google Firebase Datenbank verknĂŒpfen.

â…„.Ⅰ. Benutzer hinzufĂŒgen

Im Projekt ist bereits eine externe Datenbank in Google Firebase mit Firestore und dem Account der innFactory GmbH verknĂŒpft.

  • Sieh dir die Konfiguration einmal an.
    • Unter package.json sind die "@angular/fire" und "@firebase" Bibliotheken als AbhĂ€ngigkeiten angegeben.
    • Unter src/app/app.config.ts sind Firebase und Firestore Services anwendungsweit zur VerfĂŒgung gestellt.
    • Unter src/environments/environment.development.ts sind die Anmeldedaten fĂŒr den innFactory Firebase Account hinterlegt.
    • Im "JokeDatabaseService" erfolgt schlussendlich der Zugriff auf die Datenbank.
  • Erstelle dir in der OberflĂ€che der App einen neuen Benutzer und melde dich damit an.
    • Klicke auf den Benutzer Icon im Header der Webapp und dann auf Registrieren.
    • Verwende am Besten deine innFactory E-Mail. Im Hintergrund wird ein neuer Benutzer im innFactory Firebase angelegt.

â…„.Ⅱ. Datenbank Synchronisierung

Als nÀchstes werden wir die Chuck Norris Witze beim favorisieren nicht nur wie bisher an den Service, sondern auch an die Datenbank weitergeben.

  • HĂ€nge die "add()" und "remove()" Methodenaufrufe des "JokeDatabaseService" einfach denjenigen des "FavouriteChuckJokesSignalService" am Ende an. Den Witz bzw. die ID in den Methoden musst du natĂŒrlich weitergeben.
  • Melde dich erneut ĂŒber das Benutzer Icon an.
  • Wenn du nun Chuck Norris Witze favorisierst, werden sie nun automatisch der Datenbank hinzugefĂŒgt.
  • Melde dich nun ab und lade die Seite im Browser neu, sodass die Favoriten verschwinden. Melde dich nun erneut an. Die Witze sollten wieder erscheinen.

Nicht schlecht! Du hast die bestehende externe Datenbank erfolgreich angebunden đŸ‘šâ€đŸ’».

â…„.ⅱ. Sicherung eigener Witze

Damit nun auch deine eigenen Witze verewigt werden, kannst du ebenfalls den "JokeDatabaseService" in deinem "FavouriteOwnJokesSignalService" verwenden. Allerdings mĂŒssen beide noch ein wenig angepasst werden.

  • HĂ€nge die "add()" und "remove()" des Datenbank Service an diejenigen des Services fĂŒr eigene Witze.
  • Aktuell wird immer "CREATOR_CHUCK" als Ersteller verwendet. Erweitere die "JokeDatabaseService" "add()" Methode um einen Parameter fĂŒr den Ersteller "creator" und benutze diesen statt dem Festtext.
  • Jetzt kannst du den Ersteller auch jeweils passend im "FavouriteOwnJokesSignalService" und "FavouriteChuckJokesSignalService" weiterreichen.
  • Fast geschafft. Aktuell werden im Projekt bei Anmeldung die Witze geladen und bei Abmeldung wieder entfernt. Das musst du nun fĂŒr die eigenen Witze auch ergĂ€nzen.
    1. Kopiere die Methode "setFromDatabase()" aus dem "FavouriteChuckJokesSignalService" in den eigenen. Tausche die Konstante "PREFIX_ID_CHUCK_JOKES" jeweils durch "PREFIX_ID_OWN_JOKES" aus.
    2. Passe die Methode "loadJokesFromDatabase()" der "Login" Komponente src/security/login/ an.
      • Neben der "chuckJokeTableData: JokeData[]" Konstante fĂŒgst du am Besten auch eine "ownJokeTableData: JokeData[]" hinzu.
      • Diese BefĂŒllst du dann beim Ersteller "CREATOR_OWN".
      • Im Anschluss fĂŒgst in "Login" den Zugriff auf deinen Service "FavouriteOwnJokesSignalService" mit inject() hinzu.
      • Nun musst du noch dessen "setFromDatabase()" ansprechen und die "ownJokeTableData" ĂŒbergeben.
    3. Erweitere die "logout()" Methode der Menu Komponente und setze bei erfolgreichem Abmelden die Witze des FavouriteOwnJokesSignalService mit setFromDatabase([]) auf einen leeren Datensatz.

Fertig! Nun werden auch deine eigenen Witze in der Datenbank gespeichert. Teste es gleich einmal aus. Melde dich wieder ab und lade die Seite im Browser neu, sodass die Favoriten verschwinden. Melde dich nun erneut an. Deine eigenen Witze sollten nun auch wieder erscheinen. Auch das Löschen sollte funktionieren.

â…„.Ⅳ. Eigene Datenbank

Bisher bist du vor allem mit der Frontend Entwicklung in BerĂŒhrung gekommen. Im Folgenden wirst du einen eigenen Google Firebase Account Projekt erstellen und an die Angular Chuck Norris Webapp daran anbinden.

  • Melde dich auf der Google Firebase Console mit einem bestehenden Google Konto an, oder erstelle ein neues Google Konto mit deiner innFactory E-Mail.
  • Klicke auf "Neues Firebase-Projekt erstellen" und gib z.B. "angular-chuck-norris" als Projektnamen ein. Du musst weder Gemini noch das Entwicklerprogramm oder Google Analytics aktivieren.
  • Navigiere nach ProjektĂŒbersicht -> Projekteinstellungen -> Allgemein. Unter Meine Apps klickst du auf das </> Symbol fĂŒr Web um Firebase zu einer Webapp hinzuzufĂŒgen.
  • Benutze als Alias auch den Projektnamen "angular-chuck-norris" und klicke auf App registrieren.
  • Du erhĂ€ltst eine Übersicht zum Setup. Das wurde aber schon fertig eingestellt. Kopiere dir nur den Inhalt mit folgendem Schema heraus:
      apiKey: '...',
      authDomain: 'angular-chuck-norris.firebaseapp.com',
      projectId: 'angular-chuck-norris',
      storageBucket: 'angular-chuck-norris.firebasestorage.app',
      messagingSenderId: '...',
      appId: '...',
    
  • FĂŒge diesen Inhalt nun in die src/environments/environment.development.ts Datei in das "firebase" Attribut ein.
  • Stoppe den laufenden Angular Client im Terminal mit Cmd + C oder durch Eingabe von q + Enter fĂŒr "quit".
  • Starte den Client neu mit npm start
  • In der Browser Konsole sollten keine Fehler wie z.B. "auth/invalid-api-key" erscheinen.

Nun ist die App erfolgreich mit Firebase verbunden. Beim Registrieren oder Anmelden erhĂ€ltst du noch richtigerweise einen "❌ ... fehlgeschlagen" Hinweis.

â…„.â…€. Datenbank Konfiguration

Die Authentifizierung per E-Mail und Passwort muss im Firebase Projekt aktiviert werden.

  • Navigiere im Firebase HauptmenĂŒ im Reiter links nach Entwickeln -> Authentication und klicke auf den Los geht's Button.

  • Bei Anmeldemethode aktivierst du E-Mail-Adresse/Passwort. E-Mail-Link kannst du deaktiviert lassen. BestĂ€tige die Konfiguration mit Speichern.

  • Jetzt sollte die Registrierung und Anmeldung unmittelbar funktionieren. Unter Authentication -> Nutzer kannst du den neu erstellten Benutzer sehen.

  • Damit nun auch die Datenbank-Speicherung funktioniert, musst du in Firebase noch Firestore Datenbanken aktivieren.

  • Navigiere im Firebase HauptmenĂŒ im Reiter links nach Entwickeln -> Firestore Database und klicke auf den Datenbank erstellen Button. WĂ€hle einen Standort in Europa.

  • WĂ€hle die Option Im Produktionsmodus starten und bestĂ€tige mit dem Erstellen Button.

  • Navigiere nun im Reiter oben auf Regeln. Du siehst bereits voreingestellte Zugriffsregeln die du nun entfernst. Folgende Regeln kannst du komplett kopieren und einfĂŒgen. Du musst nichts weiter anpassen.

    rules_version = '1';
    
    service cloud.firestore {
    match /databases/{database}/documents {
    
          // Only read, create for signed in users
          match /users/{userID} {
            allow delete: if false;
            allow read, create: if isSignedIn() && isAllowedToChangeTable(userID);
    
            // Only read, create, delete in table with userID equals email
            match /jokes/{jokeID} {
              allow delete, create, read, update: if isSignedIn() && isAllowedToChangeTable(userID);
            }
    
            // Only read, create, delete in table with userID equals email
            match /cats/{catID} {
              allow delete, create, read, update: if isSignedIn() && isAllowedToChangeTable(userID);
            }
          }
        }
    
        function isSignedIn() {
          return request.auth != null;
        }
    
        function isAllowedToChangeTable(userID) {
          return request.auth.token.email == userID;
        }
    
    }
    
  • Klicke auf den Veröffentlichen Button

Fertig! Du hast deine eigene Datenbank mit Benutzer Authentifizierung richtig erstellt und konfiguriert đŸ„ł. Teste es direkt einmal aus. Nun solltest du eigene Witze und Chuck Norris Witze ganz einfach favorisieren können, dich ab- und anmelden und sie erscheinen erneut.

â…„.â…„. Katzen-Transferaufgabe đŸ±

In der letzten Challenge wirst du einen neuen Service erstellen, der fĂŒr die Verwaltung einer Katzen-Datenbanktabelle verantwortlich ist. Dieser Service wird bei der Benutzeranmeldung geladen und beim Logout gelöscht. Hier sind die Details zu den erforderlichen Schritten.

  • Erstelle unter src/models/ einen neuen Typen "FirebaseCatTableRow". Er bekommt die Attribute "id" und "url" jeweils vom Typ "string".
  • Erstelle einen neuen "CatDatabaseService". Du kannst den Code des "JokeDatabaseServices" hierfĂŒr einfach kopieren.
  • Als "FIREBASE_TABLE_NAME" verwendest du die "cats" Tabelle, anstatt der jokeID jeweils eine catID.
  • In der "add()" Methode benötigst du nur noch die Parameter "catID" und "url" vom Typ string. "catData" hat nur das Feld "url", das du ĂŒbergibst.
  • Verwende "FirebaseCatTableRow" im "CatDatabaseService" anstelle von "FirebaseJokeTableRow". Tausche auch die ĂŒbrigen Parameternamen so aus, sodass sie zum "CatDatabaseService" passen.
  • Passe auch die BefĂŒllung des "cats" Arrays in der "getAll()" Methode an.
  • ErgĂ€nze nun die "add()" und "remove()" Methoden des "FavouriteCatsService" um den Aufruf des neuen "CatDatabaseService". FĂŒge eine Methode "setFromDatabase()" hinzu und verwende hier "PREFIX_ID_CATS".
  • Damit die Katzen-URLs nach der Anmeldung geladen werden, fĂŒgst du der "login()" Methode der Login Komponente eine neue Methode "loadCatsFromDatabase()" hinzu. Die du bei erfolgreicher Anmeldung aufrufst.
  • Bei Abmeldung soll die Katzentabelle gelöscht werden. Setze die Daten des "FavouriteCatsSignalService" in der "logout()" Methode der Menu Komponente auf ein leeres Array.

GlĂŒckwunsch, du hast alle Challenges gemeistert. Chuck Norris und die innFactory sind stolz auf deine Webdevelopment KĂŒnste đŸ€©.

transparent-spacing

Chuck Norris Laughing

Foto von Craig Michaud, lizenziert unter CC BY 3.0.

Angular Icon in Favicon und Readme Intro von Angular, lizenziert unter CC BY 4.0. Das Icon wurde editiert.


VII. Links 🔗

Dieser Abschnitt enthÀlt alle externen Links. So können sie schnell & an einer Stelle geupdated werden.

(Links unsichtbar in der Vorschau)

About

Die Angular Chuck Norris Challenge ist dein erster Einstieg in die Angular Webapp Entwicklung 🚀.

Resources

License

Stars

Watchers

Forks