Showing repeater results for today's date and subsequent 30 days?

Hi Corvid Community!

I wondered if anyone could help with my coding problem which I imagine will appear rather trivial.

I have a dataset incorporating a bunch of sayings/quotes that have specific dates (‘month’ and ‘day of month’) attached to them. There is x1 ‘month number’ column (Field Key: monthNumber) and x1 ‘day of month’ column (Field Key: day) - both of field type: number. Each row therefore comprises a quote, month number and day of month number.

I want to display a repeater that shows the following:

  • the quote in dataset1 based on the date today (whichever day of the year ‘today’ happens to be)
  • the quotes in dataset1 for the subsequent 30 days after today’s date including when this extends
    into the following month.

Code so far:

import wixData from ‘wix-data’ ;
import wixWindow from ‘wix-window’ ;
let getDate = true ;

$w.onReady( async function () {

const today = new Date();
const day = today.getDate();
const month = today.getMonth();

$w( “#dataset1” ).onReady( async () => {
$w( “#dataset1” ).setFilter(wixData.filter()
.eq( “day” ,day) //“day” = field ID of month day in dataset1 with numeric property
.eq( “monthNumber” , month) //“monthNumber” = field ID of month number (Jan = 0) in dataset1 with numeric property
)

.then(() => {

let file = $w( “#dataset1” ).getCurrentItem();
})
. catch ((err) => {
console.log(err);
});

});
});

This code succeeds in filtering the database by today’s date however I can’t work out how to pull quotes for ‘today +1’, ‘today+2’ etc?

I tried the following:

$w( " #dataset1 " ).onReady( async () => {
$w( " #dataset1 " ).setFilter(wixData.filter()
.eq( “day” ,day)
.eq(“day”, day+2)
.eq(“day”, day+3)

BUT it didin’t work :frowning:

I then tried:

$w( " #dataset1 " ).onReady( async () => {
$w( " #dataset1 " ).setFilter(wixData.filter()
.eq( “day” ,day+2)

and this did pull the quotes from the date 2 days in the future BUT again I can’t display results for anything more than 1 single day.

I would be grateful if anyone might know a way to get the quotes for today AND the subsequent 30 days such that they all appear on the page simultaneously?

Many thanks in advance for any help offered.

Mark

Hi Mark,

Your challenge is indeed not trivial given that you are 1) not storing actual dates to the collection and 2) using a dataset filtering approach. The combination of the two makes this a vexing problem without a clear solution for what you are wanting it to do.

Thinking about this further since you posted this yesterday, there is a solution involving creating an array via wixData.query and using that to get the next 30 or however many days that you want to show.

import wixData from 'wix-data';
// initiate array so it's available in ShowQuotes method.
let quotes = [];

$w.onReady(function () {
    QuoteArray();
});

export function QuoteArray(){
 const today = new Date(); 
 const day = today.getDate(); 
 const month = today.getMonth(); 
 // create an array that will capture the quote records
 // for the current month and the next month, so the query 
 // result ends up being manageable.  Begin by getting an 
 // array in place for the hasSome function in the query.
 let months = [];
 months.push(month);
 // add 1 for next month unless December (11)
 let nextMonth = (month === 11) ? 0:month + 1;
 months.push(nextMonth);

  wixData.query("quotes")
    .hasSome("month", months)
    .limit(62)
    .find()
    .then((results) => {
      for (var i = 0; i < results.items.length; i++) {
        let item = results.items[i];
        let todayYear = today.getFullYear();
        let year = (month === 11) ? todayYear + 1:todayYear;
        let date = new Date(year,item.month,item.day,0,0,0);
            results.items[i].date = date.toDateString();
        }
        quotes = results.items;
    })
}

export function ShowQuotes(day,month,nextHowManyDays){
  let now = new Date();
  let year = now.getFullYear();
  let searchDate = new Date(year,month,day,0,0,0,0);
  let searchDateString = searchDate.toDateString();
  // get a simple array to search for the start point
  let dates = quotes.map(a => a.date);
  let startWith = dates.indexOf(searchDateString);
  let endsWith = startWith + nextHowManyDays;
  // an array to store those fitting the criteria
  let displayQuotes = [];
  for (var i = startWith; i < endsWith; i++) {
     displayQuotes.push(quotes[i]);
  }
  $w("#repeater1").data = displayQuotes;
}

Hi Anthony,

Amazing work! Your code is a little over my head I must admit.

I deleted my code and copied + pasted yours directly into the editor however it doesn’t yet seem to work as I’m getting a frustrating error saying:

“WDE0025: The Quotes collection does not exist. You cannot work with a collection using the Data API before it is created in the Editor”

This infers that it can’t find the quotes within the dataset right? The quotes are under field key: title in the database (somewhat silly of me not to have changed this to simply ‘quotes’ at the outset) but any idea how to fix this?

Also, I noted that you mentioned it would have been easier if I had logged the actual date format in dataset1. I’m happy to report that there is actually a column with the date in format Monday, July 13 (Field key: date, Field type: text) but I was having trouble getting my earlier code to recognise this (? due to the mix of numbers and letters) which is why I switched to numerically labelling day and month via separate columns.

Many thanks again

Mark

I have a similar collection named “quotes” where I display the quote of the day, that similarly has a month field and a day field and does not have a date field. That works well for the simple task of displaying the quote of the day.

All you need to do is substitute the name of the collection tied to your dataset.

I was hesitant to post this because it seemed that you are learning to code, but on the other hand, your post had not been responded to and I had a solution in mind.

So, all you really need to do to get this to work is to call the ShowQuotes function with the three parameters. To show the next 30 days (on July 13) would be the following:

ShowQuotes(13,6,30);

And … create an onItemReady function, that runs for each item (row) every time the data is assigned to the repeater, something like this:

export function repeater1_itemReady($item, itemData, index) {
    $item("#txtTopic").text = itemData.topic;
    $item("#txtPerson").text = itemData.person;
    $item("#txtDate").text = itemData.date;
    $item("#txtQuote").text = itemData.quote;
}

Hi Anthony,

Yes I’m definitely very new to this but thanks for taking the time to try and help me. It is all unimaginably nuanced!

I have now managed to get rid of the error code in relation to the collection (I had mistakenly used upper rather than lower case for my dataset name when substituted into the place where you had the word “quotes”).

I then put the following code in as I think you suggested:

$w.onReady( function () {
QuoteArray();
ShowQuotes( 13 , 6 , 30 )
});

Good news - I get a repeater showing quote results for consecutive days!

Bad news - It’s for the month of November rather than July and I get the error code (in Console log):

TypeError: e is undefined line 55

Line 55 is:
$w( “#repeater1” ).data = displayQuotes;

Also tried putting ShowQuotes (13,6,30) under the repeater function as follows :

$w( “#repeater1” ).data = displayQuotes;
ShowQuotes( 13 , 6 , 30 );
}

No TypeError with this however still getting quote results listed for November :frowning:

Have I still gone wrong somewhere?
(Note: there are no error messages/red dots within the code editor itself)

This November thing doesn’t conjure up anything as to what might be the issue. You better post your code and perhaps a screenshot of the collection from the content manager.

Regarding ShowQuotes, I wasn’t sure what your page looks like - whether or not you wanted to leave open ended how many quotes to display. If it’s always going to be 30 days, you could put it in this place in the QuoteArray function:

  wixData.query("quotes")
    .hasSome("month", months)
    .limit(62)
    .find()
    .then((results) => {
      for (var i = 0; i < results.items.length; i++) {
        let item = results.items[i];
        let todayYear = today.getFullYear();
        let year = (month === 11) ? todayYear + 1:todayYear;
        let date = new Date(year,item.month,item.day,0,0,0);
            results.items[i].date = date.toDateString();
        }
        quotes = results.items;
        ShowQuotes(day,month,30);
    })

So you know, the problem with the onReady code you attempted above was that the query hadn’t completed before ShowQuotes executes. In other words, the data is still being fetched from the server while the code continues to execute.

Doing it this other way, you are making sure that the the quotes array is fully populated before ShowQuotes runs.

Hi Anthony,

Thanks for the continued interest and for your explanation as regards the ShowQuotes and onReady code.

My current page code is:

import wixData from ‘wix-data’ ;
// initiate array so it’s available in ShowQuotes method.
let quotes = ;

$w.onReady( function () {
QuoteArray();

});

export function repeater1_itemReady($item, itemData, index) {
$item( “#txtTitle” ).text = itemData.title;
$item( “#txtHoliday” ).text = itemData.holiday;
$item( “#txtDate” ).text = itemData.date;
}

export function QuoteArray(){
const today = new Date();
const day = today.getDate();
const month = today.getMonth();
// create an array that will capture the quote records
// for the current month and the next month, so the query
// result ends up being manageable. Begin by getting an
// array in place for the hasSome function in the query.
let months = ;
months.push(month);
// add 1 for next month unless December (11)
let nextMonth = (month === 11 ) ? 0 :month + 1 ;
months.push(nextMonth);

wixData.query( “sloganistacollection” ) //collection ID
.hasSome( “month” , months)
.limit( 62 )
.find()
.then((results) => {
for ( var i = 0 ; i < results.items.length; i++) {
let item = results.items[i];
let todayYear = today.getFullYear();
let year = (month === 11 ) ? todayYear + 1 :todayYear;
let date = new Date(year,item.month,item.day, 0 , 0 , 0 );
results.items[i].date = date.toDateString();
}
quotes = results.items;
ShowQuotes(14,6, 30 );
});
}

export function ShowQuotes(day,month,nextHowManyDays){
let now = new Date();
let year = now.getFullYear();
let searchDate = new Date(year,month,day, 0 , 0 , 0 , 0 );
let searchDateString = searchDate.toDateString();
// get a simple array to search for the start point
let dates = quotes.map(a => a.date);
let startWith = dates.indexOf(searchDateString);
let endsWith = startWith + nextHowManyDays;
// an array to store those fitting the criteria
let displayQuotes = ;
for ( var i = startWith; i < endsWith; i++) {
displayQuotes.push(quotes[i]);
}
$w( “#repeater1” ).data = displayQuotes;

}

Collection/database pic:

Month with field key: month, field type: text
Month Number with field key: monthNumber, field type: numeric
Day with field key: day, field type: numeric
Date with field key: date, field type: text
Title with field key: title, field type:text
Holiday with field key: holiday, field type: text

This leads to the following repeater appearance when in preview mode:

As mentioned before, it strangely displays November hashtags which is a bit odd.

Any insights to get this working are much appreciated as always!

Mark

You are using the character month instead of the numeric month field.

Instead of

let date = new Date(year,item.month,item.day,0,0,0);

It should be

let date = new Date(year,item.monthNumber,item.day,0,0,0);

Well spotted Anthony! I’ve changed this now but despite a merciful gesture to the Gods as I hit preview, the repeater still looks the same :persevere::disappointed_relieved:

Maybe it’s just not meant to be but thanks so much for your best efforts in any event.

Could you post a screen shot of the July portion of the collection?

Sure, no problem.

The naming of the new property “date” is the same as one of the field names in the collection (and the resulting results.items array). It needs to be named something different.

 results.items[i].newdate = date.toDateString();        

Also, this line in ShowQuotes needs to be changed to correspond with the above change:

let dates = quotes.map(a => a.newdate);

It’s getting there.

Made those changes Anthony but still the same repeater appearance. Here is the code I now have in the editor:

import wixData from ‘wix-data’ ;
// initiate array so it’s available in ShowQuotes method.
let quotes = ;

$w.onReady( function () {
QuoteArray();

});

export function repeater1_itemReady($item, itemData, index) {
$item( “#txtTitle” ).text = itemData.title;
$item( “#txtHoliday” ).text = itemData.holiday;
$item( “#txtDate” ).text = itemData.date;
}

export function QuoteArray(){
const today = new Date();
const day = today.getDate();
const month = today.getMonth();
// create an array that will capture the quote records
// for the current month and the next month, so the query
// result ends up being manageable. Begin by getting an
// array in place for the hasSome function in the query.
let months = ;
months.push(month);
// add 1 for next month unless December (11)
let nextMonth = (month === 11 ) ? 0 :month + 1 ;
months.push(nextMonth);

wixData.query( “sloganistacollection” )
.hasSome( “month” , months)
.limit( 62 )
.find()
.then((results) => {
for ( var i = 0 ; i < results.items.length; i++) {
let item = results.items[i];
let todayYear = today.getFullYear();
let year = (month === 11 ) ? todayYear + 1 :todayYear;
let date = new Date(year,item.monthNumber,item.day, 0 , 0 , 0 );
results.items[i].newdate = date.toDateString();
}
quotes = results.items;
ShowQuotes(14,6, 30 );
});
}

export function ShowQuotes(day,month,nextHowManyDays){
let now = new Date();
let year = now.getFullYear();
let searchDate = new Date(year,month,day, 0 , 0 , 0 , 0 );
let searchDateString = searchDate.toDateString();
// get a simple array to search for the start point
let dates = quotes.map(a => a.newdate);
let startWith = dates.indexOf(searchDateString);
let endsWith = startWith + nextHowManyDays;
// an array to store those fitting the criteria
let displayQuotes = ;
for ( var i = startWith; i < endsWith; i++) {
displayQuotes.push(quotes[i]);
}
$w( “#repeater1” ).data = displayQuotes;

}

Leading to repeater appearance:

The itemReady code needed to be modified too:

$item("#txtDate").text = itemData.newDate;

Change made Anthony but still the same appearance of repeater :frowning:

Maybe you need to make sure the repeater and its elements are disconnected from the dataset.

I’ve just checked to see if that helps but sadly it just displays the original repeater that was brought in from the ‘add’ menu when not connected to data.

I’m going to leave it there for tonight but thanks again for your efforts Anthony! I suspect we must be close…

That would suggest that it’s not making it to the line where the repeater is assigned the data.

So we take nothing for granted, put some console.logs following lines in a couple places in the QuoteArray function:

  .then((results) => {
 	console.log(results);
quotes = results.items;
console.log(quotes);

And before this line in the ShowQuotes function:

console.log(displayQuotes);
 $w("#repeater1").data = displayQuotes;

In the developer console at the bottom, there should be three ellipsis buttons. Expand them and take a screen shot.

The original posted code works flawlessly with the collection in my database. It has been tested, in other words. There’s still something not quite right with fitting it into your situation.

Also, I’m wondering if you added the itemReady function from the property sheet? If you just copied and pasted the code, it’s not “registered” with Corvid and will not run.

Hi Anthony,

I have indeed ensured that #repeater1 is connected via onitemReady function (in the properties panel) to the code in the editor rather than just pasting the code into the editor (which admittedly I had done at first).

Here is a screenshot of the developer console with those console.log lines added and without any connection to data :

Here is a screenshot of the developer console with console.log lines added and with connection to data:

Good, we’re getting somewhere. The query hasn’t been returning anything. One more console.log so I know what’s happening with the months array:

months.push(nextMonth);
console.log(months);