Filter set based on date comparison

Hello,
I have a dynamic dataset (called promoDS) bound to a promotions page and the dataset SpecialPromotions. The dataset needs to be filtered based on two fields of type DATE for each promotion: StartDate and EndDate. The documentation claims dates are compared using .gt and .lt as standard javascript date objects.
The result should populate a repeater object on the promotions page but fails to do so, even though the setfilter calls seem not to have failed. The code I attempted and tested is below. I have also tried this with var n = Date.now() just to see if that is the problem. Maybe I shouldn’t be setting the filter on the onReady function? Any help is greatly appreciated.

import wixData from ‘wix-data’;

$w.onReady(function () {
//TODO: write your page related code here…
var n = new Date();
$w(“#promoDS”).setFilter(wixData.filter()
.lt(“StartDate”, n)
)
.then(() => {
console.log(“Filter1 is applied”);
})
.catch((err) => {
console.log(err);
});
$w(“#promoDS”).setFilter(wixData.filter()
.gt(“EndDate”, n)
)
.then(() => {
console.log(“Filter 2 is applied”);
})
.catch((err) => {
console.log(err);
});

});

I left something out in my description: without the filters applied, two records are correctly bound to the repeater and displayed. When the filters are run, no records appear.

Hi Robin,

I believe you need to chain your conditions. Something like this:

.lt("StartDate", n)
.or (
   .gt("EndDate", n);
)

Yisrael

Hi Robin, your setting the repeater filter twice. So the second would be applied. It would be more something like this

$w("#promoDS").setFilter(wixData.filter()
     .lt("StartDate", n) 
     .gt("EndDate", n)
)

Naturally, if ‘StartDate’ and ‘EndDate’ are datetime, n may need to be too. Above is the ‘AND’ situation.

Yisrael was just quicker :slight_smile:

Hey Edgar,

And that was waaaaaay after my morning coffee :slight_smile:

The problem with the and condition is that there won’t be a date that is both less than the start and greater than the end. That’s why I used an .or() . The problem is, I’m not sure what exactly Robin wants so we can both say we’re right. :beers:

Yisrael

Then i should be clear - I want to see the records where the StartDate in the record before the current date and the EndDate date is after the current date. I want those records included, not filtered out.

So something like StartDate < currentDate < EndDate which in text would be ‘in progress’. is your start and end date always filled? Maybe my example replacing ‘n’ with new Date will work. “new Date” is javascript for current datetime. I haven’t a table currently to try it my self I can make adapt my own data tomorrow though.

I’m new to this forum and so I don’t even see where I can respond directly to a comment. Anyway, I think my problem is I’m just getting used to javascript syntax and operators and wix after not having programmed for 10 years. Edgar’s comment looks like pseudocode to me. Yes, logically startDate < n(or currentdate) < endDate would get me what I want and that is what I was trying to do with using two filters, since I was unsure of any other syntax that would work more simply and logically inside the setfilter call. At any rate, though nothing yet said has really produced a result, I’m thankful for all your comments, since they have given me ideas. Also, if someone has a “working” snippet of wixcode that shows a filter using the .or operator, I’d love to see it. Thanks to all.

Ok, based on what I’ve read, it seems that Yisrael’s suggestion ought to work. The following code executes without error, however it yields an emptry date set. The dates in the records are set correctly. Here is what I have:

import wixData from ‘wix-data’;
let n = new Date();
$w.onReady(function () {
$w(“#promoDS”).setFilter(wixData.filter()
.lt(“StartDate”, n)
.or(wixData.filter()
.gt(“EndDate”, n)
)
)
.then(() => {
console.log(“Dataset is now filtered”);
})
.catch((err) => {
console.log(err);
});
});

Robin,

You need to chain your conditions, and you need to “apply” the or like this:

.lt("StartDate", n)
.or(
    .gt("EndDate", n)
)

Yisrael

It’s early morning in Prague where I live. I will try your idea in the morning but i don’t see in the api where wixData.filter() takes a parameter. Thanks, Robin

Hey Robin,

Sorry - No idea what happened, but the code got messed up. I fixed it in my original post, but here it is again - hopefully correct this time - .or takes the parameter.

.lt("StartDate", n)
.or(
    .gt("EndDate", n)
)

(I was in Prague about a year ago - beautiful city!)

Yisrael, it looks like in your code the “.gt(“EndDate”,n)” statement has lost it’s needed context of belonging to the wixdataFilter() call (governing the .lt(“StartDate”, n) statement and consequently gets an unexpected token syntax error. Maybe you meant

wixData.filter().lt(“StartDate”, n)
.or(
wixData.filter().gt(“EndDate”, n) )

I did try this and there was no syntax error, but also no records filtered. So using this code above, I first created the filter and then inserted it. So below is a console.log printout of the filter(s) that that the code above inserted. I am at a bit of a loss as to how to interpet it given all the nesting. Is it possible I need to clear all the filters out before doing this?

{“filterTree”:{“$and”:[{“$or”:[{“$and”:[{“StartDate”:{“$lt”:“2018-01-22T12:02:17.664Z”}}]},{“$and”:[{“EndDate”:{“$gt”:“2018-01-22T12:02:17.664Z”}}]}]}]},“invalidArguments”:[]}

What is the data of your two rows, can you make a screenshot of them? You mention you have two test rows appearing with no filter. If the date gt and lt filter works like ‘contains’ and ‘hassome’ then it will hide rows where the column being compared is empty. No value is not smaller or larger. If your test record for startdate has no enddate that translates to hide it for the enddate filter. If the enddate test row has no startdate value it will hide it for the startdate filter. This would mean your filter works :slight_smile:

Thanks for asking for that. Both records have StartDate and EndDate and only the 2nd one fulfills the requirement that it be within the range my filter intends. And I think therefore that my filter somehow doesn’t work, but who knows?

Now I’m beginning to wonder whether either my database is broken or if setting filters on dynamic datasets from callbacks (i.e. here the page’s onReady callback) simply doesn’t work. I have tried some simple tests of creating a boolean field in the database table and testing that in a filter. if I create the filter directly in the dynamicdataset manager, it works fine, but if I do via code in the onReady callback, it executes without error, but all the records are filtered out. To be sure, my dataset has two records, one with “Active” (the new boolean field i added) set to true, and the other with it set to false. I tried a similiar simple test on another table with a dynamic page and a repeater and that fails too. Either I am stupid, or there is something else going on here that is not kosher.

Hey Robin,

Sorry you’re having so much trouble. I will try my best to play around with this and figure out how things work. I’ll get back to you as soon as I can.

Yisrael

Thanks so much Yisrael, it is a bit frustrating. But if you figure it out then the next time you come to Prague I’ll take you on my private tour of city :slight_smile:

Hi Robin. What is your exact onReady code for the boolean test? I trried this snippit. Watch, out the syntax is not equal to the docs I’m not passing a string to the boolean field

import wixData from 'wix-data';
$w.onReady(function () {
	$w("#dsBooleanChk").onReady( () => {
		if ($w("#chk1").checked) {
			$w("#dsBooleanChk").setFilter(wixData.filter().eq("field_boolean", true))
		}
	});
});

Hey Edgar,

Excellent - there is onReady() and there is onReady(). I was just going to point out to Robin that the onReady() that “counts” is that of the dataset. After all, it might be that the page is ready, but the dataset isn’t.

Good point and thanks for pointing this out. I’m going to keep playing with this since this has piqued my curiosity. But I hope Robin gets back and say it works so I don’t have to break my head.

Yisrael