How to use the current date/time in an API call? - javascript

I have a test that makes an API call, and a required part of the body that I'm passing in is a timestamp. The whole test is working except for this last piece (if I manually set the date/time before each test execution the test succeeds).
I have been trying to set a variable like this:
const todaysDate = Cypress.moment().format('YYYY-MM-DDTHH:MM:SS-07:00');
but I cannot figure out how to use this in the API call. The API parameter is formatted as such:
"offDateTime": "YYYY-MM-DDTHH:MM:SS-07:00"
Can anyone help me out?

Well I would say just adapt the given parameter according to the api's needs.
const todaysDate = Cypress.moment().format('YYYY-MM-DDTHH:MM:SS-07:00');
How to use in the API Call depends on how you create your call and what the concrete requirements in your case are. As your API use some kind of JSON to run, it usually might look something like this.
const date = new Date();
const timestamp = date.getTime();
const publicKey = '<publickey>';
const privateKey = '<privateKey>'
cy.request(`/v1/public/orders?ts=${timestamp}&apikey=${publicKey}&hash=${hash}`)
.then((response) => {
expect(response.body).to.have.property('offDateTime', todaysDate )
})
This snipplet would state a request to an existing File on your baseUrl or an explicit given url, using -cv.visit(url). If file referres to baseUrl from your cypress.json configuration file, that url would be [baseUrl]/v1/public/orders. The rest is like you would have set an AJAX request to this file, you'll get the response form the file and can try to catch if the expected values are in.

To retrieve a future date, you can easily relay on moment.js cypress includes automatically.
Quick example how to add future dates:
var twoDaysForward = new Cypress.moment().add(2, 'day');
document.write(twoDaysForward.format('YYYY-MM-DDTHH:MM:SS-07:00');
Same works with minutes
twoDaysForward.add(minutes, 'minutes');

Related

Dialogflow: Is this being used in an async call

I'm new to the javascript world and have been tinkering with Actions on Google. I had an action that was previously running but after attempting to simplify my code, I've been running into a new error I cannot seem to figure out. The code is supposed to make a call to a database and return information to the user based on the date they have selected.
Problem:
The code is supposed to make a call to a database and return information to the user based on the date they have selected. The intent seems to break down when I call the URL using axios. When I test my function I receive the following error from the Google Cloud Platform: "Error: No response has been set. Is this being used in an async call that was not returned as a promise to the intent handler?"
app.intent('Moon', (conv, {date}) => {
// Sets date to today if none given
if (!date) {
date = new Date().toISOString();
}
// Slices date string to match date format in database
const dateSlice = date.slice(5, 9);
// Call to row in dabase for the given date
function getData() {
return axios.get(`example.com/search?Date=${dateSlice}`);
}
return getData().then(res => {
res.data.map(con => {
conv.ask(`On X date there will be a ${con.Object1}`);
});
});
});
I don't know much about Promise and await but that seems to be the issue. I'm not sure how I was able to get my code to run before without these objects. I've tried to insert a Promise object before my return but it makes the rest of the function unreachable. I also checked to see if Axios had any updates but it has not, I am on the latest version. Does the error have to do with one of the returns perhaps?
It could be related to Promises, but you seem to be handling them correctly.
The call to axios.get() is returning a Promise...
... which you are returning in getData()...
... which is returned in the 'Moon' Intent handler as part of the getData().then() block.
I suspect more that this is a logic problem. If res.data is an empty array, then there will be no calls to conv.ask(), so you end up not asking anything.
There is also a problem if res.data has more than two items. In this case, you'll generate an error because you've replied with more than two "simple" responses.
Either way - you may wish to log res and/or res.data to make sure you're getting back what you think.

Server timestamp using firebase

I am working on a review/comment process and would like to be able to store each review/comment given by a user for another one in firebase, with each review/rating given at the same time being under the same timestamp. I was using the JS function new Date().getTime() initially, and this works fine, but to ensure that users can't tamper with the value (ie by changing the date on their computer) I would like to use firebase timestamp instead.
Now, I want the end product to be a map:
[chatStartTime] : {
review : stars,
time : chatStartTime
}
Which I then incorporate into a firebase document using transaction.set(). Now the issue is the ChatStartTime, which is supposed to represent this timestamp. I have the code:
var chatStartTime = firebase.firestore.FieldValue.serverTimestamp();
As an aside, I am also hoping to get:
var chatStartTimeDate = chatStartTime.toDate();
However chatStartTimeDate leads to an error – my understanding is that this is because chatStartTime is essentially "void" until it is added to a document; is there any way to get around this and use this function? Also, if I just use chatStartTime for both instances, I end up with a map on the database of the form:
[object Object]
review : 4.5
time :
.sv: "timestamp"
Where .sv is a string type. How can I solve this issue? I'd like the end result to look something like (for example)
1579194722735
review : 4.5
time : 1579194722735
The FieldValue.serverTimestamp() value is written on the server at time of write. So you can't get it before the write happens. However, you can get the writeTime from the response. This should give you what you're after. Alternately, you could read the document back out after you write it to fetch the timestamp (but that seems unnecessary).
myCollection
.doc('foo')
.create({ timestamp: FirebaseFirestore.FieldValue.serverTimestamp() })
.then(result => {
const serverTime: Date = result.writeTime.toDate();
});

How do I get user's local date and time in RESTful app with Spring MVC

I have a app where the user is able to perform actions, but only once and if his local time is before noon. The question is how can I retrieve this from user?
Say I have a method in the controller like this:
#PostMapping(value = "/performaction")
public void performIt()
{
if(/*somehow getHour()*/ < 12)
{
perform();
}
else reject();
}
I know that JS can help out, by calling var date = new Date() I can retrieve it, but I don't have any JSP pages to put this code and get locals. The service is completely REST with plain text. How can I do that?
you can use java8's LocalTime.now() and do compare like this
LocalTime currentTime = LocalTime.now();
LocalTime noon= LocalTime.of(12, 0);
if(currentTime.isBefore(noon){
}
Get the time stamp from the server itself if you can ignore the network time in your use-case.

Cache HTML using request-promise and Node.js

I'm looking for a simple way to cache HTML that I pull using the request-promise library.
The way I've done this in the past is specify a time-to-live say one day. Then I take the parameters passed into request and I hash them. Then whenever a request is made I save the HTML contents on the file-system in a specific folder and name the file the name of the hash and the unix timestamp. Then when a request is made for the using the same parameters I check if the cache is still relevant via timestamp and pull it or make a new request.
Is there any library that can help with this that can wrap around request? Does request have a method of doing this natively?
I went with the recco in the comments and used Redis. Note this only works for get requests.
/* cached requests */
async function cacheRequest(options){
let stringOptions = JSON.stringify(options)
let optionsHashed = crypto.createHash('md5').update(stringOptions).digest('hex')
let get = await client.getAsync(optionsHashed)
if (get) return get
let HTML = await request.get(options)
await client.setAsync(optionsHashed, HTML)
return HTML
}

Are Javascript date/time functions dependent on the client machine?

I was wondering if Javascript date/time functions will always return correct, universal dates/times
or whether, Javascript being a client-side language, they are dependent on what the client machine has its date set to.
If it is dependent on the client machine, what is the best way to get the correct universal time?
Javascript only knows as much about the correct time as the environment it is currently running within, and Javascript is client-side.
So, Javascript is at the mercy of the user having the correct time, AND timezone, settings on the PC on which they are browsing.
If the user has the incorrect time zone, but correct time, then functions depending on time zones like getUTCDate() will be incorrect.
If the user has the incorrect time, then all time-related functions in Javascript will be incorrect.
One could make the argument, however, that if the user wanted correct times on their PC they would have set the correct time. The counter to that is that the user may not know how to do that.
Edit Jun 2020: It is common now for operating systems to update the computer's system time automatically from a time server, significantly reducing the chances of incorrect time on the client. There is still a possibility of an incorrect time zone, but this too is often geo-detected somehow by systems during installation and/or is tied to the user's supplied country of residence in their relevant online account.
As thomasrutter has said javascript date functions are reliant on the client's machine. However if you want to get an authoritative date you could make and ajax request to your server that just returns the date string. You can then convert the date string into a date object with the following
var ds = ... // Some ajax call
var d = new Date(ds);
or whether, Javascript being a client-side language, they are dependent on what the client machine has its date set to.
Yes, this is correct.
If it is dependent on the client machine, what is the best way to get the correct universal time?
To get the time/date from an authoritative source, not from a client machine.
The methods do what they're documented to do. The best way to get UTC info is obviously to use the UTC methods:
getUTCFullYear(), getUTCMonth(), getUTCDate(), etc.
Javascript's date() constructor will always get the time of local machine.
The best way to get the universal time are
1) get the time from your server by an ajax call. This method will always show your server time no matter where your user is.
2) Get the time from an third party server. Use a third party server to get time from any time zone / country of the world. Here I'm explaining this method by using plain javascript and axios. The service I'm using is worldtimeapi.org/
VANILLA JS
function getTime(url) {
return new Promise((resolve, reject) => {
const req = new XMLHttpRequest();
req.open("GET", url);
req.onload = () =>
req.status === 200
? resolve(req.response)
: reject(Error(req.statusText));
req.onerror = (e) => reject(Error(`Network Error: ${e}`));
req.send();
});
}
Now Use this function to make the ajax call
let url = "http://worldtimeapi.org/api/timezone/Etc/GMT";
getTime(url)
.then((response) => {
let dateObj = JSON.parse(response);
let dateTime = dateObj.datetime;
console.log(dateObj);
console.log(dateTime);
})
.catch((err) => {
console.log(err);
});
AXIOS
axios({
url:"http://worldtimeapi.org/api/timezone/Etc/GMT",
method: "get",
})
.then((response) => {
let dateObj = response.data;
let dateTime = dateObj.datetime;
console.log(dateObj);
console.log(dateTime);
})
.catch((err) => {
console.log(err);
});
Hope that helps. Bear one thing in mind though, worldtimeapi.org/ is a third party service. If they choose to terminate their service, your code will break. Happy coding.

Categories

Resources