How to compare a string to a date in postman test? - javascript

Suppose a API request fetches a users id, email address and birthday. Sample API Request below:
GET: /v1/users HTTP/1.1
Content-Type: application/json
Authorization: bearer {access_token}
For the above request, the following is the response:
{
"content": [
{
"id": 1,
"email": "random#random.com",
"birthday": "1990-01-01"
},
{
"id": 40,
"email": "random1#random1.com",
"birthday": "1990-18-10"
}
],
"last": false,
"total_elements": 2,
"total_pages": 1,
"sort": null,
"first": true,
"number_of_elements": 2,
"size": 20,
"number": 0
}
Now, what will be the test in postman to make sure that all the returned values under birthday node is greater than 1988-18-01?
I have tried the following:
pm.test("Check birthday greater than 1988-18-01", () => {
for (i = 0; i < jsonData.content.length; i++) {
var a = '1988-18-01';
pm.expect(jsonData.content[i].birthday).to.be.above(a);
}
});
But postman says: "Check birthday greater than 1988-18-01 | AssertionError: expected '1990-01-01' to be a number or a date".

So firstly, the dates need to be converted to a format that JS accepts and use the Date constructor to generate the complete date.
Next, the 'above' function in pm accepts an integer, so the date format will not be compared.
To fix this, we can convert the date to integer format by using the .getTime() function.
Lastly, it's not a good practice to declare variables inside a for loop.
Here's what you can replace your test with:
pm.test("Check birthday greater than 1988-18-01", () => {
let date,
isoFormatDate,
a = new Date('1988-01-18').getTime();
for (i = 0; i < jsonData.content.length; i++) {
date = jsonData.content[i].birthday;
isoFormatDate = new Date(date).getTime(); // Converting to integer from date format
pm.expect(isoFormatDate).to.be.above(a);
}
});

Related

Wrong results in group_by by month with javascript date objects in node app

I have a problem using javascript date objects in a node app and running queries through postgresql.
I have following data in a csv file (first column: date, second column: amount)
08/08/2022;620,00
01/08/2022;-73,41
01/08/2022;600,00
01/08/2022;-341,36
Since date format is not standard, I convert it manually to a date object:
new Date(year, month, day);
I store it to a postgresql database through the prisma client.
The date field is following type in schema.prisma
model Transaction {
id Int #id #default(autoincrement())
amount Float
date DateTime #db.Date
which corresponds to this migration:
ALTER TABLE "Transaction" ALTER COLUMN "date" SET DATA TYPE DATE;
Once data is stored, it looks like this:
[
{
"id": 9205,
"date": "2022-08-07T22:00:00.000Z",
},
{
"id": 9206,
"amount": -73.41,
"date": "2022-07-31T22:00:00.000Z",
},
{
"id": 9207,
"amount": 600,
"date": "2022-07-31T22:00:00.000Z",
},
{
"id": 9208,
"amount": -341.36,
"date": "2022-07-31T22:00:00.000Z",
}
]
Dates look good, I double-checked running .getMonth, creating the date again in the browser etc.
I try to run a raw query with prisma:
const expensesByMonths: any[] = await this.prisma.$queryRaw`
SELECT
date_trunc('month', date) as date_month,
sum(amount)
FROM "public"."Transaction"
GROUP BY
date_month
`;
Unfortunately, the results are wrong:
{
"expensesByMonths": [
{
"date_month": "2022-07-01T00:00:00.000Z",
"sum": -414.77
}
],
"incomesByMonths": [
{
"date_month": "2022-07-01T00:00:00.000Z",
"sum": 600
},
{
"date_month": "2022-08-01T00:00:00.000Z",
"sum": 620
}
]
}
I don't understand why group_by from postgresql is not understanding the javascript date objects, since they are strings at the end.
I guess I can't store in postgresql things like 2022-07-31T22:00:00.000Z, I see everywhere dates like '2022-11-23', not sure if it's stored as strings or dates

How to convert Excel Table to specific JSON format using Office Scripts

I'm trying to get a specific JSON output from Office Scripts in order to make an API call with Power Automate. The output I'm receiving from Power Automate does not have the format required in the API docs (link to API docs below). Tried modifying the script to get the required output but unfortunately, I'm just starting out with js, so I can't figure out what I need.
Right now, the input must come from an Excel table. I can format the excel table differently for this flow if it's needed, but nevertheless, the input must come from an Excel table. Right now, the Excel table looks like this:
This is the Office Script I am using, comes from this blog post: https://learn.microsoft.com/en-us/office/dev/scripts/resources/samples/get-table-data:
function main(workbook: ExcelScript.Workbook): TableData[] {
// Get the first table in the "WithHyperLink" worksheet.
// If you know the table name, use `workbook.getTable('TableName')` instead.
const table = workbook.getWorksheet('WithHyperLink').getTables()[0];
// Get all the values from the table as text.
const range = table.getRange();
// Create an array of JSON objects that match the row structure.
let returnObjects: TableData[] = [];
if (table.getRowCount() > 0) {
returnObjects = returnObjectFromValues(range);
}
// Log the information and return it for a Power Automate flow.
console.log(JSON.stringify(returnObjects));
return returnObjects
}
function returnObjectFromValues(range: ExcelScript.Range): TableData[] {
let values = range.getTexts();
let objectArray : TableData[] = [];
let objectKeys: string[] = [];
for (let i = 0; i < values.length; i++) {
if (i === 0) {
objectKeys = values[i]
continue;
}
let object = {}
for (let j = 0; j < values[i].length; j++) {
// For the 4th column (0 index), extract the hyperlink and use that instead of text.
if (j === 4) {
object[objectKeys[j]] = range.getCell(i, j).getHyperlink().address;
} else {
object[objectKeys[j]] = values[i][j];
}
}
objectArray.push(object as TableData);
}
return objectArray;
}
interface TableData {
"Event ID": string
Date: string
Location: string
Capacity: string
"Search link": string
Speakers: string
}
And this is the output I am getting in Power Automate when I run the Office Script:
[
{
"Line": "",
"Id": "0",
"Description": "nov portion of rider insurance",
"Amount": "100",
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": "",
"PostingType": "Debit",
"AccountRef": "",
"value": "39",
"name": "Opening Bal Equity"
},
{
"Line": "",
"Id": "",
"Description": "nov portion of rider insurance",
"Amount": "100",
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": "",
"PostingType": "Credit",
"AccountRef": "",
"value": "44",
"name": "Notes Payable"
}
]
BUT, the schema I need looks like this (it is based on this API doc https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/journalentry):
{
"Line": [
{
"Id": "0",
"Description": "nov portion of rider insurance",
"Amount": 100.0,
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": {
"PostingType": "Debit",
"AccountRef": {
"value": "39",
"name": "Opening Bal Equity"
}
}
},
{
"Description": "nov portion of rider insurance",
"Amount": 100.0,
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": {
"PostingType": "Credit",
"AccountRef": {
"value": "44",
"name": "Notes Payable"
}
}
}
]
}
There are a lot of differences and obviously, when I try to make the API call, I get a 400 'Bad request' error. Does anyone know how I must modify either the Script or the Excel table or do something different in Power Automate in order to get the specific schema I need?
Any help will be appreciated. Thanks!!
I think the core of what's going on is that your script is parsing everything to match a linear "TableData" interface given in the tutorial you followed before it sends it to the Stringify method, but your data doesn't match that interface, so it does the best it can and outputs each individual row into an object array. When Stringify gets called, it sees an array of plain objects, so it just converts everything to a string.
I think you want this to be a bit more structured, which means you'll want to hand-code the objects you're passing for each of your rows. Basically, what your JSON schema is telling you is that your data types should be something like this:
Interface AccountRefPart {
value: string
name: string
}
Interface JournalEntryLineDetailPart {
PostingType: string
AccountRef: AccountRefPart
}
Interface LinePart {
ID?: string
Description: string
Amount: number
DetailType: string
JournalEntryLineDetail: JournalEntryLineDetailPart
}
Interface TableData {
Line: LinePart[]
}
If you just want to pass a single Line element as a JSON (what the outer-most curly braces suggest), you'll want to stringify a single object of the TableData type, and you want to construct this object using the data from the rows of your table. (I can't actually see your table, but I trust that it has the information you need above.)

Bind input value to specific value in object

I'm trying to build a timesheet application where users can enter the amount of hours they are working each day. I'm storing the data about each user in an object and I wish to populate an input field in a table with each respective hour (duration). To illustrate how I want to store the data, I added an image: https://imgur.com/a/WmV4GvU
And also a fiddle: https://jsfiddle.net/h64wafkp/14/
Basically, each user in the database has a one-to-many relationship with another table called "hours", so the data structure looks as such:
{
"id": 1,
"firstname": "JayZ",
"lastname": "Carter",
"email": "jay#rocafella.com",
"hours": [
{
"id": 226,
"user_id": 1,
"date": "2018-12-05",
"duration": 140
},
{
"id": 1,
"user_id": 1,
"date": "2018-12-02",
"duration": 13
},
{
"id": 2,
"user_id": 1,
"date": "2018-12-03",
"duration": 13
}
]
},
Then there's the table itself which is just a regular html table with each respective day as column headers. My issue is how to bind each duration to each respective date cell (see image above). Any suggestions?
In your methods define a function to get the duration for a given user and date:
getDuration(user_id, date) {
const user = this.users.find(user => user.id == user_id);
const hour = user.hours.find(hour => hour.date == date);
return hour ? hour.duration : 0;
},
Then in the HTML part add a :value attribute to the input element:
:value="getDuration(user.id, day)"
If you need to also bind updates to those input values back to the data structure, you'll need to define a function setDuration and call it with the following input attribute:
#input="e => setDuration(user.id, day, e.target.value)"
You would again locate the user and hour as above, but then you need to possibly add an hour object to the hours array, where you need a new id. I don't know how you would generate new id values in your case, so I'll leave that for you to implement (see comment):
setDuration(user_id, date, duration) {
const user = this.users.find(user => user.id == user_id);
const hour = user.hours.find(hour => hour.date == date);
if (hour) {
hour.duration = duration;
} else {
user.hours.push({
id: getNewId(), // <--- implement this!
user_id,
date,
duration
});
}
},
After our exchange below it turns out that your ORM will recognise an hour record needs to be inserted (instead of updated) if there is no id property, so in that case just omit the line:
id: getNewId(), // <--- implement this!

dynamodb query single row using javascript

Not sure what is going on here, I follow the docs, and I get errors, so maybe my table is defined wrong?
function parseGET( data, callback )
{
const params =
{
TableName: data.TableName,
Key:
{
"workOrder": data.workOrder // <--number, not a string
}
};
dynamodb.get( params, ( error, data ) =>
{
if( error )
console.log( 'table ERROR:', error );
...
}
}
Response: "The provided key element does not match the schema"
Response:
{
"statusCode": 200,
"body": "The provided key element does not match the schema",
"headers": {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
}
}
If I do a scan, I get all my data, but I just want to get a single row.
dynamodb.scan( {"TableName": data.TableName}, ( error, data ) =>
...
data:
{
"probeCount": "123",
"rangeCal": "hight",
"ESID": "1",
"rangeNom": "1000",
"nodeCount": "123",
"password": "123",
"cableLength": "456",
"userId": "Onicon",
"usePasswd": "disable",
"elevation": "789",
"workOrder": 789456,
"rangeMax": "1150",
"serialNumber": "3"
}
],
"Count": 11,
"ScannedCount": 11
Getting a single row works in the console, but I can't figure out how to do the same via JS.
Some table details:
Table name myTestTable
Primary partition key workOrder (Number)
Primary sort key -
Point-in-time recovery DISABLEDEnable
Time to live attribute DISABLEDManage TTL
Table status Active
Creation date March 22, 2018 at 1:45:09 PM UTC-7
UTC: March 22, 2018 at 8:45:09 PM UTC
Local: March 22, 2018 at 1:45:09 PM UTC-7
Region (N. California): March 22, 2018 at 12:45:09 PM UTC-8
Have you tried changing the definition of your key to something like...
Key:
{
"workOrder": {"N", data.workOrder} // <--number, not a string
}
you might need to use
data.workOrder.toString()
when defining the key.
Thanks to those who helped.
The end result was I was a little confused (as usual).
data.workOrder was a string of a number, eg. "654" in JSON, not 654.
So the simple solution is to convert it to an actual number:
data.workOrder = parseInt( data.workOrder, 10 );
And now my original query works!

Access to value of object inside array

I have a complicated response from an http request as shown below:
"rates": [
{
"non_refundable": false,
"no_of_rooms": 1,
"includes_wifi": false,
"includes_boarding": true,
"has_promotions": true,
"group_code": "xgirbylkwb6xtg",
"currency": "INR",
"cancellation_policy": {
"under_cancellation": false,
"details": [
{
"from": "2016-12-25T00:00:00",
"flat_fee": 20309.01,
"currency": "INR"
}
],
"cancel_by_date": "2016-12-24T00:00:00",
"amount_type": "value"
}
}
]
Rates length is between 6-20 inside another array with length of around 200.
The "cancellation_policy"shows up only if "non_refundable": false.
How I can access "from": "2016-12-25T00:00:00" and change the format with Moment JS and how I can access "flat_fee": 20309.01?
I tried using angular.forEach already but it defines only the value of last array .
I tried this already:
if ($scope.data[i].rates[j].non_refundable == false) {
for (var d = $scope.data[i].rates[j].cancellation_policy.details.length - 1; d >= 0; d--) {
But I had no success.
ps:
The value should show on $mdDialog
You don't need to loop under details, just do it like this :
var startdate = $scope.data[i].rates[j].cancellation_policy.details[0].from;
var new_date = moment(startdate).format('MMMM Do YYYY, h:mm:ss a');
var other = $scope.data[i].rates[j].cancellation_policy.details[0].flat_fee;

Categories