dynamodb query single row using javascript - 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!

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 parse/filter data from JSON file in Javascript

Is there any way to parse/filter the data present in JSON file in a Javascript file.
Basically, I am calling JSON file into my local javascript. I am having trouble in reading specific data and printing.
Can anyone please help.
JSON file contains:
{
"Data": [
{
"name": "John",
"age": 30
},
{
"joined on":"Jan 2015",
"working on": "Automation",
}
]
}
I am trying to read the above JSON file as:
var jfile = require("./Example.json");
var test = JSON.parse(JSON.stringify(jfile))
console.log(test)
I get the output like this:
{ Data:
[ { name: 'John', age: 30 },
{ 'joined on': 'Jan 2015', 'working on': 'Automation' } ] }
From the above, I am interested in accessing/filtering out only one i.e. "name". I would like to print only the value "John" to the console.
I have tried to use the ".filter" method to the JSON.parse method but it throws me an error as:
JSON.parse(...).filter is not a function
Is there any way to perform this activity?
You can access it using . dot notation
var a = {
"Data": [{
"name": "John",
"age": 30
},
{
"joined on": "Jan 2015",
"working on": "Automation",
}
]
}
console.log(a.Data[0].name)
filter is an array method.
JSON.parse(...) will not give you an array. It will give you an object with a Data property. The value of that property is an array.
JSON.parse(...).Data.filter.
You can't just ignore parts of your data structure.
If you have multiple items in your array of different shapes, you can use this
Access the Data key with json.Data
map your array to transform its items into names
apply filter(Boolean) to take out those who are undefined
In your case you'll end up with an array containing only one name John
const getName = json => json.Data.map(x => x.name).filter(Boolean);
const json = {
"Data": [{
"name": "John",
"age": 30
},
{
"joined on": "Jan 2015",
"working on": "Automation",
}
]
};
console.log(getName(json));
Your JSON's main level is an object (not an array) and only arrays have .filter method.
So filter the array under Data key:
var test = JSON.parse(JSON.stringify(jfile)).Data.filter(/*something*/);
But better if you aren't re-parse JSON:
var test = jfile.Data.filter(/*something*/);
As Quentin mentioned in his comment, What is the use of below statement ?
var test = JSON.parse(JSON.stringify(jfile))
You can directly access the name property from the response.
Try this :
var obj = {
"Data": [{
"name": "John",
"age": 30
},
{
"joined on": "Jan 2015",
"working on": "Automation"
}
]
};
// Solution 1
console.log(obj.Data.map(item => item.name).filter(Boolean));
// Solution 2
console.log(obj.Data.filter(item => item.name).map(elem => elem.name));

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!

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

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);
}
});

Unable to print json values after parsing in NodeJS

The below NodeJS code tries to convert an xml document into json and then parse it.
var fs = require('fs');
var parse = require('jsonml').parse;
var jsonML = parse(fs.readFileSync('myfile.xml'));
var jsondata = JSON.parse(jsonML);
console.log(jsondata.BESAPI.Computer[0].ID);
It works fine, but I am unable to display the correct values. An error is thrown on the line console.log(jsondata.BESAPI.Computer[0].ID);
I am trying to display the ID of each computer in the json object.
Json object
{
"BESAPI": {
"-xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"-xsi:noNamespaceSchemaLocation": "BESAPI.xsd",
"Computer": [
{
"-Resource": "api/computer/2431038",
"LastReportTime": "Thu, 26 Feb 2015 14:54:41 +0000",
"ID": "2431038"
},
{
"-Resource": "api/computer/16710075",
"LastReportTime": "Thu, 26 Feb 2015 14:45:18 +0000",
"ID": "16710075"
},
{
"-Resource": "api/computer/3415985",
"LastReportTime": "Thu, 26 Feb 2015 14:50:52 +0000",
"ID": "3415985"
}]
}
}
I get this error:
Without having your original XML, I can't know for sure what's going on, but this experiment may help you with further investigations.
For an XML like
<?xml version="1.0"?>
<BESAPI>
<Computer ID="api/computer/2431038"></Computer>
<Computer ID="api/computer/16710075"></Computer>
</BESAPI>
the output from jsonML looks like this:
[ 'BESAPI',
[ 'Computer', { ID: 'abc123' } ],
[ 'Computer', { ID: 'def987' } ] ]
which doesn't resemble the JSON you gave us, but attempting to parse it gives the error you presented.
So I'm guessing that the output from jsonML isn't parsable JSON, but a nested array of sorts.

Categories