• בלוג
  • עמוד 97
  • מדריך קוד: שליפה מבסיס נתונים ב Node.JS והצגת המידע כטבלא ב HTML

מדריך קוד: שליפה מבסיס נתונים ב Node.JS והצגת המידע כטבלא ב HTML

פוסט זה כולל טיפ קצר בנושא פיתוח Front End. אם אתם רוצים ללמוד יותר לעומק על פיתוח Front End מהבסיס ועד הנושאים המתקדמים תשמחו לשמוע שבניתי קורס וידאו מקיף בנושא זה הכולל מעל 50 שיעורי וידאו והמון תרגול מעשי.
למידע נוסף והצטרפות לקורס בקרו בדף קורס Front End באתר.
 

בפוסט זה אדגים איך לכתוב אפליקציית Node.JS ו Express פשוטה, ששולפת מידע מבסיס נתונים באמצעות ספריית Knex.JS ומציגה אותו בתור טבלה ב HTML. חסרי הסבלנות ביניכם מוזמנים לדלג על ההסבר ולקפוץ ישר לקוד במאגר: https://github.com/ynonp/node-knex-ejs-demo

לכל השאר - בואו נראה איך זה עובד.

1. מה אנחנו בונים

המשימה במדריך הזה מאוד פשוטה - יש לנו אפליקציית Node.JS שמשתמשת ב Express וב EJS. אני יודע כולם רגילים לראות ריאקט ו Ajax ופריימוורקס מתוחכמים של פרונט אנד, אבל האמת שיש הרבה אפליקציות בעולם שעדיין כתובות בגישה הקלאסית של יצירת HTML בצד שרת, כולל אפליקציות חדשות.

בכל מקרה המערכת בדוגמה שלנו היא כזאת - יש לה EJS View שנראה בערך כך:

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
  </body>
</html>

ועכשיו אנחנו רוצים לחבר אותה לבסיס נתונים. בשביל הדוגמה יצרתי בסיס נתונים מסוג SQLite3 עם טבלה אחת בשם users ובתוכה הנתונים הבאים:

sqlite> select * from users;
user|user@mysite.com
admin|admin@mysite.com
info|info@mysite.com
sales|sales@mysite.com

לעמודה הראשונה קוראים name ויש בה את שם המשתמש ולעמודה השניה קוראים email והיא מכילה את כתובת המייל של המשתמש.

2. הקובץ lib/db.js

אני אוהב להתחיל בקובץ חיבור לבסיס נתונים. אם השליפות מתוחכמות או המערכת גדולה יהיה לי נוח לכתוב בקובץ הזה גם פונקציות עזר לשליפות, אבל בדוגמה שלנו הכל עדיין פשוט ולכן מספיק לכתוב בו את קוד החיבור לבסיס הנתונים ולייצא ממנו את האוביקט knex, איתו קוד חיצוני יוכל לכתוב את השליפות:

const knex = require('knex')({
  client: 'sqlite3', // or 'better-sqlite3'
  connection: {
    filename: "./mydb.sqlite"
  },
  useNullAsDefault: true,
});

module.exports = knex;

3. הקובץ routes/index.js

התחנה השניה היא קוד הטיפול בבקשה בקובץ routes/index.js. קוד זה צריך לשלוף את המידע מבסיס הנתונים. כל עוד אנחנו יודעים שאין הרבה מידע אפשר להשתמש ב:

router.get('/', async function(req, res, next) {
  const users = await knex('users').select('*');
  res.render('index', { title: 'Express', users: users });
});

ככל שיהיה יותר מדי נצטרך לשלוף רק "דף" אחד ממנו באמצעות הוספת limit. נרצה גם לתת למשתמשים אפשרות להעביר פרמטרים כדי לקבוע כמה רשומות יהיו בדף ובאיזה דף לצפות, ובמערכות עוד יותר מורכבות נרצה לקבל גם פרמטרים עבור סינונים - לדוגמה פרמטר שמגיע מהמשתמש שאומר שצריך להציג רק את המשתמשים שכרגע מחוברים למערכת. שינויים אלה משפיעים על שורת השליפה, ונשים לב לשני הדברים החשובים בפונקציה הקטנה הזו:

  1. אני משתמש ב await כדי לקבל את התוצאות ממש של השליפה, ולא את השליפה עצמה.

  2. אני מעביר את התוצאות ל View.

4. הצגת המידע כטבלה בקובץ views/index.ejs

הקובץ האחרון הוא ה View. קובץ זה רץ בלולאה על הרשומות במשתנה users ובונה מהן טבלת HTML:

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
    <p>All users = <%= JSON.stringify(users) %></p>
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Email</th>
        </tr>
      </thead>
      <tbody>
        <% for (user of users) { %>
        <tr>
          <td><%= user.name %></td>
          <td><%= user.email %></td>
        </tr>
        <% } %>
      </tbody>
    </table>
  </body>
</html>

אני הוספתי גם הדפסה של כל הנתונים בפורמט JSON בשביל שנוכל להיות בטוחים שהטבלה מציגה את כל המידע. כמובן שבמערכת אמיתית זה משהו שנרצה להוריד.

5. מה הלאה

ראינו בפוסט את המסלול שעובר מידע מבסיס הנתונים, דרך קוד צד שרת ועד שהופך ל HTML. ההרחבה המרכזית לדוגמה הזאת תהיה קבלת פרמטרים מהמשתמש כדי להציג רק חלק מהמידע כאשר יש בטבלה בבסיס הנתונים יותר מדי מידע.

ספריה מעניינת בהקשר הזה היא knex-paginate, שתתן לכם לכתוב קוד כזה:

const result = await knex('persons')
   .paginate({ perPage: 10, currentPage: 2 });