WixDataQuery on Date Fields not returning expected results

I have a promotions page that queries a Promotions collection looking for all promotions for a particular store that are (.gt) the promotionStartDate and (.lt) the promotionEndDate. I am only getting results returned if I only use one parameter - . lt ( “promotionEndDate” , localDate ) . If I query using both . gt ( “promotionStartDate” , localDate ) and . lt ( “promotionEndDate” , localDate ) , as I have it in my code below, no results are returned.

I have been stuck on this all day. I’m sure it is a dumb mistake - any help would be appreciated! Thank you!

Here is my query:

const localDate = new Date (). toLocaleDateString ( ‘en-us’ , { year : “numeric” , month : “short” , day : “numeric” })

console . log ( "localDate: " , localDate );

wixData . query ( “Promotions” )
. eq ( “store” , storeId )
. gt ( “promotionStartDate” , localDate )
. lt ( “promotionEndDate” , localDate )
. ascending ( “promotionEndDate” )
. limit ( 20 )
. find ()
. then ( ( results ) => {
console . log ( “results: " , results );
if ( results . items . length > 0 ) {
//$w(”#boxPromotions").expand();
$w ( “#repeaterPromotions” ). expand ();
$w ( “#repeaterPromotions” ). data = results . items ;
} else {
$w ( “#textNoPromotions” ). show ();
}

} ); 

}

Hi, instead of converting your local date to string try to just use it as date data type.

Try replacing

const localDate=new Date().toLocaleDateString('en-us', {year:"numeric",month:"short",day:"numeric"})

With

const localDate=new Date()

Thank you so much for responding, Qu4dri. I tried changing the data type but no luck. Do you happen to have any other ideas that I can try? Thank you so much!

Could you comment out the .gt and .lt of your query and provide the output of the console? Please expand the console 'results ’ object > items > [0]

Thank you again for your response!

I have commented out .gt and .lt and here are the console results:

localDate: Wed May 17 2023 17:24:19 GMT-0400 (Eastern Daylight Time)
load promotion results:
{…}jsonTableCopy JSON
_items: Array(1)jsonTableCopy JSON
0: {…}jsonTableCopy JSON
name: “Save 35% on Trampolines”
url: “https://springfree-trampoline.pxf.io/c/2592818/1681858/18258
_id: “fbbbad00-96b7-45e4-bf83-722a5b675d56”
_owner: “f164eb40-361c-438f-9545-655f425d51ed”
_createdDate: “Mon May 15 2023 10:33:52 GMT-0400 (Eastern Daylight Time)”
store: “56b4493d-2b01-4d8c-b651-5bc3a35e5153”
_updatedDate: “Mon May 15 2023 16:52:02 GMT-0400 (Eastern Daylight Time)”
promotionEndDate: “2023-07-07”
status: “”
promotionStartDate: “2023-05-09”
type: “Product Discount”
_totalCount: 1
_cursors: “undefined”
_createdByCursor: “undefined”
_query: {…}
_partialIncludes: false
_pagingFunction: “function(){return this.find(t)}”
_hasExtraItem: false
nextSkipNumber: 1
prevSkipNumber: -20
totalCount: 1

Thank you so much for your help!

Hi, it seems like your dates are somehow saved as text and not as date objects.
Inside the collection try to click on the promotions start/end date and manually pick the date using the interface. After this for example in your console the promotionStartDate should have a similar format as the _updatedDate just above instead of a normal text string.

If you get the fields to be of type Date instead of string, it would be easy to use the .gt and .lt in the query.

so strange…here a screen shot of the collection:


Would you recommend recreating the table? Is there any easy way to do that?

I maybe know now.
try to use date and times fields, instead of just date.

The alternative would be to parse the date string and manually filter the results.

No luck with the date and time fields. In fact, in testing, I cannot get a query to successfully run using just:

const localDate = new Date ()

and

. lt ( “promotionEndDate” , localDate )

I have only been successful converting the date to a string and then running against a date placed in a text field. But that seems to only be working for one parameter - not both .lt and .gt.

Thank you so much for your time. I will keep working on it and let you know if I come up with anything.

Thank you!

Just an update…after recreating the collection and setting up the date field with the time, I was able to run the query using const localDate = new Date () and return results with one parameter.

But, I am still not able to chain both .lt and.gt.

Hi, i found a solution, using both DateTime and Date data types.

I quickly simulated the dataset you’re using as follows:

To show you the differences with both method I have columns for the dates with or without time.

Here is the page code I use to query the promotions:

import wixData from 'wix-data';
$w.onReady(async function () {
    console.log('Get promotions with date and time')
    await getPromotionsWithDateTimeField()
    console.log('Get promotions only with date')
    await getPromotionsOnlyDate()
})

async function getPromotionsWithDateTimeField() {
    //Get user current local date
    let today = new Date()
    //Create array of objects with active promotions
    let activePromotions = await wixData.query('Promotions')
        .lt('promotionStartTimeDate', today)
        .gt('promotionEndTimeDate', today)
        .find().then((results) => { return results.items })
    //Print in the console the promotion details
    if (activePromotions.length > 0) {
        console.log('Active promotions:')
        for (let promotion of activePromotions) {
            console.log(promotion)
        }
    }
    //Do other stuff
}

async function getPromotionsOnlyDate() {
    //query all promotions
    let allPromotions = await wixData.query('Promotions').find().then((results) => { return results.items })
    //filter all promotions to get just the active promotions
    let activePromotions = allPromotions.filter((promotion) => {
        let today = new Date()
        let startDate = new Date(promotion.promotionStartDate)
        let endDate = new Date(promotion.promotionEndDate)
        return (startDate < today && today < endDate)
    })
    //Print in the console the promotion details
    if (activePromotions.length > 0) {
        console.log('Active promotions:')
        for (let promotion of activePromotions) {
            console.log(promotion)
        }
    }
    //Do other stuff
}

Pay attention about few things:

  • In the first function the .lt is assigned to the Starting date, and the .gt to the Ending date. (Which I understand is a bit misleading)

  • The result (activePromotions) is already a list of promotion objects containing only the active ones.

  • In the second function the date is in string format in the dataset, for this reason a manual filtering is needed as is not possible to compare a string with a date format.

  • The filter just creates date types from the string, which can be compared with a normal boolean operations.

The console output if you want to compare:

One more thing, be sure that your .eq(“store”,storeId) in your query is not filtering the results you want to obtain.

Let me know if it works :smiley:

Thank you so much, Qu4dri ! It works perfectly. I really appreciate you taking the time to break it down for me and explain. I have been stuck on this for days! I cannot thank you enough :slight_smile:

I’m not sure how but you can set it as best answer and set the question as solved.

Have fun with coding :smiley:

Thanks again for your help!