Issue with Server-side \ Client-side HTML/JavaScript

61 views
Skip to first unread message

Eran Raviv

unread,
Nov 27, 2023, 4:28:50 AM11/27/23
to Google Apps Script Community
Hi, 

I'm trying to create a simple webapp to track daily foods I consume and fail to deliver the simple task of displaying the items from the google spreadsheet on the webapp.

On the code.js server-side everything's seem to work well and the return statement variable is includes the required array data.

On the index.html client side, on the other hand, a null value to passed for a reason I can't find.

Did anyone encounter this phenomena? 

Attaching the code files and the error screenshot,

Thanks!

ER

Index.html

<!DOCTYPE html>
<html dir="rtl">
<head>
    <title>Food Diary</title>
    <!-- Add some CSS for styling -->
   <!-- CSS Styling for Success Message -->
    <meta name="viewport" content="width=device-width, initial-scale=1">

  <style>
        /* Existing styles */

        /* Responsive styles for mobile devices */
        @media only screen and (max-width: 600px) {
        body {
          font-size: 32px; /* Larger font size for readability */
        }
        h1 {
          font-size: 48px; /* Adjust heading size */
        }
        form {
          width: 90%; /* Use percentage for width */
          margin: auto; /* Center the form */
        }
        button {
          padding: 20px 40px; /* Larger buttons for touch screens */
      }
    /* Other responsive adjustments */
}

    </style>
</head>
<body>
    <h1>Food Tracker</h1>
    <form id="foodForm">
      <!-- Combo-box for Food/Drink Items -->
      <select name="foodItem" required>
        <option value="">Choose from list</option>
      </select>

      <!-- Quantity Input -->
      <input type="number" name="quantity" placeholder="quantity" required>

      <!-- Submission Button -->
      <button type="button" onclick="submitEntry()">Submit</button>
    </form>
    <!-- Container for Success Messages -->
    <div id="messageContainer"></div>
    <div id="allEntries">
      <h3>All Entries</h3>
      <!-- Records will be listed here -->
    </div>

    <div id="todaysEntries">
      <h3>Today's Entries</h3>
      <!-- Entries will be listed here -->
    </div>

  <script>

    function handleError(error) {
    console.error("Error occurred:", error);
    // Display a more detailed error message on the page
    const container = document.getElementById('todaysEntries');
    container.textContent = 'Error loading entries: ' + error.message;
    }

    function getAllEntries() {
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DailyTrack");
    return sheet.getDataRange().getValues();
    }

    function displayAllEntries(entries) {
    const container = document.getElementById('allEntries');
    entries.forEach(entry => {
        const div = document.createElement('div');
        div.textContent = `Item: ${entry[0]}, Date: ${entry[1]}, Quantity: ${entry[2]}`;
        container.appendChild(div);
      });
    }


    // Function to populate the combo-box with items from Google Sheets
    function populateFoodItems(items) {
        var select = document.getElementsByName("foodItem")[0];
        items.forEach(function(item) {
            var option = document.createElement('option');
            option.value = option.textContent = item;
            select.appendChild(option);
        });
    }

    function displayTodaysEntries(entries) {
   
    console.log("Entries received:", entries); // This line logs the data to the console

    //Check if entries is not null or undefined
    if (!entries) {
        console.error('No entries received');
        return;
    }

    const container = document.getElementById('todaysEntries');
    entries.forEach(entry => {
        const div = document.createElement('div');
        div.textContent = `Item: ${entry[0]}, Quantity: ${entry[2]}`; // Adjust according to your data structure
        container.appendChild(div);
    });
   }


  function submitEntry() {
    var foodItem = document.getElementsByName("foodItem")[0].value;
    var quantity = document.getElementsByName("quantity")[0].value;

    google.script.run
        .withSuccessHandler(function() {
            displaySuccessMessage(foodItem, quantity);
        })
        .addEntry(foodItem, quantity);
}

function displaySuccessMessage(foodItem, quantity) {
    var messageContainer = document.getElementById('messageContainer');

    // Create a new div for the message
    var messageDiv = document.createElement('div');
    messageDiv.textContent = 'You have consumed ' + quantity + ' ' + foodItem;
    messageDiv.style.color = 'red'; // You can add more styling as needed

    // Append the new message div to the container
    messageContainer.appendChild(messageDiv);
}

    // Load items into the combo-box when the page loads
    document.addEventListener('DOMContentLoaded', function() {
        google.script.run.withSuccessHandler(populateFoodItems).getFoodItems();
    });

    document.addEventListener('DOMContentLoaded', function() {
    google.script.run
        .withSuccessHandler(displayTodaysEntries)
        .withFailureHandler(handleError)
        .getTodaysEntries();
    });

    document.addEventListener('DOMContentLoaded', function() {
      google.script.run
        .withSuccessHandler(displayAllEntries)
        .getAllEntries();
    });

  </script>

</body>
</html>

Code.js

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index')
    .setTitle('Food Tracker') // Optional: Set a title for your web app page
    .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
function addEntry(foodItem, quantity) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DailyTrack");
  sheet.appendRow([foodItem, new Date(),  quantity]);
}
function submitEntry() {
    var foodItem = document.getElementsByName("foodItem")[0].value;
    var quantity = document.getElementsByName("quantity")[0].value;

    google.script.run
        .withSuccessHandler(function() {
    displaySuccessMessage(foodItem,quantity);
    })
    .addEntry(foodItem, quantity);
}

// Function to display success message
function displaySuccessMessage(foodItem, quantity) {
    var messageContainer = document.getElementById('messageContainer');

    // Create a new div for the message
    var messageDiv = document.createElement('div');
    messageDiv.textContent = 'You have consumed ' + quantity + ' ' + foodItem;
    messageDiv.style.color = 'red'; // You can add more styling as needed

    // Append the new message div to the container
    messageContainer.appendChild(messageDiv);
}
function getEntries() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DailyTrack");
  return sheet.getDataRange().getValues();
}
function getFoodItems() {
    var sheet = SpreadsheetApp.openById('1a04dsi8NSHP6QQY4ieidGlMoNQqINdBP6y_kPL-UGb8').getSheetByName('DataSets');
    var data = sheet.getDataRange().getValues();
    return data.map(function(row) { return row[0]; }); // Assuming items are in the first column
}

function getTodaysEntries() {
    try {
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DailyTrack");
    const today = new Date();
    today.setHours(0, 0, 0, 0); // Set to start of the day
    Logger.log("Today's Date (Start of Day): " + today);

    const data = sheet.getDataRange().getValues();
    Logger.log("Data from Spreadsheet: ");
    Logger.log(data);

    const filteredData = data.filter(row => {
        const entryDate = new Date(row[1]); // Assuming date is in the second column
        entryDate.setHours(0, 0, 0, 0);
        Logger.log("Entry Date: " + entryDate + ", Today: " + today + ", Comparison Result: " + (entryDate.getTime() === today.getTime()));
        return entryDate.getTime() === today.getTime();
    });
    Logger.log("Filtered Data (Today's Entries): ");
    Logger.log(filteredData);

    return filteredData;

    } catch (error) {
        Logger.log('Error in getTodaysEntries: ' + error.toString());
        throw new Error('Error fetching entries.');
    }
   
}Picture1.png

cwl...@gmail.com

unread,
Dec 6, 2023, 9:27:32 AM12/6/23
to Google Apps Script Community
In web apps, you need to be careful how you structure things and understand *where* the code is being executed.
You have added your server functions into your html file that runs in the browser. Anything that works with your sheet resides on the server and should be in your code.js file.
Then in your html file, you call google.script.run to access the backend script from the browser.

doGet() creates the initial page and sends it to the browser.
Once open in the browser, you update the page content by sending requests to your functions on the server via google.script.run which returns the data back to the browser. 
You would use <script>'s in the html file to handle the data returned by the function.
Reply all
Reply to author
Forward
0 new messages