Alle Folgen

Webcafé — Folge 25

React ToDo-App - Teil 2

Kay hat eine Beispielanwendung entwickelt, anhand der wir uns Stück für Stück durch unseren Entwicklungsprozess arbeiten.

hören lesen

Folge 25 React ToDo-App - Teil 2 50 min · 5 Kapitel
0:00 50:16

Am Mikrofon

01 — Worum geht es

Worum geht es?

Kay hat eine Beispielanwendung entwickelt, anhand der wir uns Stück für Stück durch unseren Entwicklungsprozess arbeiten. Im zweiten Teil geht es tief in den Code und wir schauen uns die CRUD-Funktionen in der actions.ts an. Dabei streifen wir u.a. Themen wie Typisierung, Signals, States, Errors und Validierung.

02 — Transkript

Das Gespräch, Wort für Wort

Kapitel

7.630 Wörter in 5 Abschnitten. Jede Zeitmarke springt an die passende Stelle im Audio. Automatisch transkribiert und maschinell nachkorrigiert — im Zweifel gilt das Gesprochene.

Intro 0:00–2:00

  1. 0:00

    Hallo zu Part 2 von unserer Folge über unsere To-Do-App.

  2. 0:10

    Und Kay, für uns ist es ein Novum, weil wir direkt im Anschluss aufnehmen. Das haben wir bisher noch nie gemacht. Wir haben immer die Folgen separat aufgenommen. Aber jetzt haben wir hier direkt Teil 2 auch mit aufgenommen. Von daher können wir auch noch nicht auf Feedback eingehen. Das geht dann vielleicht in der nächsten Folge. Ganz kurzer Abriss, damit man hier den Anschluss kriegt. Wir haben uns mit dieser To-Do-App beschäftigt und sind da eingegangen auf das Konzept. Darauf, wie wir die Installation machen. Und den Projektbaum haben wir uns einmal angeguckt. Und wollen uns als nächstes jetzt hier das Modul To-Do angucken.

  3. 0:46

    Das ist so unser Plan. Ich habe, weil das hier eine ganz eigene Folge ist, mir auch einen neuen Tee gemacht. Kay, kannst du da mithalten? Nee, tatsächlich. Ich habe den anderen Tee noch nicht ganz verdaut. Und wenn ich jetzt noch einen draufgieße, dann muss ich wirklich zwischendurch weg. Ich wusste, dass ich dich kriege. Eihihi. Ja, ich für meinen Teil habe mir nämlich einen fruchtigen Winterpunch gemacht. Nee, Winterpunch. Einen fruchtigen Winterpunch. Und das ist so ein Bio-Früchte-Gewürztee. Der hat nur ein Problem. Der ist nicht fruchtig. Also, der ist eigentlich nur ein Winterpunch. Eigentlich so ein Kräutertee schmeckt mir jetzt nicht so irre gut.

  4. 1:25

    Aber passt zur Jahreszeit. Von daher werde ich damit hier für die Folge mal mit Stimme ölen. Ich habe das letzte Mal schon gedacht, als du quasi vor einer Stunde uns erzählt hast, wie großartig dein Ausflug da auf Mauritius war. Und du willst ja so noch, dass du den Tee in Zukunft selber pflückst. Und da kann es jetzt ja eigentlich nur ein Downgrade im nächsten Schritt sein, wenn du einfach so einen Früchtetee aus dem Laden präsentierst. Ja, das stimmt. Eben, als ich meine Tee-Schublade durchgeguckt habe, habe ich geniale Tees gefunden, die ich auch in der nächsten Folge noch präsentieren werde.

  5. 1:55

    Also, ihr könnt gespannt sein. Hervorragend. Wir machen direkt weiter mit Kapitel 4, dem Modul To-Do. Und dafür gehen wir jetzt auch wirklich mal in den Code rein. Das war jetzt alles sehr abstrakt und sehr konzeptionell. Aber jetzt gehen wir mal wirklich rein. Und dafür schauen wir uns als allererstes die Types im Modul To-Do an. Das heißt, wer das im GitLab nachschauen möchte, wir sind jetzt unter Source, Modules und To-Do und haben da als erstes eine Datei mit dem Namen Types.ds. Und das ist auch so eine Sache, die sich bewahrt hat, nämlich die Types und alles zu typisieren und möglichst auch aufzuteilen,

Entities & Types 2:00–7:00

  1. 2:38

    sodass man nicht eine große Datei hat, wo alles drin hängt, sondern das so ein bisschen unterteilt. Und auch hier Types wieder. Wir denken wieder an mein Monolog über die Namespaces vom letzten Mal. Das Ding heißt nur Types und nicht irgendwie To-Do-Types oder sonst irgendwas. Und was wir darin finden, ist vor allem die TypeScript-Repräsentation von dieser Entity, die wir uns in der letzten Folge überlegt haben. Und dafür erstellen wir auch ein Interface, das wir To-Do nennen. Und da repräsentieren wir genau die Eigenschaften, über die wir das letzte Mal gesprochen haben. Also eine Eigenschaft ID vom Typ String, Label vom Typ String und dann created at mit großem A.

  2. 3:20

    Und das ist in Form eines Date.js. Ich habe mich dazu entschieden, nicht ein natives JavaScript-Date zu verwenden, sondern ein Date.js. Das ist so ein kleiner Wrapper um Date herum und damit kann man noch so ein bisschen Formatierung anstellen und bessere Berechnungen und so weiter. Ist einfach ein bisschen kompakter und eleganter als dieses doch rechtsperrige Date-Format. Und als letztes haben wir noch completed at, auch hier wieder completed, klein, mit großem A und dann T, ohne Unterstrich oder sonst irgendwas. Und das ist dann ein Union-Type aus Day.js oder Null. Genau, wir nennen die meisten von diesen Eigenschaften eigentlich immer im Camel-Case, hast du gerade schon gesagt.

  3. 4:01

    Also alle Wörter hintereinander, erste Buchstaben immer groß, vorne klein geschrieben. Das ist eigentlich so unser Modus, wie wir das machen. Ich glaube, Konstanten werden dann anders dargestellt. Aber für diese Eigenschaften hier machen wir das so. Was mich noch interessiert, Kay, weil ich immer wieder verwirrt bin, was ist denn der Unterschied zwischen Interfaces und Types? Oder führt das hier zu weit? Nee, das können wir gerne nochmal ansprechen. Das sind in TypeScript, geht jetzt schon sehr in den Code rein, zwei Konzepte, die man im Großteil austauschen kann. Und die machen 99 Prozent das Gleiche.

  4. 4:35

    Konzeptionell haben wir da allerdings eine klare Unterscheidung und auch ein Konzept dafür, wann wir was einsetzen. Und die Idee ist, dass ein Type ein einzelner Wert ist, während ein Interface eine Kombination von unterschiedlichen Types sind, die eine gemeinsame Aussage greifen. Es gibt ja schon diese eingebauten Types, wie zum Beispiel String oder Day.js oder sonst irgendwas. Das sind einzelne Werte. Und die To-Do selber ist ein Interface, weil das eine Kombination aus verschiedenen Types sind. Und wenn ich jetzt was Neues anlege, ist eben die Frage, habe ich da eine Entität, die ich repräsentiere,

  5. 5:14

    oder eine Kombination von verschiedenen Eigenschaften? Dann ist es ein Interface. Habe ich nur einen einzelnen Wert? Und das kann auch mitunter mal ein bisschen was Komplizierteres sein, aber so konzeptionell, wenn es einen einzelnen Wert repräsentiert, dann ist es eher ein Type. Auch hier, wie vorhin bei der Wahl der Wörter für diese Entität, einfache Bezeichnungen verwenden, möglichst simpel bleiben, nicht irgendwelche Wortwiederholungen oder sowas. Das Suffix mit AT für Dates habe ich schon genannt. Man kann ansonsten auch so Präfixe mit IS oder HAS machen, um Booleans abzubilden, wobei das meistens eine schlechte Idee ist.

  6. 5:54

    Und grundsätzlich sollte man lieber bei diesen Entitäten darauf achten, dass immer alle Eigenschaften da sind. Und wie zum Beispiel im Fall von diesem Completed-Ad, dass da einen Wert realistischerweise keinen Sinn macht, dann lieber den mit Null auffüllen, statt verschiedene Entities zu bauen, die mal diese Eigenschaft Completed-Ad haben oder nicht. Da ist es deutlich einfacher, wenn das Objekt immer gleich aussieht, also immer dieselben Keys hat und dann die Werte vielleicht ein bisschen unterschiedlicher sind. Genau, das ist auch schon alles zu der Entität. Die ist ja relativ easy übertragen aus diesem Konzept,

  7. 6:31

    das wir uns schon überlegt haben. In der tatsächlichen Datei hier sind jetzt noch ein paar andere Sachen drin, die mit Validierung und sowas zu tun haben. Die würde ich jetzt einmal emotional überspringen und vielleicht später zurückkommen und ihr tut so, als würdet ihr gar nicht lesen. Im nächsten Schritt kommen wir jetzt nämlich zu dem ganzen spannenden Teil, nämlich den Verwalten dieser Entities. Wir haben jetzt erstmal ein Konzept erstellt und jetzt geht es wirklich hands-on, dass wir mit dieser Entität auch was machen. Und dafür gibt es einmal einen Store, in dem die Entities gespeichert werden.

CRUD Actions 7:00–38:20

  1. 7:05

    In unserem Fall ist das irgendeine Form von State, in dem wir also eine Liste der tatsächlichen Aufgaben in der Anwendung haben, plus verschiedene Funktionen, mit denen wir diesen Store manipulieren können. Und das ist hier alles gruppiert in der Actions.ts-Datei, auch in diesem Modul To-Do wieder drin. Das heißt, wir nennen es jetzt nicht irgendwie To-Do-Actions oder sowas, sondern nur Actions. Und darin haben wir ein paar große Blöcke, nämlich zum einen die ganzen Imports ignoriere ich mal, während die Datei mit mir durchgeht, aber den eigentlichen Store, wo eine Liste von To-Dos drin ist. Und das wird auch im Type genauso genannt.

  2. 7:45

    Wir beziehen uns also wieder auf dieses To-Do-Interface, das wir vorhin gemacht haben und machen daraus ein Array. Und zusätzlich gibt es noch ein paar Funktionen, die exportiert werden, die verschiedene Mutationen mit diesen To-Dos anstellen. Also Get, um die irgendwie zu bekommen. Ich habe in der letzten Folge über Locals Deutsch gesprochen. Create, Remove und Toggle Complete. Das heißt, um dieses Toggeln hin und her zu schalten. Die gehen wir jetzt mal einfach nach und nach durch und schauen uns an, was es da so für Besonderheiten gibt. Vielleicht noch ein paar Sätze zur Allgemeinheit. Wir haben das hier extra getrennt in einer komplett eigenen Datei,

  3. 8:25

    die jetzt auch nichts mit React zu tun hat, um eben diese MVC-Trennung zu haben. Wir haben dann vorhin eine Trennung gehabt, wo nur die Types sind. Jetzt haben wir nur die Actions oder das Controlling, wenn man so möchte. Und können dann nachher im View-Teil uns wirklich nur mit der Darstellung und dem UI beschäftigen. Sagen wir noch einmal zu den Actions hier. Ist das ein generischer Name, den du in allen Modulen so nennen würdest? Oder ist das jetzt speziell hier, weil das eben jetzt Aktionen sind, dass diese Datei hier so heißt? Genau, also ich habe mich bei der Benennung dieser Modifikatoren so ein bisschen an dem CRUD orientiert.

  4. 9:03

    Also CRUD ist ja so eine klassische Abflüssung für Create, Read, Update, Delete. Und das sind so die vier Basis-Operatoren, die man mit so einer Entity machen kann. Und dementsprechend habe ich mich auch hier bei der Benennung der Funktionen daran orientiert. Zum einen ein Get, was ein Äquivalent für dieses Read ist. Create, Remove, da kann ich das Delete nicht nutzen, weil das ein reserviertes Schlüsselwort ist. Und dann Toggle Complete, was so ein bisschen aus dem CRUD-Konzept ausbricht, aber eben eine ganz besondere, ja, also eine besondere Eigenschaft von diesem To-Do ist, dass man das eben so toggeln kann.

  5. 9:40

    Antwortet das deine Frage? Nee, also du würdest aber die Actions-TS dann tatsächlich in allen Modulen, diese CRUD-Funktionalität, CRUD hört sich so coole an, abbilden, würdest du dann tatsächlich auch Actions nennen. Ja, genau. Wir denken dran, wir sind eben innerhalb dieses To-Do-Moduls und das heißt, diese Actions-Datei ist sinnvollerweise nicht exposed. Also andere Module oder Bausteine dieser Anwendung sollten die eigentlich gar nicht benutzen. Und dementsprechend ist es eigentlich konzeptional egal, wenn es da fünfmal die gleiche Datei gibt, weil die eigentlich nicht miteinander verwendet werden sollten.

  6. 10:17

    Schauen wir uns zuerst einmal diesen To-Do-Store an. Das ist also eine Liste, in der wir speichern, welche Aufgaben es jetzt gerade zurzeit gibt. Und da sind wir jetzt natürlich schon sehr spezifisch beim Thema React und TypeScript und die Frage, wie setzt man das um? Und da gibt es auch ganz verschiedene Strategien. Klassisch, wenn man von React kommt, würde man dafür einen React-State verwenden und dann über so ein Set-State und Getter diese Liste verwalten. Die hat allerdings das große Problem, und deswegen habe ich es jetzt hier nicht benutzt, dass das von der ganzen Syntax und vom ganzen UI her schon sehr eng an React gekoppelt ist.

  7. 11:01

    Da muss man dann so ein bisschen Tricks machen, wie dass man einen Custom-Hook macht oder sowas, dass man die Funktionalität ein bisschen auslagert. Weil dadurch, dass man diese Hooks nur verwenden kann, wenn man in einer React-Komponente drin ist und eine React-Komponente sich wiederum dadurch auszeichnet, dass sie HTML zurückgibt, sage ich mal, hat man immer diese enge Verschmelzung zwischen diesem Controlling und dem UI und kann das nicht so schön trennen. Während, so wie wir es hier gemacht haben, in einer separaten Datei mit einer separaten Technologie, gehe ich gleich nochmal drauf ein, haben wir das wirklich schön getrennt

  8. 11:35

    und können uns nur auf technischer Ebene, auch wenn es nachher um die Tests geht, nur mit JavaScript beschäftigen, nur mit TypeScript und haben React erstmal komplett außen vor. Wir benutzen dann tatsächlich als State-Konzept die angesprochenen Signals. Das ist konzeptionell, also technisch ist das etwas, was wir uns jetzt von Preact geborgt haben. Das gibt es aber auch in anderen Tech-Stacks. Das ist im Prinzip eine Variable, auf die React reagieren kann, so wie es das auf ein State machen könnte. Wir benutzen dann hierfür also dieses Signals von React. Das sieht man oben schon anhand des Imports.

  9. 12:16

    Das ist eben dieser Adapter, von dem wir letztes Mal gesprochen haben, dass wir also nicht direkt irgendwelche Preact-Sachen verwenden, sondern da so einen kleinen Adapter, den die selber anbieten. Und die eigentliche Syntax ist dann relativ einfach. Wir haben nämlich einfach eine Funktion, die heißt Signal und die initialisieren wir erstmal mit Null. Und der Type dazu kann aber eine Liste von To-Dos sein oder Null. Und dieses Vorgehen hat man ganz häufig tatsächlich, auch wenn man einen React-State verwenden würde, dass der State-Typ entweder das ist, was da tatsächlich drin gespeichert werden soll,

  10. 12:54

    in unserem Fall zum Beispiel eine Liste von To-Dos, oder aber wir ja auch noch das Szenario abbilden müssen, dass vielleicht gar keine To-Dos geladen wurden aus irgendeinem Grund, weil die dynamisch irgendwo herkommen. Dann bietet es sich immer an, auch zusätzlich nochmal diesen Null-Type zu verwenden, um eben zu sagen, hier wird irgendwann mal diese To-Do-Liste drin sein, aber im Moment ist noch nichts und im Hintergrund gibt es gerade hoffentlich irgendeine Operation, die sich darum kümmert, die zu beschaffen. Und das ist ja immer ein anderer Status, als würde man das zum Beispiel jetzt mit einem leeren Array hier initialisieren,

  11. 13:28

    weil das das Gleiche sein könnte, wie es sind keine Einträge in der Liste. Ganz genau. Und so hat man nochmal diese Unterscheidung zwischen, es ist nicht leer, weil da noch niemand was eingetragen hat, sondern es ist noch leer, weil wir irgendeine Ladeabhängigkeit haben oder sowas. Diese To-Do-Variable, die daraus entsteht, ist auch das, was wir als Default-Export aus dieser Datei anbieten, um zu sagen, schau mal, das ist das Allerwichtigste, was es hier gibt, nämlich die Liste dieser Entities, die ja konzeptionell die Grundlage von allem sind, was wir da drum herum bauen. Vielleicht, um die Zeile darunter zu erklären,

  12. 14:04

    in der Realität haben wir natürlich die To-Dos dann auch irgendwie sortiert nach dem Datum, in dem sie erstellt wurden. Und da gibt es hier diese zusätzliche Variable To-Do-Sorted, habe ich sie genannt, in der die To-Dos aus dem State, den wir vorher genannt haben, sortiert werden nach diesem Created-Ad-Feld. Das ist so eine abgeleitete Geschichte, das ist auch jetzt wieder ein bisschen Pre-Act- und Signal-Geschichte, dass das automatisch neu berechnet wird, wenn sich das Original-Array ändert. Hier vielleicht auch ganz spannend, das ist eine Abwandlung von den To-Dos, die wir vorher genannt haben,

  13. 14:41

    und dementsprechend ist auch die Benennung der Variable eine Ableitung davon. Deswegen habe ich sie jetzt To-Do-Sorted genannt, damit klar ist, okay, das bezieht sich auf dieses originale To-Dos-Array, diese Liste, die wir da haben, aber ist irgendwie davon abgewandelt. Bei diesem Stichwort Computed, da klingelt ganz doll meine Vue.js-Vergangenheit. Also ich weiß gar nicht, ob es für das gleiche Konzept, aber immerhin gibt es da sowas. Genau. Ein bisschen weiter unten, ich überspringe jetzt mal diesen ganzen Get-Block, da gehe ich nachher drauf ein, haben wir dann eben einen Effekt. Das ist auch so eine Funktion,

  14. 15:16

    die eben diese Signals anbietet, und das funktioniert ähnlich wie dieses Use-Effekt, wie man es von React kennt. Nämlich das heißt einfach, hör mal, hier ist so ein Seiteneffekt, und der wird in diesem Fall getriggert, das erste Mal, wenn diese Datei geladen wird. Und in der checken wir zuerst so ein paar Abhängigkeiten, wie zum Beispiel haben wir schon mal To-Dos geladen. Dafür ist hier dieser Null-Check. Und wenn, dann holen wir die aus dem Local Storage. Auf diese ganze Local Storage-Funktionalität gehe ich nachher noch ein. Nur das ist eben dieser erste Schritt, der passiert, wenn diese Datei initial einmal geladen wurde.

  15. 15:49

    Dann ist diese To-Dos-Liste, hat noch den Type Null. Und dieser Effekt sorgt dann dafür, dass im zweiten Schritt da die Sachen reingeladen werden. Und es ist auch tatsächlich, eine gute Idee, das so aufzuteilen und nicht zu sagen, okay, wir sorgen dafür, dass der initiale Wert der To-Dos-Liste schon immer das aus dem Store ist. Weil dann müsste nämlich alles andere warten, bis dieser Request, der es ja wahrscheinlich üblicherweise ist, oder diese Aktion, die das von irgendwo herholt, fertig ist. Und das blockiert dann einfach sehr lange das UI. Wenn man das so auslagert, wie ich das jetzt hier gemacht habe,

  16. 16:28

    kann das UI schon mal einmal durchrendern und einmal alles schon mal vorbereiten. Dann halt mit diesem Null-Loading-State. Währenddessen kann im Hintergrund hier in diesem Fall dieser Effekt werkeln und einen beliebig umfangreichen Request machen. Und irgendwann nach ein oder zwei Sekunden, je nachdem, wie auch die Internetverbindung ist, bekommt man dann die Daten rein und das UI updatet sich. Man kann hier in allen Funktionen auch ganz schön sehen, dass du immer einen Early Return verwendet hast. Auch so ein Konzept, was wir gerne verwenden, dass wir möglichst früh aus den Funktionen aussteigen,

  17. 17:01

    wenn irgendwelche Parameter nicht passen. Genau, das ist natürlich das eine. Da können wir gleich mal drauf angehen, in Form von diesem Effekt. Also in der Logik, zuerst prüfe ich tatsächlich, ist Local Storage verfügbar? Das kann man einfach checken, indem man schaut, ob die globale Variable Local Storage, ob die ein Objekt ist oder eben nicht. Wenn es das nicht gibt im Browser, dann ist das kein Objekt. Und gleichzeitig checke ich, ob die To-Dos noch Null sind. Und wenn eins von beidem nicht der Fall ist, dann gehe ich hier mit einem Early Return raus, weil das heißt entweder, dass Local Storage nicht verfügbar ist,

  18. 17:36

    dementsprechend kann ich da auch nichts laden, oder dass die To-Dos schon geladen wurden. Early Escape ist das eine, was ich hier benutze. Das heißt wirklich, ich mache meine Funktion alles auf der Grundlinie der Funktion. Soll heißen, ich verschachtel das nicht, wer weiß, wie in irgendwelchen If-Statements, die dann so riesige Blöcke haben, sondern ich versuche, meine If-Statements möglichst kompakt zu halten und so auf einer Linie hintereinander zu ketten, sodass ich am Happy Path unten dann nur noch im Glücksfall bin und alle etwaigen Probleme vorher rausgehoben habe. Plus, das Zweite, was ich mache,

  19. 18:14

    ist, dass ich explizit auf das teste, was ich jetzt gerade möchte. Beispiel, wenn ich schauen möchte, ob diese To-Do-Variable, die wir vorher angelegt haben, Null oder schon eine Liste enthält, dann checke ich das wirklich explizit auf ist gleich Null und nicht sowas wie Ausrufezeichen, wo ich dann so Fall-Sie-Werte abbilde. Und das hat zwei Gründe. Zum einen tut es genau das, was ich will und ich weiß genau, auch durch die Typisierung von To-Do, mit was für Typen ich es zu tun habe und welche ich jetzt explizit ausschließe. Plus das Zweite ist, es steht eben genau da, was passiert, während bei so ein bisschen

  20. 18:56

    der allgemeingültigeren Statements, wie zum Beispiel diesem Ausrufezeichen vor einer Variable, der einfach nur auf irgendeinen Fall-Sie-Wert checkt, muss ich halt die ganze Zeit noch zusätzlich im Kopf behalten, okay, was sind denn hier jetzt für Szenarien, die vielleicht abgehandelt werden können? Null ist klar, aber was zum Beispiel, ist ein leeres Array auch Fall-Sie oder sowas? Das ist halt dann in solchen Statements nicht eindeutig ersichtlich und ich muss wieder mehr kognitive Kapazität aufwenden, um die Zeile zu lesen, während wenn ich einfach hinschreibe if to-dos gleich null, dann return,

  21. 19:30

    ist sofort für alle klar, was da passiert. Das Gleiche gilt auch für den Local Storage. Ich will auf das prüfen, was ich will und nicht gegen das prüfen, was ich nicht will. Also in diesem Fall ist es wichtig, dass Local Storage ein Objekt ist und deswegen, um damit zu interagieren weiter unten, und deswegen prüfe ich, ob der Type of Local Storage kein Objekt ist, weil ich brauche nachher das Objekt, damit es funktioniert. Statt dass ich hier sowas sage wie if Local Storage gleich undefined, dann habe ich ja nur auf das gecheckt, was ich nicht will, statt auf das, was ich will. Bisschen vielleicht abstrakt erklärt,

  22. 20:07

    aber das führt eben beides dazu, dass man zwar relativ lange Statements hat, also man könnte es auch mit weniger Zeichen schreiben, aber dafür ist direkt klar, was da passiert und was hier die Ausscheidungskriterien sind. Springen wir mal vielleicht weiter zu der Create-Funktion. Die ist nämlich auch aus mehreren Gründen relativ spannend und gleichzeitig kompakt. Es geht jetzt also darum, dass wir eine API anbieten wollen, mit der irgendwelche Teile innerhalb dieses To-Do-Moduls neue To-Dos anlegen können. Und dann ist die Frage, was ist denn die minimalst nötigen Informationen, die wir dafür brauchen.

  23. 20:56

    Und auch hier immer die Entscheidung, wenn ich dieses Modul oder diese Unit Create entwerfe, möchte ich so wenig wie möglich an Unwägbarkeiten aus der Hand geben. Wir haben vorhin uns überlegt, wie diese To-Do-Entity aussieht, nämlich diese vier Eigenschaften. Und wenn wir jetzt ein neues To-Do createn wollen, brauchen wir logischerweise diese vier Eigenschaften, die diesem Interface entsprechen. Aber aus der Sicht dieser Create-Unit sind das wirklich alles diese vier Eigenschaften, die ich jetzt beim Anlegen von irgendjemandem bekommen muss? Oder kann ich mir vielleicht Sachen selber zusammen reimen?

  24. 21:39

    Um, wie gesagt, möglichst die Fehlerquote auch gering zu halten. Und wofür ich mich dann hier jetzt nämlich entschieden habe, ist das eigentlich von diesen vier Eigenschaften, die diese To-Do-Entität ausmacht, ich nur eine einzige als Parameter haben möchte, nämlich den To-Do-Label. Während die ID kann ich innerhalb der Funktion selber erzeugen durch eine UUID. Die brauche ich also nicht übergeben bekommen und dafür kann ich auch wirklich sicherstellen, dass die ID eine UUID ist. Genauso wie dieses Created-Ad. Das ist ja immer der aktuelle Zeitpunkt, zu dem das erstellt wird. Und die kann ich auch

  25. 22:19

    innerhalb der Create-Action selber setzen und brauche die nicht als Parameter, weil da kann nur mehr schief gehen, als es nützt. Genauso wie dieses Completed-Ad. Wenn man eine neue To-Do erstellt, ist die üblicherweise noch nicht erledigt und deswegen erlaube ich gar nicht erst, dieses Completed-Ad-Feld irgendwie zu manipulieren, sondern ich setze es direkt auf Null. Und so brauche ich eigentlich zum Anlegen einer To-Do-Entität bloß einen Parameter, der den Label beinhaltet und kann daraus das ganze andere zusammenbauen. Vielleicht noch mal grundsätzlich einen Schritt zurück. Wie schreiben wir jetzt

  26. 23:00

    diese Funktion? Da haben wir auch ein bisschen Besonderheit, nämlich alle Funktionen, die wir schreiben, sind bei uns Arrow-Functions. Das hat den Grund, dass wir diese Type-Aufstellung zwischen Signatur-Definition und Implementierung haben. Da haben wir auch schon eine Folge drauf gemacht, deswegen reiße ich es hier nochmal kurz ein. Es gibt ja bei Arrow-Functions dieses magische Gleichheitszeichen, dass die Barrikade ist zwischen auf der linken Seite dem Variablen-Namen und auf der rechten Seite der Implementierung der Arrow-Functions. Und wir haben tatsächlich eine Linting-Rule über ESLint,

  27. 23:38

    die sagt, dass vor dem Gleichheitszeichen die komplette Typisierung erfolgen muss. Und das führt jetzt dazu, dass wir hier also in der Syntax eine Variable haben, die habe ich const create genannt und dahinter ist direkt die Typisierung von der Arrow-Functions, die folgen wird, nämlich eine Funktion mit einem Parameter to do create, da gehe ich gleich drauf ein und der Rückgabewert ist eine vollständige to do und erst dann kommt das Gleichheitszeichen und danach die Implementierung. Und mit dieser Arrow-Functions gegenüber von so einer Named-Function oder so anderen Syntaxen, die man verwenden kann,

  28. 24:18

    erlaubt uns eben diese Zuweisung von einer Funktion zu einer Variable und dadurch diese Typisierungsregel, die uns sehr wichtig ist, sodass man direkt auf einen Schlag die Signatur der Funktion sieht. Und mit Signatur meine ich Name, Parameter, Rückgabewert. Du hast hier die ESLint-Regeln, die wir allgemein in unseren Projekten verwenden, angewandt. Ich weiß, dass wir später noch einen Punkt dazu haben, aber die sind in der Anwendung drin und wahrscheinlich auch public, sodass man sich die angucken könnte. Genau, wir haben dafür ein eigenes Preset, weil wir das ja tatsächlich in all unseren Projekten

  29. 24:52

    verwenden. Da haben wir ein Preset gemacht, das man bei MPM einsetzen kann und das stellt eben so Sachen sicher, wie zum Beispiel diese Typ-Zuordnung. Jetzt habe ich vorhin gesagt, eigentlich brauche ich zum Anlegen nur den eigentlichen Aufgabentext, den wir dann nachher auch in diesem Input abfragen und die Frage ist, wie will ich jetzt diesen Parameter entgegennehmen? Das Einfachste wäre natürlich zu sagen, okay, ich mache einfach einen Parameter, den nenne ich, weiß ich nicht, Text und das ist ein String oder sowas. Was ich jetzt aber überlegt habe, ist, dass ich eine Abwandlung von dem tatsächlichen

  30. 25:31

    To-Do-Interface mache. Das Spannende bei diesen Interfaces ist eben, wenn man durch die Anwendung hindurch verfolgen kann, wo alles damit gearbeitet wird. Und wenn ich jetzt hier einfach nur einen Parameter mit dem Namen Label vom Type String nehmen würde, hätte ich gar keine Referenz zu dem To-Do-Interface, was wir ja gerade so mühsam gebaut haben. Trotzdem beschäftigt es sich ja mit diesem To-Do-Interface und hat darauf Auswirkungen. Und wenn ich dann rückwirkend bei dem To-Do-Interface schauen möchte, wo das alles eingesetzt wird, möchte ich ja auch irgendwie diese Funktion hier sehen, weil die

  31. 26:09

    damit zu tun hat. Eine Möglichkeit wäre dann zu sagen, man macht statt Label und Type String bezieht man sich statt String auf den Wert von dem von dem von der Eigenschaft Label aus dem Interface, jetzt ein bisschen schwer zu erklären, aber man kann auch nur bestimmte Aspekte eines Interfaces referenzieren und so eine Verbindung herstellen. Was ich aber stattdessen gemacht habe, ist ein Schema zu entwerfen, um das To-Do zu erstellen. Also ein Subset, ein abgleitetes Objekt von dem To-Do Interface, das die Dinge enthält, die ich brauche, um das anzulegen. Das referenziert wieder ein bisschen die

  32. 26:58

    Validierungsgeschichte, dafür benutze ich nämlich JUP, um da so ein tatsächliches Schema heraus zu erstellen, aber da reden wir nachher noch mal drauf, wenn wir tatsächlich uns das Formular anschauen und wie da die Zusammenhänge sind. Wichtig ist jetzt erstmal nur versuchen, die Interfaces zu verwenden, mit denen man noch arbeitet und wo wir hier jetzt gerade eine Abwandlung von dem To-Do brauchen, um ein To-Do zu erstellen, möchte ich auch idealerweise dafür einen Typ wählen, der dazu passt. Der Rest der Funktion ist dann relativ einfach. Ich erstelle ein neues Objekt vom Typ To-Do wo ich eben

  33. 27:36

    die ID selber anhand von einer UUID setze. Da gibt es so ein kleines Package. Den Label habe ich ja als Parameter bekommen. Created add setze ich mit day.js zum kleinen Helfer auf die aktuelle Zeit und das completed add setze ich auf null. Das Ganze wird dann an die Liste der aktuell verfügbaren To-Dos drangesetzt. Wir haben diese Variable vorher erstellt und dann return ich trotzdem nochmal das To-Do das ich gerade angehangen habe. Einfach so ein bisschen als nette Gehste sag ich mal damit ich da auch sehr gut mit testen kann und solche Dinge. Bei der Remove Funktion die da als nächstes kommt

  34. 28:17

    konzeptionell das ähnliche kann man aber vielleicht noch sehen wie ich das mit dieser Eigenschaft Verlinkung meine da ist nämlich die Remove Funktion die ID entgegen nimmt und diese ID wird dann eben benutzt um die To-Do aus der Liste der To-Dos zu entfernen und hier nehme ich bei der Typisierung eben nicht ein String als die ID sondern referenziere das Feld ID auf dem To-Do Interface und so habe ich auch wieder sichergestellt dass überall wo ich dieses Interface verwende mir eben diese Funktion auch unterkommt jetzt mixt du hier die beiden Arten also oben machst du quasi ein Schema davon also

  35. 29:01

    nimmst nur eine Eigenschaft aus dem eigentlichen Interface raus und unten referenzierst jetzt so auf die ID von der To-Do ist das jetzt hier zum Showcasen oder würde man das tatsächlich mixen und zweite Frage direkt im Anschluss warum returnst du hier nicht die To-Dos Es sind zwei unterschiedliche Dinge bei dem create aus der vorherigen Funktion habe ich deswegen ein eigenes Schema und ein eigenes Objekt drauf gebaut weil ich das nachher auch wieder total easy verwenden kann weil ich das aus dem Formular rausbekomme wir haben ja nachher irgendeine Form von Formular wir haben es im Wireframe schon

  36. 29:35

    mal besprochen da ist irgendeine Art von Input Feld wo ich den Text des To-Dos eintragen kann und dann drücke ich auf Speichern und wenn man ein bisschen Erfahrung mit HTML hat dann kann man sich schon vorstellen dass da irgendeine Art von Form ist in dem es einen Input vom Typ Label gibt

  37. 30:00

    Form heraus ein Objekt mit eben einer Eigenschaft Label und dem Text den ich da eingetragen habe und so überträgt sich ganz elegant das was ich eh schon haben möchte auf das wie es eingetragen wird und muss nicht noch zwischendurch das irgendwie umschreiben plus ich

  38. 30:30

    kleinseitige Inline Validierung zu machen das hört sich einleuchtend unsinnvoll an und der return was ich noch genau zu diesem remove sagen wollte da man könnte auch sagen statt dass ich nur die ID für das remove brauche könnte ich auch das komplette to do Objekt nehmen und damit Dinge anstellen das bricht allerdings so ein bisschen die Regel der Single source of truth nämlich dass sich eine Information möglichst nur an einer Stelle zentral verwalten möchte und überall wo ich die benutze greife ich auf diese eine Information zu und verwende die wieder statt dass ich die Information klone und an

  39. 31:12

    allen möglichen Stellen verwende und wenn ich jetzt hier dieses to do was ich entfernen möchte direkt als vollständigen Parameter bekomme habe ich

  40. 31:29

    habe auf einmal zwei Quellen für dieselbe Information und dann können so ganz spannende Späße passieren wie was passiert wenn sich das in der Zwischenzeit ändert oder solche Dinge und durch diese ID nur die ID als Parameter stelle ich also sicher okay ich bekomme nur die ID die gelöscht werden soll und dann das tatsächliche modifizieren mache ich dann wieder auf dem realen Datensatz aus meiner Quelle da hat sich tatsächlich die Theorie auch so ein bisschen bei uns geändert früher haben wir eher die ganzen Objekte übergeben und hätten dann die Funktion vielleicht auch remove to do genannt und der

  41. 32:04

    wäre dann schon implizit drin dass ich auch ein to do übergeben muss und genauso bei create to do wobei da würden wir eher die ganzen Objekte übergeben und dann der Funktion gesagt du bist

  42. 32:23

    das ist dann der Funktion überlassen ja das also das ist jetzt auch alles nicht ein Stein gemeißelt das ist jetzt eben der Gold Standard aktuell aber wer weiß wie es in einem Jahr aussieht es hängt auch immer so ein bisschen davon an wie konkret man jetzt die Anwendung gebaut hat und wie da die Zusammenhänge sind und üblicherweise hat man immer wenn man über these to do's redet eine konkrete Instanz und nicht nur eine einzelne ID dann kann es sich schon anbieten auch das immer als Parameter zu wählen aber richtig sauber wäre es eigentlich zu sagen ich entferne ein to do aus der Liste anhand der

  43. 33:00

    ID weil das ja auch mein primary key ist und was da sonst noch dran hängt ist mir eigentlich an der Stelle auch egal in dieser remove Liste ist ganze Zeit ja das Problem haben dass wir mit dieser originalen to do variable arbeiten und wir erinnern uns ihr habt sicherlich total aufgepasst und erinnert euch die kann ja auch null sein nun ist es rein auf TypeScript Ebene möglich dass diese remove Funktion aufgerufen wird mit irgendeiner ID obwohl diese initiale Liste noch null ist und dementsprechend könnte ich gar nicht in dieser Liste nach irgendeiner ID suchen das heißt TypeScript fällt mir hier

  44. 33:51

    an der Stelle schon auf die Füße wenn ich sage ich möchte diese To-Do Liste durchsuchen und was ich dann häufig sehe ist dass die Leute hier einfach einen Check rein machen und sagen To-Do Liste gleich null dann mache ich einfach ein Return weil das ist ja Quatsch dass das aufgeführt wird und wir als Entwickler wissen natürlich auch so wie diese Funktion verwendet wird dass die niemals aufgerufen wird wenn diese originale Liste noch nicht geladen ist weil wir natürlich anhand anhand der Liste wenn die da ist erst das Element anzeigen und mit dem Element erst den löschen Button und so setzt das

  45. 34:27

    alles zusammen aber nur auf TypeScript Ebene ist das eben möglich und was mir dann wichtig ist an dieser Stelle nicht einfach so still zu sagen jo dann mache ich mal TypeScript zufrieden und sage hier if to do gleich null dann return sondern zu sagen halt warte mal was passiert denn wenn das doch ist das ist doch eindeutig auf jeden Fall ein Fehler und wenn ich hier einfach nur return rein mache dann wird er so ganz klamm und heimlich verschluckt aber ich weiß ja dass das eigentlich niemals auftreten soll und deswegen wäre meine Maßgabe und auch das was ich hier gemacht habe für dieses Szenario

  46. 35:07

    eben einen richtigen echten Error zu werfen und zu sagen so mir ist völlig egal wie die restliche Anwendung aufgebaut ist ich denke hier jetzt nur an meine Remove Unit und aus Sicht dieser einen Remove Unit unabhängig davon was drumherum passiert könnte theoretisch die To-Dos Liste null sein und deswegen werfe ich hier einen Error und sage hey die Liste ist leer so geht das nicht das hilft dann nachher ungemein wenn man über Error Handling und so weiter spricht da können wir dann in späteren Kapitel noch zu und können sagen okay das sind wirklich harte Fehlerfälle wo die Anwendung auf den Mund

  47. 35:48

    fällt die Toggle Complete Funktion wie ich sie genannt habe ist dann ganz ähnlich die sucht einfach nur in der Liste der To-Dos nach einem mit der gleichen ID und setzt das Completed add Feld auf entweder null wenn es schon ein Wert ist oder wenn es kein Wert ist dann setzt es das auf das aktuelle Datum und ich habe mich jetzt auch bewusst dazu entschieden eben diese Toggle Funktionalität hier separat abzubilden der richtige Crude Weg wäre ja irgendwie eine Update Funktion zu machen mit dem ich das manipulieren kann aber hier gebe ich die Business Logik vor und sage nee du kannst eben nicht update

  48. 36:30

    mäßig alle Felder beliebig manipulieren wie du möchtest und zum Beispiel auch den Aufgabentext nicht ändern sondern ich gebe dir ganz spezifisch vor wie du mit dieser Entität interagieren kannst was mir Interaktionsmöglichkeiten außer lesen hier versammel damit ich die volle Kontrolle habe wo wie mit dieser Entität interagiert werden kann du hast jetzt trotzdem noch verheimlicht warum du nicht return bei den removes ach so genau ich returne kein remove weil ich ja anders als beim create nichts erschaffe sondern was lösche und das remove ist ja darauf geeicht einen einzelnen Eintrag zu löschen und

  49. 37:18

    dann die neue Liste zurückzugeben erscheint mir nicht so richtig sinnvoll weil die ja schon im globalen state dann ist die neue Liste und ich es nicht so richtig stimmig fand zu sagen das to do was ich gelöscht habe kann ich dir nicht zurückgeben weil das habe ich gerade gelöscht und die daraus resultierende Liste wäre auch dann wieder doppelte Informationen ok ich nehme es mal so hin ich habe jetzt die get funktion ein bisschen ausgelassen weil mir wichtig war hier so ein paar grundlegende konzepte zu erklären zum Beispiel mutable style bin ich jetzt ein bisschen drüber hinweg gegangen aber wir

  50. 37:54

    verändern keine bestehenden werte sondern machen neue das heißt bei einem filter und bei diesen map dateien und so weiter das bietet javascript ja von haus schon an da wird nicht eine bestehende liste mutiert sondern immer neue erstellt und die schreiben wir dann in den state rein statt den state direkt zu modifizieren oder sowas ich glaube wir haben auch schon mal eine Folge zu gemacht aber das wird den Rahmen noch mehr springen als er das eh schon tut wir sind ja schon wieder soweit ich würde deswegen noch mal ganz kurz auf dieses create zurückkehren weil wir an der Stelle nämlich noch mal auf

Validierung 38:20–47:28

  1. 38:30

    die validierung eingehen können die wir hier an zwei stellen im code haben und das ist ein sehr spannendes konzept generell deswegen würde ich sie gerne nochmal aufnehmen wir haben ja unsere Anwendung mit TypeScript geschrieben das heißt wir haben unsere Entität in TypeScript gebaut und die überall wieder verwendet wo sie eingesetzt wird und zusätzlich haben wir jede einzelne Variable typisiert auch wenn sie eine Funktion enthält dann haben sie eine aufregende Typisierung und das führt dazu dass wenn ich innerhalb von diesem Kosmos unterwegs bin und irgendeinen Quatsch mache dass mir TypeScript

  2. 39:06

    dafür aufs Dach steigt das heißt wenn ich eine Variable die ID zum Beispiel von dem To-Do als String bezeichne und dann da eine Nummer reinschreiben möchte dann fliegt TypeScript in die Luft und ich kann es gar nicht erst bauen und so habe ich innerhalb der Anwendung eben sichergestellt dass alle Zahnräder ideal miteinander funktionieren weil ich nur die Parameter übergeben kann die dem richtigen Typ entsprechen und nur die Variablen austauschen kann die dem gleichen Typ entsprechen und habe so eine sehr robuste Anwendung weil mir eben schon direkt während ich programmiere auffällt wenn irgendwas

  3. 39:43

    parents kaputt geht und das gilt allerdings leider nur für die Sachen die auch wirklich als Teil der Anwendung setze zum Beispiel bei dieser id die setze ich ja aktiv im Code indem ich da irgendwo ein Objekt mache beim erstellen von so einem To-Do zum Beispiel sage ich hier id ist gleich und dann setze ich die id selber über diese uuid helfer Funktion und das habe ich explizit im Code gesetzt und das heißt da greift diese fancy TypeScript Mechanik und stellt sicher dass ich da wirklich keinen Quatsch reinschreibe nun gibt es allerdings leider einen Haufen Stellen wo nicht zur Bildzeit sondern zur

  4. 40:26

    Laufzeit Informationen in unsere Anwendung reinkommen auf verschiedene Arten und Weisen und bei denen müssen wir sicherstellen dass die auch dem entsprechen was wir erwarten damit sobald das in unserer Anwendung drin ist sie wieder übereinstimmen sonst sage ich vielleicht hier die ID von dem To-Do ist vom Typ String aber zur Laufzeit kommt dann da irgendwie eine Number rein und dadurch dass zur Laufzeit das ganze TypeScript rausgerechnet wird weil der Browser damit nichts anfangen kann ist die Variable dann wieder untypisiert und wenn ich die als Parameter reintue und dann mit irgendwelche Sachen

  5. 41:03

    machen die ich nur auf Strings machen dass immer wenn Informationen in unsere Anwendung zur Laufzeit reinkommen dass wir die direkt als allererstes validieren um sicherzustellen dass sie dem entsprechen was wir erwarten und das gilt zum einen für alles was die Nutzer so in Formularen eingeben das ist eine der gängigsten Varianten oder aber auch für API Requests wo wir irgendwelche Daten zur Laufzeit von irgendwo abrufen und uns vorher während der Entwicklung total vergewissert haben dass das so ist wie wir es uns vorstellen aber wir nie garantieren können dass sich das irgendwann mal ändert was

  6. 41:53

    wir deswegen inzwischen machen ist immer an diesen Schnittstellen wo Information in unser System reinkommt da validieren wir die und dafür benutzen wir in TypeScript diese JUP Package heißt das ganz witziger Name dieses JUP Package erlaubt es uns ein Schema zu definieren also wir definieren wie ein Objekt aussieht und zwar nicht nur welche Eigenschaften es hat sondern auch wie diese Eigenschaften aussehen und was es Anforderungen gibt sage ich gleich nochmal konkreter und wenn wir ein neues Objekt bekommen dann schicken wir es einmal durch diese JUP Validierung und wenn es dem Schema nicht entspricht

  7. 42:34

    dann wirft es an der Stelle schon direkt ein Error bevor unsere Anwendung damit irgendwie weiter arbeiten konnte ich habe vorhin gesagt dass dieses Schema auch das ist was ich bei diesem Create verwende dafür springen wir jetzt da ist nämlich relativ weit unten ist eben ein JUP Schema für unser To-Do Interface und wir sagen ihm quasi anhand dieses To-Do Interface auch wie das Schema grundsätzlich aussehen soll das ist jetzt hier typisiert durch dieses Object Schema vom Type To-Do und dahinter definieren wir ein Objekt das zufällig dem entspricht wie das Interface aussieht nämlich können wir da zum

  8. 43:21

    Beispiel sagen hier dieses Objekt das hat ein Feld ID und das soll wiederum ein String sein und ist jetzt required und eine UUID so können wir sicherstellen dass wenn wir dieses JUP Schema anwenden und es durchläuft dass dieses ID Feld genau den Anforderungen entspricht die wir genannt haben oder zum Beispiel beim Thema Label was der Nutzer einfügt da ist es 3 Zeichen haben weniger macht so ein Aufgabentext keinen Sinn und maximal 30 Zeichen weil es soll noch nicht zu lang werden so kann man eben ganz genau nicht nur auf Typ Ebene sondern auch auf inhaltlicher Ebene checken ob die Werte die man

  9. 44:05

    da bekommt dem entsprechen und von diesem allgemeinen To-Do Schema wo ich das komplette Interface nochmal abbilde habe ich eben dieses To-Do Schema create abgeleitet was im Prinzip von diesem generellen To-Do Schema nur die Eigenschaft Label rauspickt das heißt ich habe dann ein separates abgeleitetes Objekt wo nur die Spezifikation vom Label drin ist und das benutze ich zum einen im Formular wo tatsächlich was eingetragen wird da gibt es so eine schöne Interaktion zwischen Formic und Jup dass man dem Formic so ein Schema übergibt das kann man uns gleich mal anschauen und habe direkt sichergestellt

  10. 44:48

    okay egal was der Nutzer da einträgt es muss im Rahmen von diesem allgemeinen To-Do Schema sein was ich da definiert habe wir können vielleicht mal in die Create Komponente reinspringen also jetzt wirklich die Create View die finden wir auch in diesem To-Do Modul unter Create das ist so eine klassische React Komponente und dort sieht man oben zum einen wieder die Typisierung dass wir also eine Variable haben die heißt Create für diese Komponente weil es React ist wird sie groß geschrieben der Typ ist dieses FC von React Functional Component und erst dahinter kommt mit dem gleiche Zeichen wieder

  11. 45:30

    die Arrow Function die unsere komplette Komponente enthält und in dem Return Statement kann man jetzt sehen dass wir eben diesen Formic Helper benutzen mit einem initialen Value für dieses Label weil es der einzige Input ist den wir brauchen und eben dieses Validation Schema wo ich jetzt dieses abgeleitete Schema Create einsetzen kann und das stellt mir dann sicher das macht dieses ganze Form Handling für mich weiter unten sieht man dass ich einfach nur ein Field habe was ein Text Feld repräsentiert mit dem gleichen Namen und ein Submit Button und dieser Formic Helper nimmt mir diese ganze Form

  12. 46:11

    Interaktion ab die wir da eigentlich haben also ich brauche keine States mehr für die Inputs das macht Formic alles für mich das ganze Submitten macht Formic für mich ich muss ihm nur noch definieren was ich damit mache und vor allem dieses ganze Error Handling macht er für mich und diese schöne Kombination jetzt aus Formic und diesem Schema ist dass wenn ich in diesem Labelfield als User im Formular irgendwas reinschreibe was diesem Schema nicht entspricht dann macht Formic für mich ganz automatisch vorab eine Validierung stellt fest dass das Feld nicht passt und macht automatisch eine Fehlermeldung

  13. 46:49

    die dann auch zu diesem Input angezeigt wird und wo dann steht hey schau mal hier das Labelfeld muss mehr als drei Zeichen haben oder sowas das ist alles Aufwand den ich ansonsten mühsam manuell programmieren müsste und dass dieser Kombination von Formic und diesem Juck Schema kann ich also wirklich sicher sein auf sehr wenig Code dass was immer aus dem Formular an mich als Programm rauspurzelt dass das so kann ich quasi das Ergebnis dieses Forms direkt an meine Create Funktion übergeben und kann sicher sein dass das auch wirklich alles übereinander passt das waren jetzt schon wieder 50 Minuten

Überleitung zum dritten Teil 47:28–50:16

  1. 47:31

    genialer Input Kay du musst mir mal sagen ob wir hier einen guten Schnitt machen können oder würdest du gerne noch ein Kapitel mit reinnehmen ich gehe jetzt gerade mal hier meine Kapitel inho durch ich habe jetzt eigentlich nur das zusammen was ich schon genannt habe nämlich Error Handling habe ich da diesen JUP Schema was ich vorhin erzählt habe benutze ich da nämlich eben auch um die Sachen die ich aus dem Local Storage lade zur Laufzeit zu validieren bevor ich sie in die Anwendung packe um sicherzustellen dass auch die Sachen im Local Storage so sind wie ich sie gerne hätte da kommt

  2. 48:20

    Folge generell über das Thema Error Handling sprechen ansonsten ja Felix musst du mir sagen ob das halbwegs verständlich war bis hierhin also ich kannte davon natürlich jetzt einiges schon und trotzdem waren auch wieder spannende Dinge und Konzepte dabei wo ich auch was gelernt habe also es war so ein bisschen meine persönliche Masterclass jetzt hier auch an der Stelle schon mal vielen Dank ich habe den Code jetzt tatsächlich mitgelesen und das hilft schon auch also das vielleicht nochmal als Tipp zur falschen Zeit vielleicht weil jetzt die Folge schon durch ist aber an alle da draußen also wenn

  3. 48:56

    ihr die Möglichkeit habt eben auf dem Rechner das mitzulesen dann versteht man es natürlich schon besser auch wenn ich denke Kay dass du viele Sachen doch ganz gut auf Tonspur erklären konntest aber wie das immer so ist Code sich nur im Kopf durch zu denken das ist natürlich dann immer schwierig sehr gut ich würde sagen dann machen wir jetzt einen wirklichen Cut und machen dann mit der nächsten Folge weiter wo wir unter anderem über das Thema Errorhandling sprechen werden und dann jetzt auch wie gesagt nochmal der Hinweis wenn ihr euch das angeschaut habt und euch den Code angeschaut habt und irgendwelche

  4. 49:29

    Fragen offen sind zu den Themen die wir jetzt schon behandelt haben oder vielleicht auch kommen dann gerne eine E-Mail schreiben an podcast at genen minus it minus system .de und dann gehen wir in der nächsten Folge darauf ein und ich versuche das alles zu erklären und aufzubereiten und natürlich interessiert mich besonders ob diese Art von Frontal Unterricht einigermaßen interessant ist und ob man sich da gut vorstellen kann wie es im Code aussieht auch wenn genau dann danke ich dir für den Moment sehr gut Felix bis dahin bis dahin ciao ciao

03 — Weiterhören

Nebenan im Webcafé

Alle zwei Wochen montags eine neue Folge über Webentwicklung, Codequalität und die Art, wie wir zusammenarbeiten.

Alle 52 Folgen
04 — Feedback

Fragen an Felix und Kay?

Themenwunsch, Widerspruch oder eine Frage aus Deinem Projektalltag — schreib uns. Was uns erreicht, landet regelmäßig in einer der nächsten Folgen.

podcast [at] geenen-it-systeme.de