Der Großteil der heutigen Arbeit war eine Fortsetzung der Arbeit von gestern, lediglich die Implementierung von Geschäftslogik auf den Routen meiner Anwendung. Also dachte ich mir, dass ich eine Pause einlegen würde, um über drei Funktionen zu sprechen, die ich erstellt habe, um ganz bestimmte Dinge in meiner Anwendung zu tun.
Dies ist das Verzeichnis, in dem Sie all Ihre kleinen Funktionen ablegen, für die es schwierig ist, ein Zuhause zu finden, ohne die Ihre Anwendung jedoch nicht leben könnte.
Ein Utils-Ordner ist der Abladeplatz für die unbesungenen Helden vieler Anwendungen.
Wenn Sie eine Transformation Ihrer Daten durchführen müssen, die mehr als ein paar Codezeilen erfordert, die Sie wiederverwenden müssen, ist es eine gute Idee, sie in einer eigenen Datei abzulegen, die Sie exportieren können Rest Ihrer Bewerbung.
Warum kopieren wir nicht einfach und fügen ein? Nun, dies würde gegen zwei Programmierprinzipien verstoßen: DRY und Trennung von Belangen.
Sich zu wiederholen ist nicht nur eintönig, es ist auch mühsam, etwas zu ändern, wenn Sie es während Ihrer Bewerbung oft genug getan haben. Stellen Sie sich einen Algorithmus vor, der die prozentuale Regenwahrscheinlichkeit heute berechnet.
Ich weiß nicht, wie die Leute das machen, deshalb kann ich Ihnen kein Beispiel zeigen. Aber wenn Sie das alles in Ihrem Code an den verschiedenen Stellen kopieren, die Zugriff auf diese Berechnung haben müssen, werden Sie sehr verärgert sein, wenn das Very Smart Scientific Weather Committee mit einem neuen, genaueren Algorithmus zurückkommt.
Nehmen Sie wiederverwendete Teile Ihres Codes und finden Sie Möglichkeiten, sie so zu verpacken, dass sie an mehreren Stellen verwendet werden können, während sie dennoch an einer Stelle aktualisiert werden.
Alle Funktionen in meinem Utils-Ordner werden an vielen Stellen in meiner Anwendung verwendet!
Als Programmierer möchten wir auch keine Funktionen erstellen, die VIELE verschiedene Dinge tun. Wir hätten lieber VIELE Funktionen, die alle eine Sache tun. Warum? Nun, es macht diese Funktionen wiederverwendbar!
Was hat das mit einem Utils-Ordner zu tun? Nun, die Funktionen, die ich gleich durchgehen werde, haben keinen Platz in Funktionen wie getRoastsById, weil sie das nicht tun! Wenn wir etwas anderes tun müssen, sollten wir eine Funktion dafür erstellen. Aber wenn wir keinen logischen Platz für diese Funktion haben, weil es ein „Helfer“ ist, legen wir sie in unserem Utils-Verzeichnis ab!
Ich habe bisher drei benutzerdefinierte Dienstprogramme:
Hoffentlich ist anhand ihrer Namen klar, was sie tun, aber lassen Sie mich kurz das Problem erläutern, das sie lösen, und wie sie funktionieren.
Problem: In vielen der verschiedenen Dienste meiner Anwendung muss ich eine INSERT-Abfrage an meine Datenbank durchführen. Für diese Anweisungen müssen Sie explizit 1) die Namen der Spalten und 2) die Werte auflisten. Ich sollte diese nicht in jeder Route eingeben müssen, also habe ich eine Funktion erstellt, die das für mich erledigt.
Eingabe: Die Funktion benötigt zwei Parameter: table, eine Zeichenfolge, die mit dem Namen einer Tabelle in der Datenbank übereinstimmt, und obj, ein Javascript-Objekt, das das Modell darstellt, das der Benutzer der Datenbank hinzufügen möchte.
Ausgabe: Ein Objekt mit 1) einer eigenschaftsformatierten INSERT-Zeichenfolge mit Platzhalterwerten und 2) einem Array der Werte, die in einer parametrisierten Abfrage verwendet werden sollen.
const { snakeCase } = require('change-case-commonjs'); function insertStatement(table, obj) { const keys = Object.keys(obj); const values = Object.values(obj); let statement = `INSERT INTO ${table} (`; // Add snake_case keys to the statement const keyString = keys.map((key, i) => snakeCase(key)).join(', '); statement = `${keyString}) VALUES (`; // Add placeholders for the values const placeholders = keys.map((_, i) => `$${i 1}`).join(', '); statement = `${placeholders}) RETURNING *;`; // Return the query string and the values array return { text: statement, values: values }; } module.exports = insertStatement;
Problem: Ähnlich wie bei der INSERT-Anweisung müssen Sie bei der UPDATE-Anweisung sowohl Spaltennamen als auch Werte in Ihrer Abfrage explizit angeben. Diese Syntax unterscheidet sich von einer INSERT-Anweisung. Durch bedingte Logik könnte ich eine DatenbankQueryGenerator-Funktion erstellen, aber auch dies verstößt offenbar gegen die Interessenstrennung. Würde eine solche Funktion entscheiden, welche Art von Abfrage Sie möchten, oder eine darauf basierende Syntax generieren?
Eingabe: Die Funktion benötigt drei Parameter. obj, ein JavaScript-Objekt, das den aktualisierten Datensatz darstellt. table , eine Zeichenfolge, die mit einer Tabelle in der Datenbank übereinstimmen sollte. id , eine Ganzzahl, die dem Datensatz entspricht, der mit den neuen Informationen aktualisiert werden soll.
Ausgabe: Ein Objekt mit 1) einer eigenschaftsformatierten UPDATE-Zeichenfolge mit Platzhalterwerten und 2) einem Array der Werte, die in einer parametrisierten Abfrage verwendet werden sollen.
const { snakeCase } = require('change-case-commonjs'); function updateStatement(obj, table, id) { const keys = Object.keys(obj); const values = Object.values(obj); let statement = `UPDATE ${table} SET `; keys.forEach((key, index) => { statement = `${snakeCase(key)} = $${index 1}, `; }); // Remove the last comma and space statement = statement.slice(0, -2); // Determine the correct ID column based on the table const idColumn = table === 'users' ? 'username' : table === 'roasts' ? 'roast_id' : ''; // Finalize the statement with the WHERE clause statement = ` WHERE ${idColumn} = $${keys.length 1} RETURNING *;`; return { text: statement, values: [...values, id] }; } module.exports = updateStatement
Problem: Der Stil meiner Datenbank unterscheidet sich vom Stil meines JavaScript. Allerdings bin ich in keinem Bereich bereit, Kompromisse einzugehen. In meinen JS-Dateien verwendet meine Namenskonvention „camelCase“, während sie in meiner Datenbank „snake_case“ verwendet. Alle Eigenschaftsnamen der zurückgegebenen Objekte sind gleich, aber unterschiedlich formatiert. Um diesen Fallstandard beizubehalten, müsste ich mit „snake_case“ auf Eigenschaften in meinem JS zugreifen, aber das gefällt mir nicht.
Eingabe: Die Funktion benötigt nur einen Parameter, ein obj-JavaScript-Objekt, dessen Schlüssel in die CamelCase-Formatierung umgewandelt werden sollten.
Ausgabe: Dasselbe Objekt, mit Schlüsseln im CamelCase-Format.
const { camelCase } = require('change-case-commonjs'); function objectKeysToCamel(obj) { // Extract the keys and values const keys = Object.keys(obj); const values = Object.values(obj); let camel = {} // Change the formatting of each key, assigning it the proper value keys.forEach((key, i) => { const camelKey = camelCase(key); camel[camelKey] = values[i] }) // Return the new object return camel; } module.exports = objectKeysToCamel;
Wenn Sie über die Änderungen auf dem Laufenden bleiben, sie forken und lokal ausführen oder sogar Codeänderungen vorschlagen möchten, finden Sie hier einen Link zum GitHub-Repo!
https://github.com/nmiller15/roast
Die Frontend-Anwendung wird derzeit auf Netlify bereitgestellt! Wenn Sie mit einigen Funktionen herumspielen und es in Aktion sehen möchten, sehen Sie es sich unten auf einem Mobilgerät an.
https://knowyourhomeroast.netlify.app
Hinweis: Diese Bereitstellung verfügt über keine Backend-API, daher werden Konten und Röstungen zwischen den Sitzungen eigentlich nirgendwo gespeichert.
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3