Post request not getting req.body - node.js

I am trying to make a post request with Postman. The only thing that returns is the id made by uuidv4() all the other information for the JSON object is not there.
I have tried req.body and req.apiGateway.event.body with no luck.
This is my post request:
const serverless = require("serverless-http");
const express = require("express");
const app = express();
// const bodyParser = require("body-parser");
const AWS = require("aws-sdk");
const db = new AWS.DynamoDB.DocumentClient();
const { v4: uuidv4 } = require("uuid");
app.use(express.urlencoded());
app.use(express.json());
// app.use(bodyParser.urlencoded({ extended: true }));
// app.unsubscribe(bodyParser.json());
app.post("/inspections", async (req, res) => {
const data = req.apiGateway.event.body;
const params = {
TableName: "inspectionTrackTable",
Item: {
id: uuidv4(),
unitNum: data.unitNum,
building: data.building,
managed: data.managed,
rental: data.rental,
inHouse: data.inHouse,
robeCount: data.robeCount,
inspected: data.inspected,
notes: data.notes
},
};
try {
await db.put(params).promise();
res.status(201).json({ unit: params.Item });
} catch (e) {
res.status(500).json({ error: e.message });
}
});
This is what I am entering in Postman:
{
"unitNum": "007",
"building": "A",
"managed": true,
"rental": false,
"inHouse": false,
"robCount": 0,
"inspected": false,
"notes": "this is a good unit"
}
I have now tried adding ...req.body to the item like this:
Item: {
id: uuidv4(),
...req.body
},
The response I am getting from that is:
{
"unit": {
"0": 123,
"1": 10,
"2": 32,
"3": 32,
"4": 32,
"5": 32,
"6": 34,
"7": 117,
"8": 110,
"9": 105,
"10": 116,
"11": 78,
"12": 117,
"13": 109,
"14": 34,
"15": 58,
"16": 32,
"17": 34,
"18": 48,
"19": 48,
"20": 55,
"21": 34,
"22": 44,
"23": 10,
"24": 32,
"25": 32,
"26": 32,
"27": 32,
"28": 34,
"29": 98,
"30": 117,
"31": 105,
"32": 108,
"33": 100,
"34": 105,
"35": 110,
"36": 103,
"37": 34,
"38": 58,
"39": 32,
"40": 34,
"41": 65,
"42": 34,
"43": 10,
"44": 32,
"45": 32,
"46": 32,
"47": 32,
"48": 10,
"49": 125,
"id": "efb90ad4-f68e-4ea0-b55c-6a4f79e3a96c"
}
}
I did not expect that...
My delete, and get requests are working I am having trouble with the put and post..

Related

AutoML prediction model PDF extraction: Required field not set

I'm trying to perform entity extraction on my prediction model but having issues passing PDF document from GCS.
/**
* TODO(developer): Uncomment these variables before running the sample.
*/
const projectId = "id";
const location = "us-central1";
const modelId = "modelid";
const keyFilename = "./gcp.json";
// Imports the Google Cloud AutoML library
const { PredictionServiceClient } = require("#google-cloud/automl").v1;
// Instantiates a client
const client = new PredictionServiceClient({ keyFilename });
async function predict() {
// Construct request
const request = {
name: client.modelPath(projectId, location, modelId),
payload: {
document: {
input_config: {
gcs_source: {
input_uris: "gs://pathtofile.pdf",
},
},
},
},
};
const [response] = await client.predict(request);
for (const annotationPayload of response.payload) {
console.log(annotationPayload);
console.log(`Text Extract Entity Types: ${annotationPayload.displayName}`);
console.log(`Text Score: ${annotationPayload.textExtraction.score}`);
const textSegment = annotationPayload.textExtraction.textSegment;
console.log(`Text Extract Entity Content: ${textSegment.content}`);
console.log(`Text Start Offset: ${textSegment.startOffset}`);
console.log(`Text End Offset: ${textSegment.endOffset}`);
}
}
predict();
This gives the following error:
Error: 3 INVALID_ARGUMENT: List of found errors: 1.Field: payload.document.document_text.content; Message: Required field not set.
code: 3,
details: 'List of found errors:\t1.Field: payload.document.document_text.content; Message: Required field not set.\t',
metadata: Metadata {
internalRepr: Map(3) {
'grpc-server-stats-bin' => [
Buffer(10) [Uint8Array] [
0, 0, 183, 198, 95,
1, 0, 0, 0, 0
]
],
'google.rpc.badrequest-bin' => [
Buffer(67) [Uint8Array] [
10, 65, 10, 38, 112, 97, 121, 108, 111, 97, 100,
46, 100, 111, 99, 117, 109, 101, 110, 116, 46, 100,
111, 99, 117, 109, 101, 110, 116, 95, 116, 101, 120,
116, 46, 99, 111, 110, 116, 101, 110, 116, 18, 23,
82, 101, 113, 117, 105, 114, 101, 100, 32, 102, 105,
101, 108, 100, 32, 110, 111, 116, 32, 115, 101, 116,
46
]
],
'grpc-status-details-bin' => [
Buffer(222) [Uint8Array] [
8, 3, 18, 104, 76, 105, 115, 116, 32, 111, 102, 32,
102, 111, 117, 110, 100, 32, 101, 114, 114, 111, 114, 115,
58, 9, 49, 46, 70, 105, 101, 108, 100, 58, 32, 112,
97, 121, 108, 111, 97, 100, 46, 100, 111, 99, 117, 109,
101, 110, 116, 46, 100, 111, 99, 117, 109, 101, 110, 116,
95, 116, 101, 120, 116, 46, 99, 111, 110, 116, 101, 110,
116, 59, 32, 77, 101, 115, 115, 97, 103, 101, 58, 32,
82, 101, 113, 117, 105, 114, 101, 100, 32, 102, 105, 101,
108, 100, 32, 110,
... 122 more items
]
]
},
options: {}
},
statusDetails: [
BadRequest {
fieldViolations: [
FieldViolation {
field: 'payload.document.document_text.content',
description: 'Required field not set.'
}
]
}
]
}
I have checked all the passed parameters and they're fine.
I'm using this as an example: https://cloud.google.com/natural-language/automl/docs/predict#automl_language_entity_extraction_predict-nodejs
It works fine when I pass text but I would like to pass PDF as the payload.
Thank you

Error when trying to run dev server | React, SSR

I got this error when I'm trying to run server:
E:...\node_modules\ts-loader\dist\watch-run.js:29
for (const [filePath, date] of times) {
^
TypeError: times is not iterable
at E:...\node_modules\ts-loader\dist\watch-run.js:29:44
at Hook.eval [as callAsync] (eval at create (E:...\node_modules\tapable\lib\HookCodeFactory .js:33:10),
:7:1)
at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (E:...\node_modules\tapable\lib\Hook.js:18:14)
at run (E:...\node_modules\webpack\lib\Watching.js:138:33)
at E:...\node_modules\webpack\lib\Watching.js:120:6
at Compiler.readRecords (E:...\node_modules\webpack\lib\Compiler.js:908:11)
at run (E:...\node_modules\webpack\lib\Watching.js:116:26)
at E:...\node_modules\webpack\lib\Watching.js:112:6
at E:...\node_modules\webpack\lib\HookWebpackError.js:69:3
at E:...Hook.eval [as callAsync] (eval at create (\node_modules\tapable\lib\HookCodeFactory .js:33:10),
:6:1)
-- package.json --
{
"name": "",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack",
"dev": "webpack serve"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"#types/react": "^17.0.7",
"#types/react-dom": "^17.0.5",
"ts-loader": "^9.2.2",
"typescript": "^4.2.4",
"webpack": "^5.37.1",
"webpack-cli": "^4.7.0",
"webpack-dev-server": "^3.11.2",
"webpack-node-externals": "^3.0.0"
},
"dependencies": {
"express": "^4.17.1",
"nodemon": "^2.0.7",
"react": "^17.0.2",
"react-dom": "^17.0.2"
}
}
-- dev.js --
const webpack = require('webpack');
const webpackConfig = require('../webpack.config');
const nodemon = require('nodemon');
const path = require('path');
const compiler = webpack(webpackConfig);
compiler.run((err) => {
if(err) {
console.log('Compilation failed: ', err)
}
compiler.watch({}, (err) => {
if(err) {
console.log('Compilation failed: ', err);
}
console.log('Compilation was successfully');
});
nodemon({
script: path.resolve(__dirname, '../dist/server/server.js'),
watch: [
path.resolve(__dirname, '../dist/server'),
path.resolve(__dirname, '../dist/client')
]
})
});
-- webpack.server.config.js --
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const NODE_ENV = process.env.NODE_ENV;
module.exports = {
target: 'node',
mode: NODE_ENV ? NODE_ENV : 'production',
entry: path.resolve(__dirname, '../src/server/server.js'),
output: {
path: path.resolve(__dirname, '../dist/server'),
filename: 'server.js'
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
externals: [nodeExternals()],
module: {
rules: [{
test: /\.[jt]sx?$/,
loader: 'ts-loader',
exclude: /node_modules/
}]
},
optimization: {
minimize: false
}
};
-- webpack.client.config.js --
const path = require('path');
const NODE_ENV = process.env.NODE_ENV;
module.exports = {
mode: NODE_ENV ? NODE_ENV : 'production',
entry: path.resolve(__dirname, '../src/client/index.tsx'),
output: {
path: path.resolve(__dirname, '../dist/client'),
filename: 'client.js'
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
module: {
rules: [{
test: /\.[jt]sx?$/,
loader: 'ts-loader',
exclude: /node_modules/
}]
}
}; // module.exports
-- webpack.config.js --
const clientConfig = require('./configs/webpack.client.config');
const serverConfig = require('./configs/webpack.server.config');
module.exports = [
clientConfig,
serverConfig
];
-- server.js --
import express from 'express';
import ReactDOM from 'react-dom/server';
import { Header } from "../shared/Header";
const app = express();
app.get('/', (req, res) => {
res.send(
ReactDOM.renderToString(Header())
);
});
app.listen(4000, () => {
console.log('Server started on port http://localhost:4000');
});
-- Folder structure --
This trouble from the ts-loader. You can see pull request here.
Instead of using ts-loader you should use babel.
You need change handlers .ts and .js in webpack config.
{
test: /\.[tj]sx?$/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-react']
}
}
}
Also add .babelrc with this:
{"presets": ["#babel/react", "#babel/typescript", ["#babel/env", { "modules": false }]]}
TypeError: times is not iterable
Other than the fact that I'm confused as to why you're using serverside react rendering (unless you are trying out the experimental serverside react components), then you either need to modify your code in accordance with the above error or make times iterable.
ES2015.Iterable defines that as
interface Array<T> {
/** Iterator */
[Symbol.iterator](): IterableIterator<T>;
/**
* Returns an iterable of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, T]>;
/**
* Returns an iterable of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an iterable of values in the array
*/
values(): IterableIterator<T>;
}
Where this will likely be of most use to you:
const times = 'StackOverflow'
const iterable = [...Array(...times).values()]
console.log(iterable);
This outputs each subcharacter as follows:
[LOG]: ["S", "t", "a", "c", "k", "O", "v", "e", "r", "f", "l", "o", "w"]
if you don't spread ...times and instead use times it outputs the string as it's defined by const times. Alternatively, you could use a number in place of a string, such as 100. Then, it would return
[LOG]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
if you want a countdown, then write
const times = 101
const iterable = [...Array(times).keys()].reverse();
The above outputs a countdown from 100:
[LOG]: [100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Anyway, you could make whatever times is Iterable, but it is worth noting that you're missing ts-node as a dependency and that should be used if you're using an express server.
I had the same problem using ts-loader and webpack 5. It was resolved like this:
win+r -> %temp% and cleared this folder
Created a new folder for the project where I moved the sources and package.json
In the new folder, I installed all the dependencies from package.json via "npm i" (without arguments)
Below is my package.the json on which this was done.
{
"name": "prj-dev-1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build:dev": "cross-env NODE_ENV=development webpack --config webpack.config.js",
"build:prod": "cross-env NODE_ENV=production webpack --config webpack.config.js",
"dev": "cross-env NODE_ENV=development webpack-dev-server"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"cross-env": "^7.0.3",
"html-webpack-plugin": "^5.5.0",
"ts-loader": "^9.2.6",
"typescript": "^4.5.5",
"webpack": "^5.69.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
}
}
If you start the server via node bin\dev.js and this error persists, then try to do so:
Install npm i -D nodemon-webpack-plugin
Add settings for it in webpack.server.config.js
watch: true,
plugins: [
new NodemonPlugin({
watch: path.resolve(__dirname, '../dist/server/server.js')
}), // Dong
],
run "npx webpack --config webpack.config.js" ("node bin\dev.js" instead)
Just update version ts-loader to 9.2.8

How to use Chart.js in Nodejs?

How to create a pie chart using NodeJs with chartjs?
want to create different types of charts using chartjs but when I tried to run the code shows "cannot set the property of width"
TypeError: Cannot set property 'width' of undefined
at ni.resize (node_modules\chart.js\dist\Chart.min.js:7:93312)
at ni.initialize (node_modules\chart.js\dist\Chart.min.js:7:92818)
at ni.construct (node_modules\chart.js\dist\Chart.min.js:7:92559)
at new ni (node_modules\chart.js\dist\Chart.min.js:7:91964)
at Object.<anonymous> (chartjs\chart.js:7:15)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
I tried to run this code to produce a pie chart image but found this error.
let Canvas = require("canvas"),
canvas = Canvas.createCanvas(400, 400),
ctx = canvas.getContext("2d"),
Chart = require('chart.js'),
fs = require("fs");
var myChart = new Chart(ctx, {
type: "pie",
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: "# of Votes",
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
"rgba(255, 99, 132, 0.2)",
"rgba(54, 162, 235, 0.2)",
"rgba(255, 206, 86, 0.2)",
"rgba(75, 192, 192, 0.2)",
"rgba(153, 102, 255, 0.2)",
"rgba(255, 159, 64, 0.2)"
],
borderColor: [
"rgba(255, 99, 132, 1)",
"rgba(54, 162, 235, 1)",
"rgba(255, 206, 86, 1)",
"rgba(75, 192, 192, 1)",
"rgba(153, 102, 255, 1)",
"rgba(255, 159, 64, 1)"
],
borderWidth: 1
}
]
},
options: {
scales: {
yAxes: [
{
ticks: {
beginAtZero: true
}
}
]
}
}
});
canvas.toBuffer(function(err, buf) {
if (err) throw err;
fs.writeFileSync("chart.png", buf);
});
Should be an image in the current folder
I suggest using ChartJS for Node: https://www.npmjs.com/package/chartjs-node
It draws a chart which you can then save to the file system and insert accordingly.
Here's a snippet of code as an example:
import * as ChartjsNode from 'chartjs-node'; // Import the library
const chartNode = new ChartjsNode(600, 600); // Create an instance with dimensions
const barGraphOptions = {
type: 'bar',
data: []
};
// Draw the chart and write the file to the file system
await new Promise(resolve => {
chartNode
.drawChart(barGraphOptions)
.then(() => {
chartNode.getImageBuffer('image/png');
})
.then(() => {
chartNode.writeImageToFile('image/png', 'some_file.png').then(() => {
resolve();
});
})
.catch(e => {
console.log('Caught', e);
});
});
ChartJS is an HTML5 based file which is used in front-end development only.
For more information visit this site.
You can refer to this answer if you want to use nodejs to create Charts.
P.S. This question is duplicate to this
I had the same issue as OP. I couldn't figure out a way to do it using the standard approach of combining Node Canvas and Chart.JS, but I found using ChartjsNodeCanvas works.
import { CanvasRenderService } from 'chartjs-node-canvas';
canvasRenderService: CanvasRenderService;
async createGraph(data: any) {
const configuration = {
type: 'bar',
data: {
labels: // Your labels,
datasets: [
data
]
},
options: {
// Your options
}
};
const canvasRenderService = new CanvasRenderService(300, 500);
return await canvasRenderService.renderToDataURL(configuration);
// or return canvasRenderService.renderToBuffer(configuration);
// or return canvasRenderService.renderToStream(configuration);
}
await this.createGraph(data);
Note, ChartjsNodeCanvas requires ChartJS as a dependency.

syntax to loop through docs send from express router and use it to plot chart js

I am starting to learn node js (express js). I am trying to plot a chart using data sent from the mongo db using mongoose....I would want to loop the docs sent from the database to be used in ploting the data. I had tried using fetch api but it failed due to Passport req.user (it didn't recognize user )
here is my code. I will appreciate for any help and leads.
router.get('/mychart', loggedInYes, function (req, res, next) {
Products.find({user:req.user._id},function (err,docs) {
if (err)
return err;
res.render('user/mychart',{docs:docs});
});
});
and here is the chart js where I would want to use Docs
<canvas id="myChart" width="400" height="400"></canvas>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [{
{#
each docs
}
} {
{
this.docs.yearofbirth
}
} {
{
/each}}],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
The problem is how to loop through the data....data: [{
{#
each docs
}
} {
{
this.docs.yearofbirth
}
} {
{
/each}}],
I solved it by including the credentials objects in the client hbs file. It worked
fetch('/api/foo', {credentials: 'include'})

inserts not working mongodb

I'm having a problem while using a webtask as a backend web service to a static website. I'm using the web service to insert values to a mongodb database. The inserts are not returning any errors, but there is nothing inserting into the database. It just says 'worked' on the response. Here's the relevant code:
var MongoClient = require('mongodb').MongoClient;
function savePage (page, db, cb){
var doc = {
pageSec: page
};
db.collection("page").insertOne(doc, function (err) {
if(err) {return cb(err);}
cb('worked');
});
}
module.exports = function(context, cb){
var section = context.query.section;
if(section){
MongoClient.connect(context.data.mongoUri, function(err, db) {
if(err) {return cb(err);}
savePage(section, db, function (err) {
if(err){return cb(err);}
cb(null);
});
});
}
};
additionally, this is what mongodb returns in response to the insert
"details": {
"ok": 1,
"n": 1,
"lastOp": "6307485423539060737",
"electionId": "576dec4e2c52240b7a5bca5e"
},
"message": {
"parsed": true,
"index": 96,
"raw": {
"type": "Buffer",
"data": [
96,
0,
0,
0,
163,
69,
36,
3,
5,
0,
0,
0,
1,
0,
0,
0,
8,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
60,
0,
0,
0,
16,
111,
107,
0,
1,
0,
0,
0,
16,
110,
0,
1,
0,
0,
0,
17,
108,
97,
115,
116,
79,
112,
0,
1,
0,
0,
0,
147,
176,
136,
87,
7,
101,
108,
101,
99,
116,
105,
111,
110,
73,
100,
0,
87,
109,
236,
78,
44,
82,
36,
11,
122,
91,
202,
94,
0
]
},
"data": {
"type": "Buffer",
"data": [
96,
0,
0,
0,
163,
69,
36,
3,
5,
0,
0,
0,
1,
0,
0,
0,
8,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
60,
0,
0,
0,
16,
111,
107,
0,
1,
0,
0,
0,
16,
110,
0,
1,
0,
0,
0,
17,
108,
97,
115,
116,
79,
112,
0,
1,
0,
0,
0,
147,
176,
136,
87,
7,
101,
108,
101,
99,
116,
105,
111,
110,
73,
100,
0,
87,
109,
236,
78,
44,
82,
36,
11,
122,
91,
202,
94,
0
]
},
"bson": {},
"opts": {
"promoteLongs": true
},
"length": 96,
"requestId": 52708771,
"responseTo": 5,
"responseFlags": 8,
"cursorId": "0",
"startingFrom": 0,
"numberReturned": 1,
"documents": [
{
"ok": 1,
"n": 1,
"lastOp": "6307485423539060737",
"electionId": "576dec4e2c52240b7a5bca5e"
}
],
"cursorNotFound": false,
"queryFailure": false,
"shardConfigStale": false,
"awaitCapable": true,
"promoteLongs": true
}
When I build my JSON object to sent to MongoDB, I always set the property name as string and it works.
var doc = {
"pageSec": page
};
I don't see anything wrong in your code, so you can try this.

Resources