How do I create a search html page in Google Appscript that connect to a data source in Google Sheets

My google appscript code is experiencing issues. The search function in the back end is successfully outputting “results” but the front end “displayFunction” is not recieving the “results”. This results in the search page not working correctly.

I have tried logging the values. The search function in the backend output the data as an array correctly. Meanwhile, the function in the front end is not getting the correct value.

Front end code

<!DOCTYPE html>
<html>
  <head>
    <title>Search From Google Sheets</title>
    <style>
      body {
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 0;
        text-align: center;
        background-color: #f7f7f7;
      }

      .search-container {
        margin-top: 30px;
      }

      input[type="text"] {
        padding: 10px;
        width: 300px;
        font-size: 16px;
        margin-bottom: 20px;
      }

      button {
        padding: 10px 20px;
        font-size: 16px;
        cursor: pointer;
      }

      .results {
        margin-top: 30px;
        text-align: left;
        display: inline-block;
        width: 100%;
      }

      .result-item {
        padding: 10px;
        margin: 5px;
        background-color: #fff;
        border: 1px solid #ddd;
        border-radius: 4px;
        cursor: pointer;
      }

      /* Styling for the "Add New Contact" button */
      .add-contact-btn {
        margin-top: 20px;
        padding: 10px 20px;
        background-color: #4CAF50;
        color: white;
        font-size: 16px;
        cursor: pointer;
        border: none;
        border-radius: 5px;
      }

      /* Collapsible details */
      .collapsible {
        display: none;
        padding-top: 10px;
        padding-bottom: 10px;
        padding-left: 20px;
        background-color: #f9f9f9;
        border-top: 1px solid #ddd;
      }

      .collapsible-content {
        margin-left: 20px;
      }
    </style>
  </head>
  <body>
    <!-- Add New Contact button placed before the search bar -->
    <button class="add-contact-btn" onclick="redirectToAddContactPage()">Add New Contact</button>

    <div class="search-container">
      <h1>Search Contacts</h1>
      <!-- Input for real-time search -->
      <input type="text" id="search-query" placeholder="Search for a name..." oninput="handleSearch(event)" />
    </div>

    <div class="results" id="search-results"></div>

    <script>
      // Handle real-time search functionality
      function handleSearch(event) {
        const query = event.target.value;
        google.script.run.withSuccessHandler(displayResults).search(query);
      }

      // Display the search results returned from Apps Script
      function displayResults(results) {
        console.log("results are", results);
  // Ensure results is an array before proceeding
  if (!Array.isArray(results)) {
    results = []; // If results is not an array, treat it as an empty array
  }

  const resultsDiv = document.getElementById('search-results');
  resultsDiv.innerHTML = ''; // Clear previous results

  if (results.length > 0) {
    results.forEach(result => {
      const resultItem = document.createElement('div');
      resultItem.classList.add('result-item');

      // Helper function to handle empty or missing values
      const getDisplayValue = value => value ? value : 'N/A';

      // Helper function to format Date objects
      const formatDate = date => {
        if (date instanceof Date && !isNaN(date)) {
          return `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`;
        }
        return 'N/A';
      };

      // Use helper functions for display
      resultItem.innerHTML = `
        <strong>ID Bệnh Nhân:</strong> ${getDisplayValue(result.id_benh_nhan)} <br>
        <strong>Họ và Tên:</strong> ${getDisplayValue(result.name)} <br>
        <button onclick="toggleDetails(event)">Show Details</button>
        <div class="collapsible">
          <div class="collapsible-content">
            <strong>ID Gia Đình:</strong> ${getDisplayValue(result.id_gia_dinh)}<br>
            <button onclick="toggleFamilyDetails(event, '${getDisplayValue(result.id_gia_dinh)}')">Show Family Details</button>
            <div class="collapsible" id="family-details-${getDisplayValue(result.id_gia_dinh)}">
              <!-- Family details will be injected here -->
            </div><br>
            <strong>ID Chế Độ Chính Sách:</strong> ${getDisplayValue(result.id_che_do_chinh_sach)}<br>
            <strong>ID Lớp Học:</strong> ${getDisplayValue(result.id_lop_hoc)}<br>
            <strong>ID Các Hỗ Trợ Của Làng:</strong> ${getDisplayValue(result.id_cac_ho_tro_cua_lang)}<br>
            <strong>ID Bệnh Án:</strong> ${getDisplayValue(result.id_benh_an)}<br>
            <strong>ID Đánh Giá:</strong> ${getDisplayValue(result.id_danh_gia)}<br>
            <strong>Ngày Sinh:</strong> ${formatDate(new Date(result.ngay_sinh))}<br>
            <strong>Giới Tính:</strong> ${getDisplayValue(result.gioi_tinh)}<br>
            <strong>Địa Chỉ Gia Đình:</strong> ${getDisplayValue(result.dia_chi_gia_dinh)}<br>
            <strong>Số Định Danh Cá Nhân:</strong> ${getDisplayValue(result.so_dinh_danh_ca_nhan)}<br>
            <strong>Đối Tượng, Thế Hệ Thứ:</strong> ${getDisplayValue(result.doi_tuong_the_he_thu)}<br>
            <strong>Hộ Khẩu:</strong> ${getDisplayValue(result.ho_khau)}<br>
            <strong>Ngày Tiếp Nhận:</strong> ${formatDate(new Date(result.ngay_tiep_nhan))}<br>
            <strong>Ngày Hòa Nhập:</strong> ${formatDate(new Date(result.ngay_hoa_nhap))}<br>
          </div>
        </div>
      `;

      resultsDiv.appendChild(resultItem);
    });
  } else {
    resultsDiv.innerHTML = '<p>No results found.</p>';
  }
}


      // Toggle the display of the detailed contact information
      function toggleDetails(event) {
        const collapsible = event.target.nextElementSibling;
        if (collapsible.style.display === 'none' || collapsible.style.display === '') {
          collapsible.style.display = 'block';
          event.target.textContent = 'Hide Details';
        } else {
          collapsible.style.display = 'none';
          event.target.textContent = 'Show Details';
        }
      }

      // Toggle family details section based on ID Gia Đình
      function toggleFamilyDetails(event, idGiaDinh) {
        const familyDetailsDiv = document.getElementById(`family-details-${idGiaDinh}`);
        if (familyDetailsDiv.style.display === 'none' || familyDetailsDiv.style.display === '') {
          google.script.run.withSuccessHandler(function(familyDetails) {
            familyDetailsDiv.innerHTML = `
              <strong>Họ và Tên Bố:</strong> ${familyDetails.father_name}<br>
              <strong>Họ và Tên Mẹ:</strong> ${familyDetails.mother_name}<br>
              <strong>SĐT Liên Hệ:</strong> ${familyDetails.contact_number}<br>
              <strong>Nghề Nghiệp Bố:</strong> ${familyDetails.father_occupation}<br>
              <strong>Nghề Nghiệp Mẹ:</strong> ${familyDetails.mother_occupation}<br>
              <strong>Địa Chỉ:</strong> ${familyDetails.address}<br>
              <strong>Thông Tin Người Giám Hộ:</strong> ${familyDetails.guardian_info}<br>
            `;
            familyDetailsDiv.style.display = 'block';
            event.target.textContent = 'Hide Family Details';
          }).getFamilyDetails(idGiaDinh);
        } else {
          familyDetailsDiv.style.display = 'none';
          event.target.textContent = 'Show Family Details';
        }
      }

      // Redirects the user to the "Add/Edit Contact" page
      function redirectToAddContactPage() {
        google.script.run.withSuccessHandler(function(html) {
          document.open();
          document.write(html);
          document.close();
        }).getedit_contacts();
      }

      // Initial load of all contacts when the page loads
      window.onload = function() {
        loadAllContacts();
      };

      function loadAllContacts() {
        google.script.run.withSuccessHandler(displayResults).getAllContacts();
      }
    </script>
  </body>
</html>

Backend code

// This function fetches all contacts, including additional fields
function getAllContacts() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Bệnh nhân'); // Ensure correct sheet name
  const data = sheet.getDataRange().getValues(); // Get all data from the sheet (including headers)
  
  const contacts = [];
  
  // Loop through all rows (skipping the header row)
  for (let i = 1; i < data.length; i++) {
    const contact = {
      id_benh_nhan: data[i][0] || 'N/A', // ID bệnh nhân (use 'N/A' if empty)
      id_gia_dinh: data[i][1] || 'N/A', // ID gia đình
      id_che_do_chinh_sach: data[i][2] || 'N/A', // ID chế độ chính sách
      id_lop_hoc: data[i][3] || 'N/A', // ID lớp học
      id_cac_ho_tro_cua_lang: data[i][4] || 'N/A', // ID các hỗ trợ của làng
      id_benh_an: data[i][5] || 'N/A', // ID bệnh án
      id_danh_gia: data[i][6] || 'N/A', // ID đánh giá
      name: data[i][7] || 'N/A', // Họ và tên
      ngay_sinh: data[i][8] || 'N/A', // Ngày sinh
      gioi_tinh: data[i][9] || 'N/A', // Giới tính
      dia_chi_gia_dinh: data[i][10] || 'N/A', // Địa chỉ gia đình
      so_dinh_danh_ca_nhan: data[i][11] || 'N/A', // Số định danh cá nhân
      doi_tuong_the_he_thu: data[i][12] || 'N/A', // Đối tượng, thế hệ thứ
      ho_khau: data[i][13] || 'N/A', // Hộ khẩu
      ngay_tiep_nhan: data[i][14] || 'N/A', // Ngày tiếp nhận
      ngay_hoa_nhap: data[i][15] || 'N/A' // Ngày hòa nhập
    };
    contacts.push(contact);
  }

  // Return all contacts
  return contacts;
}


// This function performs the search operation
function search(query) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Bệnh nhân'); // Change 'Bệnh nhân' to your actual sheet name
  const data = sheet.getDataRange().getValues(); // Get all data from the sheet (including headers)
  
  const results = [];
  
  // Ensure query is a string and convert to lowercase for case-insensitive comparison
  const searchQuery = (query && query.toString().toLowerCase()) || ''; // Handle query if undefined or null
  
  // Loop through the rows in the sheet starting from the second row (skipping the header row)
  for (let i = 1; i < data.length; i++) {
    // Ensure the name field (data[i][7]) exists and is a string before calling .toString()
    const name = (data[i][7] && data[i][7].toString().toLowerCase()) || ''; // If name is undefined or null, use an empty string

    // If the name contains the search query (case-insensitive), add the result to the 'results' array
    if (name.includes(searchQuery)) {
      const result = {
        id_benh_nhan: data[i][0],
        id_gia_dinh: data[i][1],
        id_che_do_chinh_sach: data[i][2],
        id_lop_hoc: data[i][3],
        id_cac_ho_tro_cua_lang: data[i][4],
        id_benh_an: data[i][5],
        id_danh_gia: data[i][6],
        name: data[i][7],
        ngay_sinh: data[i][8],
        gioi_tinh: data[i][9],
        dia_chi_gia_dinh: data[i][10],
        so_dinh_danh_ca_nhan: data[i][11],
        doi_tuong_the_he_thu: data[i][12],
        ho_khau: data[i][13],
        ngay_tiep_nhan: data[i][14],
        ngay_hoa_nhap: data[i][15]
      };
      results.push(result); // Add the matching result
    }
  }

  // Return the results array to the front-end (HTML page)
  Logger.log(results);
  return results;
}


// This function fetches the family details for a given ID Gia Đình
function getFamilyDetails(idGiaDinh) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Gia đình'); // Ensure correct sheet name
  const data = sheet.getDataRange().getValues(); // Get all data from the sheet (including headers)
  
  let familyDetails = {
    father_name: 'N/A',  // Default values in case data is missing
    mother_name: 'N/A', 
    contact_number: 'N/A',
    father_occupation: 'N/A',
    mother_occupation: 'N/A',
    address: 'N/A',
    guardian_info: 'N/A'
  };

  // Loop through the rows in the "Gia Đình" sheet and find the matching ID Gia Đình
  for (let i = 1; i < data.length; i++) {
    const familyId = data[i][0]; // Assuming ID Gia Đình is in the first column
    if (familyId == idGiaDinh) {
      familyDetails = {
        father_name: data[i][1] || 'N/A',  // Họ và tên bố
        mother_name: data[i][2] || 'N/A',  // Họ và tên mẹ
        contact_number: data[i][3] || 'N/A',  // SĐT liên hệ
        father_occupation: data[i][4] || 'N/A',  // Nghề nghiệp bố
        mother_occupation: data[i][5] || 'N/A',  // Nghề nghiệp mẹ
        address: data[i][6] || 'N/A',  // Địa chỉ
        guardian_info: data[i][7] || 'N/A'  // Thông tin người giám hộ
      };
      break;
    }
  }

  return familyDetails;
}


    

how to append one attribute with value

<a href=”#” data-bs-toggle=”modal” data-bs-target=”#editLicenseModal” class=”edit-license” data-license-id=”2″ data-customer-id=”11″>Edit</a>

i want to append data-license-id=”2″ data-customer-id=”11″ attribute and values to <button type=”button” class=”btn btn-primary” id=”closeModal” onclick=”editLicense()” data-license-id=”” data-customer-id=””>Edit License</button> this tag

<button type=”button” class=”btn btn-primary” id=”closeModal” onclick=”editLicense()” data-license-id=”2″ data-customer-id=”11″>Edit License</button>

Alert Box for webpage. Javascript/HTML

I’m working on an assignment for school and it’s asking me to create an alert for two email addresses being different. What I have works as far as giving an alert when the two emails are different, except that it gives an alert in any other case as well. How do I fix this? Here’s what I got:

        <form method="POST">
            <p>
               <label for="email">Email Address:</label>
               <input type="text" name="email" id="email">
            </p>
            <p>
               <label for="confirmation">Confirm Email:</label>
               <input type="text" name="confirmation" id="confirmation">
            </p>
            <p>
                <textarea placeholder="Ask question here" id="textarea"></textarea>
            </p>
         </form>
         
         <button onclick="alertBox()">Submit</button>

         <script>
         function alertBox() {
            let email = document.getElementById("email");
            let confirmation = document.getElementById("confirmation");
            if (email != confirmation) {
                alert("Email addresses do not match. Please try again.");
            }
         }
         </script> ```

The assignment says to create a "submit" button and that the form isn't supposed to be submitted to a server, hence no action attribute in the form element and a button instead of input type submit. Any help is appreciated. 

Best way to structure your store for large number of state values in Zustand

So, here is a little bit of context: I am very new to Zustand and wanted to try it, so I decided to use it in my car app project. In the project, I have car filtering functionality where I have many filters of different types. The structure is as follows:

export interface CarFilters {
  location?: Location[];
  carModel?: CarModel[];
  priceRange?: FilterRange<number>;
  modelYearRange?: FilterRange<number>;
  kilometersDriven?: FilterRange<number>;
  registeredIn?: Location;
  trustedCars?: TrustedCars[];
  transmission?: Transmission;
  bodyColor?: string[];
  fuelType?: FuelType[];
  engineCapacity?: FilterRange<number>;
  assembly?: Assembly;
  bodyType?: BodyType[];
  modelCategory?: ModelCategory[];
  sellerType?: SellerType;
  numberOfDoors?: NumberOfDoors;
  seatingCapacity?: SeatingCapacity;
  adProperties?: AdProperties[];
  searchQuery?: string;
}

so, I was wondering what is the best way to structure your store should I make one filter state and set it when any of the value in it changes or should I make each filter an individual state and have a setter for that? Also, I want two very specific features:

  1. One is I want to show in the app what filters are currently being
    applied for example if there are values in the location array or car
    model array I want to show them in active filters
  2. Second is I want to show the count of these active filters someplace
    else.

What is the best and performant way to do this and what are the things I need to take care of so that I don’t end up rerendering more than required? A detailed explanation would be a great help.

Stripe Payment Vue3

I would like to integrate stripe to charge a user a one-time 20$ payment after successfully completing a form in my Vue3 application. I’ve integrated vue-stripe-js and have been able to obtain a token from stripe using the card element in that package, but have been unable to handle submitting the charge to stripe.

Here’s the request so far:

    const pay = () => {
      const cardElement = card.value.stripeElement

      elms.value.instance.createToken(cardElement).then((result) => {
        if (result.token) {
          // what should I do with the token to submit a charge for $20 and see it in my stripe dashboard?
          console.log(result.token)
        }
      })
    }

The ideal solution would show me what to do with the token to submit a payment and validate that the other fields in the form have been inputted before the payment is completed. Here’s a stackblitz that approximates the problem, thanks so much for sharing your knowledge.

MUI Custom Grid issue for different viewport

I am planning to write a custom mui grid. Grid will behave differently for different viewport.

for XL it is working as expected but not for tablet and small device viewport.

For Tablet, I need gutter 24px and width of each item inside container auto where margin outside container, will be 37px.

For small device, columns would be 4 and width will be auto and gutter will be 8px

working code for XL is as below

import React from "react";
import Grid2 from "@mui/material/Unstable_Grid2"; // MUI Grid2
import { SxProps, Theme } from "@mui/material";

interface MyGridProps {
  container?: boolean;
  gridColumn?: number;
  size?: { [key: string]: number }; // Responsive sizes
  sx?: SxProps<Theme>; // Accept custom styles
  children?: React.ReactNode;
}

const MyGrid: React.FC<MyGridProps> = ({
  container = false,
  gridColumn = 12,
  size,
  sx = {},
  children,
}) => {
  
  const calculateItemStyles = (breakpoint: string): SxProps<Theme> => {
    if (size && size[breakpoint]) {
      const cols = size[breakpoint];
      const width = cols * 70; // Each column is 70px wide

      return {
        flexBasis: `${width}px`,
        maxWidth: `${width}px`,
      };
    }
    return {};
  };

  return (
    <Grid2
      container={container}
      columns={gridColumn}
      sx={{
        ...(container && {
          borderSizing: "border-box",
          flexWrap: "wrap",
          justifyContent: "center",
          gap: "32px", // Default gap for container
          "@media (min-width:1440px)": {
            gap: "32px",
          },
        }),
        ...(!container && {
          ...calculateItemStyles("xs"),
          "@media (min-width:568px)": calculateItemStyles("sm"),
          "@media (min-width:1280px)": calculateItemStyles("xl"),
          "@media (min-width:768px)": {
            ...calculateItemStyles("md"),
            gap: '24px'
          },

        }),
        ...sx, // Merge custom styles
      }}
    >
      {children}
    </Grid2>
  );
};

export default MyGrid;

How to bold text between 1. and :

Good day gurus.
Please I am stuck at a spot in a pure JavaScript library that am writing.

One of the functions of the library is to auto bold any text that appears between . and :

For example;

  1. Class A: This is class A. In class A, there are many other classes that we might discussed. For instance: Sub-categories of class A.

  2. Class B: This is class B

A. Class C: This is class C.
B. Class D: This is class D.

i. Class E: This is class E.
ii. Class F: This is class F

What I want here is only text that appears between 1. and :, 2. and :, A. and :, B. and :, i. and :, ii. and : should be bold.

Note: I know this could be achieved via CSS if they were to be ul, ol items. But the script am writing should be able to bold any matches even if ul, ol are not used.

I have tried but mine will bold even matches found in middle of content which is not the purpose. Even if for instance, we “This is a . And here is a :”, I don’t want And here is a to be bold.

I don’t know if the explanation is clear but I will try and give more details upon request.

<script>
        window.onload = function() {
            // Get the text content of the div
            var text = document.getElementById("content").innerHTML;
            // Regex pattern to match the text between the number/letter and the colon
            var pattern = /(d+.|w.s?)([^:]+)(?=s*:)/g;
            // Replace matched text with bold tags around both the number/letter and the content after it
            var modifiedText = text.replace(pattern, function(match, p1a, p2a) {
                return "<b>" + p1a + "</b><b>" + p2a.trim() + "</b>";
            });
//alert(modifiedText);
            // Update the content of the element with the modified text          document.getElementById("content").innerHTML = modifiedText;
        };
    </script>

This image shows the preview of the script

From the image you can see aside the listed items bold, some part of the write were also bold which is not supposed to be so.

Thanks for your help

Clicked event set for multiple block works only once

I have this function to get data from an API, then I create a <div> and set the data into that . After that, for each <div> I created, I set a “click” event for that <div>.
The code worked fine for the first time I clicked a <div>, but after that, the “click” event cannot be triggered anymore, I haven’t found the reason, can someone help me?
Thank you, below is the src:

const setSuggestedQuestion = async function () {
    if (!hasSetSuggestedQuestions) {
        /* Get data from the API, response is like this:
                   ["Question 1","Question 2"]   
        */ 
        await getSuggestedMessage()
        hasSetSuggestedQuestions = true
        //Create the div, then set the necessary data for it
        const suggestedDiv = document.getElementsByClassName("mc_suggested_question")[0]
        for (let i = 0; i < suggestedQuestion.data[0].length; i++) {
            const suggestedQuestionDiv = document.createElement('div')
            suggestedQuestionDiv.className = "detail_suggested_question";
            suggestedQuestionDiv.setAttribute("data_suggested_question", suggestedQuestion.data[0][i])
            suggestedQuestionDiv.innerHTML = generateChatElement(link, 9, suggestedQuestion.data[0][i], '');
            suggestedDiv.appendChild(suggestedQuestionDiv);
        }
    
    //Set click event the all of the created div
    const suggestedElements = document.getElementsByClassName("detail_suggested_question");
    for (let suggestedElement of suggestedElements) {
        suggestedElement.addEventListener("click", async function () {
            sendQuestion(this.getAttribute("data_suggested_question"))
        });
    }
}

I get the data, set it into a block, then set a click event for it
I expect the event will be fired anytime I click the block, but it runs only once

GuildMemberUpdate event getting oldMember and newMember both false values about roles

My Discord bot uses the GuildMemberUpdate event to validate whether a specific role has been added/removed from users in a server, and based on this, it performs certain actions on a database.

The event is expected to do the following, and in fact, it works correctly:

  • Was role X added? Action 1 is performed.
  • Was role X removed? Action 2 is performed.

The issue arises when, for some reason, the bot needs to be restarted. After restarting, if role X is removed from a user who already had it previously, the event stops working as expected. It doesn’t trigger either of the two conditions because, as seen in hasVipRoleNow and hadVipRoleBefore, both values are returned as false:

const { Events } = require('discord.js');

module.exports = {
    name: Events.GuildMemberUpdate,
    async execute(oldMember, newMember) {
        // This variable has the ID of the official server.
        const guildId = 'MY_GUILD_ID';

        // This variable has the ID of the VIP User role.
        const vipRoleId = 'MY_ROLE_ID';

        // The conditional checks if the event was triggered in the official server.
        if (newMember.guild.id !== guildId) {
            return;
        }

        const oldRoles = oldMember.roles.cache;
        const newRoles = newMember.roles.cache;

        const hasVipRoleNow = newRoles.has(vipRoleId);
        const hadVipRoleBefore = oldRoles.has(vipRoleId);

        if (!hadVipRoleBefore && hasVipRoleNow) {
            try {
                managePremiumStatus(true, newMember);
            } catch (error) {
                console.error(error);
            }
        }

        if (hadVipRoleBefore && !hasVipRoleNow) {
            try {
                managePremiumStatus(false, newMember);
            } catch (error) {
                console.error(error);
            }
        }
    },
};

The best approach I’ve come up with is to use a third if statement so that if both values are false, it performs the same behavior as the second if.

if (!hadVipRoleBefore && !hasVipRoleNow) {
    // Treat this area as the second 'if'.
}

However, I’m not sure if this is the correct solution or if there might be a better one.

I am here. One man against a legion [closed]

how do I make a program that can generate digital currency from Bitcoin. As in pulling money from “nothing” continuously running as abackground app on a phone so that anyone can have money at anytime and then can be withdrawn to a bank account without a user needing to do anything except input their information, such a program could end world hunger/poverty help medical supplies to be dispersed in 3rd world countries .

I tried to make this program with blackbird (a website that utilities ai to write program pacs) . I’m a noob and don’t know how or where to start. but so far. I think I’m ok at it.
I wrote the idea for the AI to formulate the programming and make it into reality on blackbird, and then tried to deploy the test which did fail because I didn’t setup the https information. so it needs a lot of work.
also, as titled. one man against a legion, I am here..
the one man the worlds burning gaze is on.
one mistake, was all I needed to get access. thanks. 🙂

How to retrieve nested JS object and get its data by index?

I have an extensive JS object with any nested objects, eg:

data = {
  sundriesIncreases {
    month1: { projectedIncrease: 1.3, actualIncrease: 1.3 },
    month2: { projectedIncrease: 1.6, actualIncrease: 1.5 },
    month3: { projectedIncrease: 1.4, actualIncrease: 1.4 },
    month4: { projectedIncrease: 2, actualIncrease: 2.1 },
    month5: { projectedIncrease: 1.2, actualIncrease: 1.3 },
    //etc
  },
  //etc
}

I am using a loop to loop through a different data set and I want to use the index of that loop to retrieve the corresponding months data from the array.

However, I am having trouble trying to figure out how to get a given value of the child array by index.

So far I have tried getting it by index as such:

customerNumbers.forEach((amt, index) => {
   let actInc = data.sundriesIncreases[index].actualIncrease;
   console.log(`amt=${val} index=${index} increase=${actInc}`)
});

And converting the parent object to an array:

var increasesArr = Object.entries(data.sundriesIncreases);
customerNumbers.forEach((amt, index) => {
   let actInc = increasesArr[index].actualIncrease;
   console.log(`amt=${val} index=${index} increase=${actInc}`)
});

But so far nothing works.

Of course

customerNumbers.forEach((amt, index) => {
   if (index == 0) {
     let actInc = data.sundriesIncreases.month1.actualIncrease;
     console.log(`amt=${val} index=${index} increase=${actInc}`)
   }
});

works, but this isn’t ideal.

Googling the problem reveals a lot on how to get the key by value noting a lot about how to do the opposite.

Would anyone be able to point me in the right direction?

Scroll-Horizontal: Trigger Animations Only for the Visible Section

I’m a student, and I really need some help. I’ve also spoken to my professor, but the last time i have a question, i don’t received a response. I need to complete this work before the end of 2024…so if someone could help me!I reallu apreciate.

I’m working on a horizontally scrolling website where each section has different animations (images,button,div…) that should trigger only when the section becomes visible in the viewport. The goal is to stop or pause animations for sections that are not currently in view and activate them only when the user scrolls to the corresponding section.

What I’ve Tried:
I’m using the Intersection Observer API to detect when a section enters or leaves the viewport.
I’ve added classes (visible and paused) to toggle the animations based on the section’s visibility.
The animations work, but the problem is that they trigger for all sections at once or behave inconsistently when scrolling through the horizontal layout.
I also tried chat gpt e outras ai…

How to configure CRACO config file?

I want to configure the middleware of my craco.config.js, but I don’t know have, so I want tips. My actual file is:

const {CracoAliasPlugin} = require('react-app-alias')

module.exports = {
  plugins: [
    {
      plugin: CracoAliasPlugin,
      options: {}
    }
  ],
}

I found that I need to do something:

  devServer: (devServerConfig, { env, paths }) => {
    devServerConfig = {
      onBeforeSetupMiddleware: undefined,
      onAfterSetupMiddleware: undefined,
      setupMiddlewares: (middlewares, devServer) => {
        // Define middlewares
        return middlewares;
      },
    };
    return devServerConfig;
  },

But I don’t know how to use it and configure it, and I don’t want to implement any middlewares for now, just let the navigation without authentication. But, I’ll need them in the future, so, I want to know how to configure it and some tips on what is good to do here… also, if I just implement this the way is above it gives me error 404.