Undefined: Der dritte boolesche Wert

Avatar of Kushagra Gour
Kushagra Gour am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Ich wollte in einem meiner Projekte eine Benachrichtigungsnachricht implementieren, ähnlich wie man sie in Google Docs sieht, während ein Dokument gespeichert wird. Mit anderen Worten: Jedes Mal, wenn eine Änderung vorgenommen wird, erscheint eine Nachricht, die anzeigt, dass das Dokument gespeichert wird. Dann, sobald die Änderungen gespeichert sind, wird die Nachricht zu: „Alle Änderungen in Drive gespeichert.“

Werfen wir einen Blick darauf, wie wir das mit einem booleschen Wert machen könnten, aber tatsächlich drei mögliche Zustände abdecken. Dies ist definitiv nicht der einzige Weg, dies zu tun, und ehrlich gesagt bin ich mir nicht einmal sicher, ob es der beste Weg ist. So oder so, es hat für mich funktioniert.

Hier ist ein Beispiel für diesen „Speichervorgang…“-Status

Screenshot of the Google Docs header with a message that says the document is saving.
Die Benachrichtigung „Speichervorgang“ wird angezeigt, sobald eine Änderung am Dokument vorgenommen wird.

…und der „Gespeichert“-Status

Screenshot of the the message reading All Changes Saved after saving has completed.
Die Benachrichtigung „Gespeichert“ wird angezeigt, sobald eine Änderung oder eine Reihe von Änderungen abgeschlossen ist.

Die Verwendung eines Boolean-Wertes zur Definition des Zustands war meine sofortige Reaktion. Ich könnte eine Variable namens isSaving haben und diese verwenden, um eine bedingte Zeichenkette in meiner Vorlage zu rendern, wie hier

let isSaving;

…und in der Vorlage

<span>{{ isSaving ? ‘Saving...’ : ‘All changes saved’ }}</span>

Jetzt setzen wir den Wert jedes Mal auf true, wenn wir mit dem Speichern beginnen, und dann auf false, wenn kein Speichervorgang läuft. Einfach, oder?

Hier gibt es jedoch ein Problem, und es handelt sich um ein kleines UX-Problem. Die *Standardnachricht* wird als „Alle Änderungen gespeichert“ gerendert. Wenn der Benutzer die Seite *anfänglich* aufruft, findet kein Speichervorgang statt, und wir erhalten die Nachricht „Gespeichert“, obwohl nie ein Speichervorgang stattgefunden hat. Ich würde es vorziehen, nichts anzuzeigen, bis die erste Änderung die erste Nachricht „Speichervorgang…“ auslöst.

Dies erfordert einen **dritten Status** in unserer Variablen: isSaving. Nun stellt sich die Frage: Ändern wir den Wert in eine *Zeichenkette* als einen der drei Zustände? Das könnten wir tun, aber was, wenn wir den dritten Zustand in unserer aktuellen booleschen Variablen selbst erreichen könnten?

isSaving kann zwei Werte annehmen: true oder false. Aber was ist der Wert *direkt* nachdem wir ihn in der Anweisung deklariert haben: let isSaving;? Es ist undefined, weil der Wert jeder Variablen undefined ist, wenn sie deklariert wird, es sei denn, ihr wird etwas zugewiesen. Großartig! Wir können diesen anfänglichen undefined-Wert zu unserem Vorteil nutzen… aber das erfordert eine leichte Änderung daran, wie wir unsere Bedingung in der Vorlage schreiben.

Der ternäre Operator, den wir verwenden, ergibt den zweiten Ausdruck für alles, was nicht zu true konvertiert werden kann. Die Werte undefined und false sind beide nicht true und werden daher für den ternären Operator als false ausgewertet. Selbst eine if/else-Anweisung würde ähnlich funktionieren, da else für alles ausgewertet wird, was nicht true ist. Aber wir möchten zwischen undefined und false unterscheiden. Dies kann behoben werden, indem explizit auch auf den false-Wert geprüft wird, wie hier

<span>
{{ isSaving === true ? 
  ‘Saving...’ : 
  (isSaving === false ? ‘All changes saved’: ‘’) 
}}
</span>

Wir prüfen jetzt strikt auf true und false-Werte. Dies hat unseren ternären Operator etwas verschachtelt und schwer lesbar gemacht. Wenn unsere Vorlage if/else-Anweisungen unterstützt, können wir die Vorlage wie folgt umgestalten:

<span>
{% if isSaving === true %}
  Saving...
{% elseif isSaving === false %}
  All changes saved
{% endif %}
</span>

Aha! Nichts wird gerendert, wenn die Variable weder true noch false ist – genau das, was wir wollen!