I'm a bit new to Vue and was wondering how to get the the past month date: I have this code:
import SomeTable from "./table/SomeTable";
export default {
name: "Cabinets",
components: {SomeTable},
data() {
return {
defaultColumns: [
'id',
'serialNumber'
],
defaultStartDate: new Date(),
defaultEndDate: new Date('2019-10-07')
}
},
props: {
startDate: {type: Date, required: false},
endDate: {type: Date, required: false},
}
}
</script>
And then I put defaultStartDate and defaultEndDate in the SomeTable element as follows:
<some-table :start-date="defaultStartDate" :end-date="defaultEndDate" :default-columns="defaultColumns"></some-table>
Which then returns the correct startDate of today and also the set one. But when i try for instance to do something like this:
defaultEndDate: new Date().getFullYear() + '-' + new Date().getMonth() + '-' + new Date().getDate()
My local environment turns blank and get all sorts of errors. I think this is due to the fact I can't use Javascript in that place in Vue? But again I'm really not yet sure how Vue works and couldn't find much on it by googling. So how could I do this using Javascript or maybe even if Vue has a neat trick for it?
EDIT:
the errors i'm getting are of the form:
Error in data(): "TypeError: Date().getFullYear is not a function"
But then with all the javascript functions i used inside Vue. And also
Invalid prop: type check failed for prop "endDate". Expected Date, got String with value "2019-9-5".
In your codes, endDate: {type: Date, required: false}, means endDate should be in Date type.
So you need to convert calculated value into Date like below:
defaultEndDate: new Date(`${(new Date()).getFullYear()}-${(new Date()).getMonth()}-${(new Date()).getDate()}`)
EDIT:
And you need to think of the month is January(0). By using the above method, you will get error when it is on January.
I think It could be better to use computed value like below;
computed: {
defaultEndDate() {
const now = new Date();
now.setMonth(now.getMonth() - 1);
return new Date(now.toJSON().slice(0, 10));
}
}
Related
Building a rental listing application using MERN stack. My Listing model is below:
const listingShcema = new mongoose.Schema(
{
hostedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
title: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
numberOfGuests: {
type: String,
required: true,
},
numberOfRooms: {
type: String,
required: true,
},
numberOfBeds: {
type: String,
required: true,
},
numberOfBaths: {
type: String,
required: true,
},
price: {
type: String,
requried: true,
},
location: {
streetAddress: { type: String },
city: { type: String },
state: { type: String },
postalCode: { type: String },
},
bookedDates: [
{
startDate: Date,
endDate: Date,
},
],
imgUrls: [
{
type: String,
},
],
amenities: [
{
type: String,
},
],
},
{ timestamps: true }
);
Now it is fairly easy to run queries on everything given by the users search query except for the dates they want to rent out. The listing model keeps track of all bookedDates. I want to be able search the mongodb for Listings that do not have bookedDates that match the dates supplied by the users search query (showing available listings to the user). I can't think of a way to do this?? I figured it is easy keeping track of only the booked dates instead of taking away booked dates from an array of all available dates.
Doing this directly in the DB is kind of awkward, especially if you're only storing the startDate and endDate for each booking. For example, if someone books a listing from the 1st to the 5th - if another user is searching for the same listing from the 3rd to the 7th, it doesn't match the booking saved, but the listing wouldn't still be counted as available.
I'd suggest taking another look at your model and perhaps even separating out the booked dates to their own documents.
But, keeping with what you have, assuming you're not booking too far in the future, it might be worth storing the bookedDates as a flat array. So if we have a listing booked from the 1st to the 3rd, and the 6th to the 8th, your array would look like this:
bookedDates: [
'2021-01-01',
'2021-01-02',
'2021-01-03',
'2021-01-06',
'2021-01-07',
'2021-01-08'
]
Then, if someone searches for the listing between the 2nd and 4th, you'd again break down those dates into a flat array, and then you should be able to use the $nin operator (https://docs.mongodb.com/manual/reference/operator/query/nin/):
const desiredDates = [
'2021-01-02',
'2021-01-03',
'2021-01-04'
]
Listing.find({ bookedDates: { $nin: desiredDates } })
To quote the relevant part of the page:
If the field holds an array, then the $nin operator selects the documents whose field holds an array with no element equal to a value in the specified array (e.g. , , etc.).
This is obviously going to work best if you have another way to filter out the majority of your listings, so your not doing an array-array check for every listing in your database.
You'll also have to keep bookedDates up-to-date by removing past dates.
Another option is just to query your listings and do the date filtering at the application level, in which case, you can probably keep the startDate and endDate format that you have.
Update for flattening dates
Something like this should work. I just brute force it - people are generally only going to book a listing for a few days mostly, so your loop is going to be quite small. There are some checks in there if it's for one day, and to make sure the start is before the end, but that's about it.
As a method, you can call it whenever you want, and it'll split two dates into a flattened string array in yyyy-mm-dd format
function getFlattenedDatesAr(inputStart, inputEnd) {
// convert to dates and make sure that start is before end
let startDate = new Date(inputStart)
let endDate = new Date(inputEnd)
if(startDate > endDate) {
let temp = startDate;
startDate = endDate;
endDate = temp;
}
// get our dates in yyyy-mm-dd format
const startDateStr = startDate.toISOString().substr(0, 10)
const endDateStr = endDate.toISOString().substr(0, 10)
// check if they've only booked for one day
if(startDateStr === endDateStr) {
return [startDateStr];
return;
}
// fill our our dates array
const bookedDates = [startDateStr]
let currDate = startDate;
while(true) {
// NOTE: setDate returns a timestamp, not a Date
const nextDateTS = currDate.setDate(currDate.getDate() + 1);
// get our date string and add it to our bookedDates array
currDate = new Date(nextDateTS)
const currDateStr = currDate.toISOString().substr(0, 10);
bookedDates.push(currDateStr);
// if our string matches our end date, we're done
if(currDateStr === endDateStr) {
break
}
}
return bookedDates
}
// assume these are the dates sent, in yyyy-mm-dd format
let inputStart = '2021-01-01'
let inputEnd = '2021-01-05'
const datesAr = getFlattenedDatesAr(inputStart, inputEnd)
console.log(datesAr);
I am declaring dateRangePicker field in component state like below
dateRangePicker: {
selection: {
startDate: new Date(),
endDate: new Date(),
key: 'selection',
},
}
later start date and end date changes as below
let startDate = "2019-04-16";
let endDate = "2019-05-16";
But, I am not able to update these value in state after following code block
this.setState({
dateRangePicker.selection.startDate : startDate,
dateRangePicker.selection.endDate : endDate,
})
I want to update the start and end date accordingly
It doesn't work the way you showed. It should be like this:
this.setState(ps=>({
...ps,
dateRangePicker:{
...ps.dateRangePicker, // Copy old data
selection: {
...ps.dateRangePicker.selection, // Same here
startDate: startDate
endDate: endDate
},
}
}))
We use functional form of setState, because you can see at one point we access data from previous state: ps.selection
what your'e tryin to acheive is to change the state of a deep/nested
object in setState..
const startDT = "new start date"
const endDT = "new end date"
this.setState(prevState => ({
...prevState,
dateRangePicker: {
...prevState.dateRangePicker,
selection: {
...prevState.dateRangePicker.selection,
startDate: prevState.startDate = startDT,
endDate: prevState.endDate = endDT,
}
}})
)
Or,
// copy without reference..
const dateRangePicker = { ...this.state.dateRangePicker }
dateRangePicker.selection = {
startDate: startDT,
endDate: endDT,
}
this.setState({ dateRangePicker })
The state is a immutable object, so you can not modified it, but create a new one, so using spread ... expression to create a new state.
I'm getting frequent errors when i start my server. Here is the error:
RangeError: Invalid time value
at Date.toISOString ()
Here is the code:
var start = timestamp;
const expiryDate = (new Date(start)).toISOString().split('T')[0];
This exception occurs when the Date object contains an invalid date.
new Date('undefined').toISOString()
In this example the Date object can be created without any problems, but the toISOString function throws an Error.
To fix your issue, you need to make sure that the timestamp variable contains a valid date string.
In my case endDate had a null value:
const [date, setDate] = useState([
{
startDate: new Date(),
endDate: null,
key: "selection",
},
]);
Changing it to new Date() solved the issue:
const [date, setDate] = useState([
{
startDate: new Date(),
endDate: new Date(),
key: "selection",
},
]);
In my case I had previously used JSON.stringify() on an object Task with an attribute duedate of type Date. Consequently taskObj.duedate became a string and did not work as a Date object in my code.
To fix the error, I converted the stringified date to Date type using taskObj.duedate = new Date(taskObj.duedate);
I have dates as date objects.
When i do this
$scope.test = new Date([2017,2,15]);
<pre>{{test}}</pre>
<pre>{{test.getDate()}}</pre>
I get
"2017-02-14T23:00:00.000Z" and 15
So up to here, we are good.
But in my case, when I try to do the same with a date whitch is in another object like in this schema :
var tachesSchema = new mongoose.Schema({
title : String,
start: {type: Date, default: new Date()},
end: {type: Date, default: new Date()},
comment : String,
state : Boolean,
projet : { type: ObjectId, ref: 'Projets' }
});
I get nothing :(
This code :
{{tache.start}}
displays the date like this "2017-02-20T23:00:00.000Z"
but
<pre>{{tache.start.getDate()}}</pre>
displays nothing.
What I missed ?
EDIT
I've omitted to precise that I want to do this in a ng-repeat
The code below give me dates like "2017-02-20T23:00:00.000Z"
<pre ng-repeat="tache in taches">
{{tache.start}}
</pre>
The code below give me nothing
<pre ng-repeat="tache in taches">
{{tache.start.getDay()}}
</pre>
try
{{tachesSchema.start.getDate()}}
You can define a default with a function:
new Schema({
date: { type: Date, default: Date.now }
})
See docs here.
You are getting "String" value when you try {{tache.start}}. You should convert it to Date object (new Date("2017-02-20T23:00:00.000Z")) and try getDate() method.
OR try below:
new Schema({
date: { type: Date, default: '15/02/2017' }
});'
I have a collection which has a field called timestamp containing date object. I have this query:
db.articles.find({
timestamp:{
'$lte':new Date(),
'$gte': //Something to get the last week's date
}
})
Also if it is possible, Can I sort these returned documents by length of an array in this document. Here is the schema:
section: String,
title: String,
abstract: String,
url: String,
image: {
url: String,
caption: String
},
votes:{
up: [ObjectID],
down: [ObjectID]
},
comments:[ObjectID],
timestamp: Date
I want to sort the returned objects by size of difference of votes.up and votes.down. Right now I am sorting the returned objects in Javascript where this actually returns the data.
Seems the solution should look like
db.articles.find({
timestamp: {
$gte: new Date(new Date() - 7 * 60 * 60 * 24 * 1000)
}
});
it will return the previous week data i.e.,from sunday to saturday of previous week which is local where sunday is a starting day.
{
$match: {
createdAt: {
$gte: moment().day(-7).toDate(),
$lt: moment().startOf('week').toDate()
},
}
}
]);
I found a solution get the objects created in last week.
db.articles.find({timestamp:{'$lte':new Date(),'$gte':new Date(Date()-7)}})
This gets the work done. But I cant figure out how to sort the returned objects by the size of arrays.