Loop through a value in a row

So I’m creating a daily process to calculate the next payment days of a subscription within a 30 day interval.

I tried using a Javascript column, but I’ve had many issues with them since they don’t seem to like certain JS features. Instead, I created a step by step process through different math columns and excel formulas and I ended up with this:

Basically, if next_date equals looping_date (which right now is always set to today), then it adds the subscription’s ID and next_date to another table called payment_tasks.

However, as I said, I need this to calculate it daily, and it must calculate the next 30 days from today (here comes a part of ignoring previously obtained dates, but I won’t get into it). My idea was to have a loop that would be changing the offset value from 0 to 29, that value is added to looping_date and so it goes and makes the calculation for the following 30 days.

Since I hadn’t used the new Glide Workflows I decided to try it and created this one:

However, I am now realizing that this does not loop through the offset of each row 30 times, but instead goes through the first 30 rows and changes the value of offset to offset+1.

Having said this, is there a way through the glide workflows where I can loop through each offset of my table 30 times as I wish? Is there another way to do it that does not rely on 3rd party integrations? Even if it means making peace with the Glide Javascript column, I just need this to work :sob:

It seems to me that you might be making this way more complicated than it needs to be.

Can we take a few steps back?
Please forget about everything you’ve tried to do already, or what you think the solution might be, and instead focus on the end goal.

Show me a screenshot of your data (not a bunch of computed columns that probably aren’t necessary), and help me to understand what the end result should look like. I’m quite sure I can help you if I have a clear picture of the end goal.

EDIT: Since I wrote this, the requirements I was given changed, so I’m editing this post.

I have a table called subscriptions, each subscription generates Payment Tasks. By example, if I have a monthly subscription it will generate one payment task per month, if I have a weekly subscription it will generate a payment task each week.

For each new subscription created, I must generate all its payment tasks from today to 30 days in advance.

Subscriptions table provides the following values:

  • recurring_interval: day, month, year
  • recurring_interval_count: number. It defines the frequency: how many “recurring intervals”. For example, recurring interval: month, and recurring interval count: 2, means every 2 months.
  • anchor date or billing_cycle_anchor. The starting date for the subscription.

Example:

  • Recurring interval: week
  • Recurring interval count: 1
  • Anchor date: May 6th, 2025

This means that, if I’m creating that subscription today, May 6th, I must generate a Payment Task for each of these dates

  • May 6th, 2025
  • May 13th, 2025
  • May 20th, 2025
  • May 27th, 2025
  • June 3rd, 2025

The workflow must run when a new subscription is created.

This is part of my subscription’s table:

Why do you need to create future dates? Just check if it’s pass due.

Because my client needs to see all upcoming payments, not if they’re pass due.

You didn’t explain the purpose of it—is it to generate payment links or to inform the customer?

Neither, my client has a team that is in charge of making payments for others, they’re basically payment assistants. They must see all the upcoming payments so they can pay them in advance (where we live there are usually perks for paying earlier, and penalties for paying pass due)

How you wanna get these dates, in columns or JSON?

A JSON if possible to do an API Call later on. However if there is a way to generate multiple rows in a table, each one with a different date, without having to do an API Call, it would be great

function getWeeklyDatesInCurrentMonth(base_date_str) {
    const base_date = new Date(base_date_str);
    const currentMonth = new Date().getMonth();
    const currentYear = new Date().getFullYear();

    // Start from the later of base_date or first day of current month
    let current = new Date(base_date);
    if (current.getFullYear() < currentYear || (current.getFullYear() === currentYear && current.getMonth() < currentMonth)) {
        current = new Date(currentYear, currentMonth, 1);
        // Align to the next 7-day step from base_date
        const diffDays = Math.floor((current - base_date) / (1000 * 60 * 60 * 24));
        const offset = 7 - (diffDays % 7);
        current.setDate(current.getDate() + offset);
    }

    const dates = [];
    while (current.getMonth() === currentMonth && current.getFullYear() === currentYear) {
        dates.push(current.toISOString().split('T')[0]); // YYYY-MM-DD format
        current.setDate(current.getDate() + 7);
    }

    return JSON.stringify(dates);
}


return getWeeklyDatesInCurrentMonth(p1)

paste that in the JavaScript column, and add the date in the p1 argument, You can later generate rows from that JSON using a Glide helper table.

Thank you so much! I will be revising the code and adding it to my table

1 Like

If this solved your problem, please mark my answer as the solution.

I’m going to inspect the code first since it’s not taking into consideration the recurring interval and recurring interval count, which are essential to obtaining the dates (and also where my original code failed since the Javascript column didn’t allow me to use a switch case inside it)

Add extra variables and conditions to my code.

Had to support myself with AI since I was running out of time, but this is my final code (which is also the code that I started with, had to change some things that worked locally but not inside the Javascript Glide Column).

function getWeeklyDatesInCurrentMonth(anchorDateStr, recurringInterval, recurringIntervalCount) {
  
  // Convert strings to Date objects
  const parseDate = (dateStr) => {
    const [month, day, year] = dateStr.split('/').map(Number);
    return new Date(year, month - 1, day);
  };
  
  const anchorDate = parseDate(anchorDateStr);
  const today = new Date();
  const endDate = new Date();

  endDate.setDate(endDate.getDate() + 30);

  let paymentDates = [];
  
  // Calculate initial difference between today and anchor date
  let anchorDiff;
  switch(recurringInterval) {
    case 'days':
      anchorDiff = Math.floor((today - anchorDate) / (1000 * 60 * 60 * 24));
      break;
    case 'weeks':
      anchorDiff = Math.floor((today - anchorDate) / (1000 * 60 * 60 * 24 * 7));
      console.log('anchorDiff: ', anchorDiff)
      break;
    case 'months':
      anchorDiff = (today.getFullYear() - anchorDate.getFullYear()) * 12 + today.getMonth() - anchorDate.getMonth();
      break;
    case 'years':
      anchorDiff = today.getFullYear() - anchorDate.getFullYear();
      break;
    default:
      return []; // unknown interval
  }

   // Calculate how many intervals to add
  const dateToSum = Math.ceil(anchorDiff / recurringIntervalCount) * recurringIntervalCount;

  // Calculate days/months/years to add based on interval
  let daysToAdd = 0;
  let monthsToAdd = 0;
  let yearsToAdd = 0;
  
  switch(recurringInterval) {
    case 'days':
      daysToAdd = dateToSum;
      break;
    case 'weeks':
      daysToAdd = dateToSum * 7;
      break;
    case 'months':
      monthsToAdd = dateToSum;
      break;
    case 'years':
      yearsToAdd = dateToSum;
      break;
  }

// Calculate the next payment date
  let nextDate = new Date(anchorDate);
  nextDate.setFullYear(nextDate.getFullYear() + yearsToAdd);
  nextDate.setMonth(nextDate.getMonth() + monthsToAdd);
  nextDate.setDate(nextDate.getDate() + daysToAdd);

// Generate all payment dates within the 30-day window
    while (nextDate <= endDate) {
      if (nextDate >= today) {
        paymentDates.push(new Date(nextDate)); // Add to array if within window
      }
      
      // Calculate the next interval
      switch(recurringInterval) {
        case 'days':
          nextDate.setDate(nextDate.getDate() + recurringIntervalCount);
          break;
        case 'weeks':
          nextDate.setDate(nextDate.getDate() + (recurringIntervalCount * 7));
          break;
        case 'months':
          nextDate.setMonth(nextDate.getMonth() + recurringIntervalCount);
          // Handle month overflow (e.g., Jan 31 + 1 month)
          if (nextDate.getDate() !== anchorDate.getDate()) {
            nextDate.setDate(0); // Last day of previous month
          }
          break;
        case 'years':
          nextDate.setFullYear(nextDate.getFullYear() + recurringIntervalCount);
          break;
      }
  }

return JSON.stringify(paymentDates);
}

return getWeeklyDatesInCurrentMonth(p1, p2, p3)

with p1, p2 and p3 being the anchor date, recurring interval and recurring interval count respectively.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.