Getting error while POST request with JSON - javascript

This is my server.js file code . I am trying to push the JSON content in the user object , but i am getting following error. Please tell me where i am going wrong.
const express = require('express')
const app = express()
const bcrypt = require('bcrypt')
const bodyParser = require('body-parser')
app.use(express.json())
const users = []
app.get('/users', (req, res) => {
JSON.stringify(users)
res.json(users)
})
app.post('/users', (req, res) => {
const user = {
name: req.body.name,
password: req.body.password
}
users.push(user)
res.status(201).send()
})
app.listen(3000, console.log("server started"));
I used an extension in VS code called REST client.
GET http: //localhost:3000/users
#####
POST http: //localhost:3000/users
Content-Type: application/json
{
"name": "Tanay",
"password": "password"
}
When I'm firing POST request it shows the error - SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at parse (C:\Users\TANAY RAJ\Desktop\nodePassport\Wsimplified\node_modules\body-parser\lib\types\json.js:89:19)
at C:\Users\TANAY RAJ\Desktop\nodePassport\Wsimplified\node_modules\body-parser\lib\read.js:121:18
at invokeCallback (C:\Users\TANAY RAJ\Desktop\nodePassport\Wsimplified\node_modules\raw-body\index.js:224:16)
at done (C:\Users\TANAY RAJ\Desktop\nodePassport\Wsimplified\node_modules\raw-body\index.js:213:7)
at IncomingMessage.onEnd (C:\Users\TANAY RAJ\Desktop\nodePassport\Wsimplified\node_modules\raw-body\index.js:273:7)
at IncomingMessage.emit (events.js:322:22)
at endReadableNT (_stream_readable.js:1187:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21)

Can be something wrong with the user variable. Can you check this:
const user={'name':req.body.name,'password':req.body.password}
Update
I tried out:
var data = [];
const user={'name':"Deshan",'password':"password"}
data.push(user);
console.log(data);
And the result was as follow:
[ { name: 'Deshan', password: 'password' } ]
So it maybe a problem with the request data.

Related

While creating matrixClient by using matrix-js-sdk, i am getting an error of "TypeError: this.opts.request is not a function"

While creating matrixClient by using matrix-js-sdk, I am getting an error of TypeError: this.opts.request is not a function.
The error is at line no. 19. but don't understand the reason.
const express = require('express');
const sdk = require('matrix-js-sdk');
const app = express();
const port = 3000;
require('dotenv').config();
const BASE_URL = process.env.BASE_URL;
const ACCESS_TOKEN = process.env.ACCESS_TOKEN;
const USER_ID = process.env.USER_ID;
const PASSWORD = process.env.PASSWORD;
const matrixClient = sdk.createClient({
baseUrl: BASE_URL,
accessToken: ACCESS_TOKEN,
userId: `#${USER_ID}:matrix.org`,
});
app.get('/', async (req, res) => {
await matrixClient.startClient(); // error
matrixClient.once('sync', function (state, prevState, res) {
console.log(state); // state will be 'PREPARED' when the client is ready to use
});
res.send('hello');
});
// getAccessToken(USER_ID, PASSWORD);
function getAccessToken(userId, password) {
const client = sdk.createClient('https://matrix.org');
client
.login('m.login.password', { user: userId, password: password })
.then((response) => {
console.log(response.access_token);
})
.catch((err) => {
console.log('access_token error :', err);
});
}
app.listen(port, () => {
console.log(`app is listening at http://localhost:${port}`);
});
ERROR :
app is listening at http://localhost:3000
Getting saved sync token...
Getting push rules...
Attempting to send queued to-device messages
Got saved sync token
Got reply from saved sync, exists? false
All queued to-device messages sent
Getting push rules failed TypeError: this.opts.request is not a function
at MatrixHttpApi.doRequest (A:\matrix\matrix_node\node_modules\matrix-js-sdk\lib\http-api.js:741:23)
at MatrixHttpApi.requestOtherUrl (A:\matrix\matrix_node\node_modules\matrix-js-sdk\lib\http-api.js:620:17)
at MatrixHttpApi.request (A:\matrix\matrix_node\node_modules\matrix-js-sdk\lib\http-api.js:576:17)
at MatrixHttpApi.authedRequest (A:\matrix\matrix_node\node_modules\matrix-js-sdk\lib\http-api.js:524:33)
ix-js-sdk\lib\client.js:7283:22) at SyncApi.getPushRules (A:\matrix\matrix_node\node_modules\matrix-js-sdk\lib\sync.js:155:42) at SyncApi.sync (A:\matrix\matrix_node\node_modules\matrix-js-sdk\lib\sync.js:674:16)
at MatrixClient.startClient (A:\matrix\matrix_node\node_modules\matrix-js-sdk\lib\client.js:497:18) at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async A:\matrix\matrix_node\index.js:19:3
Waiting for saved sync before retrying push rules...

Can't Access Files from FormData in React/Node App. TypeError: Cannot read property '0' of undefined

I'm creating a scholarship website where users can submit an application. I've created a form and wired it up so that when it's submitted, the form data populates an email which is sent to the person who handles the applicant data, and uploaded PDFs are attached to it. This error keeps popping up on submit though, even though I'm pretty sure I should be selecting the files correctly. During other trials I selected them incorrectly and the email was sent, but while the text data was all correct, the files would be corrupted or something. The error makes it sound like the files are non-existent, but I don't know why that would be.
I had it working at one point by sending the data through regular form submission, but I need to be able to do a .then() statement when it's finished sending the email, and I don't know how to do that with regular form submission. If you can tell me how that works, I'll also accept it as an answer.
Here's my relevant code:
Fetch Request:
handleSubmit = async (e) => {
e.preventDefault()
try {
const formData = new FormData()
for (let value in this.state.formValues ) {
formData.append(value, this.state.formValues[value])
}
formData.append('essay', document.getElementById('essay').value)
formData.append('recLetter1', document.getElementById('recLetter1').value)
formData.append('recLetter2', document.getElementById('recLetter2').value)
await fetch('/', {
method: 'POST',
body: formData
})} catch (err) {
console.log(err)
}
}
Server Side POST handling:
const express = require('express')
const sendMail = require('./mail')
const multer = require('multer')
const upload = multer({dest: './uploads/'})
const app = express()
const PORT = process.env.PORT || 4000
const cpUpload = upload.fields([{name: 'essay', maxCount: 1}, {name: 'recLetter1', maxCount: 1}, {name: 'recLetter2', maxCount: 1}])
const path = require('path')
const cors = require('cors')
app.use(express.urlencoded({
extended: false
}))
app.use(express.json())
app.use(cors())
app.use(express.static(path.join(__dirname, 'client/build')))
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, 'client/build/index.html'))
})
app.post('/', cpUpload, (req, res) => {
sendMail(req.files['essay'][0], req.files['recLetter1'][0], req.files['recLetter2'][0], req.body, (err) => {
if(err) {
res.status(500).json({message: 'Internal Error'})
}
})
})
app.listen(PORT, () => {
console.log(`Listening on port ${PORT}`)
})
sendMail Function:
const sendMail = (file1, file2, file3, info) => {
const mailOptions = {
from: process.env.GMAIL_USER_NAME,
to: process.env.GMAIL_USER_NAME,
subject: `New Applicant, ${info.studentFirstName} ${info.studentMI} ${info.studentLastName}`,
text:
`New Applicant - \n
*Name*: ${info.studentFirstName} ${info.studentMI} ${info.studentLastName}
*Phone Number*: ${info.studentPhone}
*Date of Birth*: ${info.studentDOB}
*Address*: ${info.studentAddress} ${[info.studentAddress2] ?
info.studentAddress2 : ''}
${info.studentCity}, ${info.studentState}, ${info.studentZip}
// (There's more but I'm sure you get the idea)
attachments: [
{
filename: `${info.studentFirstName}${info.studentLastName}essay.pdf`,
content: file1,
contentType: 'application/pdf'
},
{
filename: `${info.studentFirstName}${info.studentLastName}recLetter1.pdf`,
content: file2,
contentType: 'application/pdf'
},
{
filename: `${info.studentFirstName}${info.studentLastName}recLetter2.pdf`,
content: file3,
contentType: 'application/pdf'
},
]
}
The Error I keep getting:
TypeError: Cannot read property '0' of undefined
at C:\Users\brand\OneDrive\Documents\GitHub\ShatteredCeilingWebsite\scweb\index.js:24:32
at Layer.handle [as handle_request] (C:\Users\brand\OneDrive\Documents\GitHub\ShatteredCeilingWebsite\scweb\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\brand\OneDrive\Documents\GitHub\ShatteredCeilingWebsite\scweb\node_modules\express\lib\router\route.js:137:13)
at Array.<anonymous> (C:\Users\brand\OneDrive\Documents\GitHub\ShatteredCeilingWebsite\scweb\node_modules\multer\lib\make-middleware.js:53:37)
at listener (C:\Users\brand\OneDrive\Documents\GitHub\ShatteredCeilingWebsite\scweb\node_modules\on-finished\index.js:169:15)
at onFinish (C:\Users\brand\OneDrive\Documents\GitHub\ShatteredCeilingWebsite\scweb\node_modules\on-finished\index.js:100:5)
at callback (C:\Users\brand\OneDrive\Documents\GitHub\ShatteredCeilingWebsite\scweb\node_modules\ee-first\index.js:55:10)
at IncomingMessage.onevent (C:\Users\brand\OneDrive\Documents\GitHub\ShatteredCeilingWebsite\scweb\node_modules\ee-first\index.js:93:5)
at IncomingMessage.emit (events.js:388:22)
at endReadableNT (internal/streams/readable.js:1336:12)
I think that's all I need to show, but let me know if I missed anything crucial. I've tried setting the Content-Type to both multipart/form-data and undefined, I tried setting the Accept header to '/', I've tried all kinds of combinations of selecting the req.files in the post handler, (That's how the email sometimes goes through with corrupted files), I don't know what to do anymore. Can someone please help me?
Figured it out. I was using document.getElementById('file').value when I should've been using document.getElementById('file').files[0]

Issue with posting data to external API using Node and Express

I am trying to post data from my form to MailChimp API server with node.js and express. However, I am getting an error message that seems strange to debug. I have checked my index.html file and all is well there. Please help me figure out a solution or point me in the right direction. Kindly check out my code below:
const express = require("express");
const bodyParser = require("body-parser");
const https = require("https");
const app = express();
app.use(bodyParser.urlencoded({extended:true}));
app.use(express.static("public"));
app.listen(3000, function(){
"Server is running on Port 3000!"
});
app.get("/", function(req, res){
res.sendFile(__dirname + "/signup.html");
});
app.post("/", function(req, res){
const firstName = req.body.firstName;
const lastName = req.body.lastName;
const email = req.body.email;
console.log(firstName, lastName, email);
var data= {
members: [
{
email_address : email,
status : "subscribed",
merge_fields : {
FNAME : firstName,
LNAME : lastName
}
}
]
};
var jsonData = JSON.stringify(data);
const url ="https://us10.api.mailchimp.com/3.0/lists/{apikey}";
const options = {
method: "post",
auth: "xxxx:xxxx"
}
const request= https.get(url, options, function(response){
response.on("data", function(data){
console.log(JSON.parse(data));
})
})
request.write(jsonData);
request.end();
});
This is the error I am getting.
events.js:200
throw er; // Unhandled 'error' event
^
Error [ERR_STREAM_WRITE_AFTER_END]: write after end
at write_ (_http_outgoing.js:594:17)
at ClientRequest.write (_http_outgoing.js:586:15)
at C:\Users\Iredafe\Desktop\Web Development practice\Email-List\app.js:48:9
at Layer.handle [as handle_request] (C:\Users\Iredafe\Desktop\Web Development practice\Email-List\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Iredafe\Desktop\Web Development practice\Email-List\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\Iredafe\Desktop\Web Development practice\Email-List\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\Iredafe\Desktop\Web Development practice\Email-List\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\Iredafe\Desktop\Web Development practice\Email-List\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\Iredafe\Desktop\Web Development practice\Email-List\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\Iredafe\Desktop\Web Development practice\Email-List\node_modules\express\lib\router\index.js:275:10)
Emitted 'error' event on ClientRequest instance at:
at writeAfterEndNT (_http_outgoing.js:649:7)
at processTicksAndRejections (internal/process/task_queues.js:82:21) {
code: 'ERR_STREAM_WRITE_AFTER_END'
}
[nodemon] app crashed - waiting for file changes before starting...
You can use axios for simplicity.
const axios = require('axios');
const headers = {
'Content-Type': 'application/json',
'Authorization': 'JWT fefege...'
}
axios.post(url,postPayload,headers)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});
I just found the answer. It was a bug in my code. I am using the native https method in Node hence I ought not to use https.get here:
const request= https.get(url, options, function(response){
response.on("data", function(data){
console.log(JSON.parse(data));
})
})
request.write(jsonData);
request.end();
the correct code that solved the problem was using the http.request instead of http.get:
const request= https.request(url, options, function(response){
response.on("data", function(data){
console.log(JSON.parse(data));
})
})
request.write(jsonData);
request.end();
Hope it helps someone in the future!

How to fix "SyntaxError: Unexpected token o in JSON at position 1" in NodeJS/Express server

I'm sending a network POST request from a javascript function to a node.js server. I get this error response on the front-end:
Access to fetch at
'https://server.herokuapp.com/connect/link' from
origin 'http://localhost:8888' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
javascript that uses fetch() to make a call looks like this:
function submitId() {
$("#progress-label").text("Working...")
const request = {
method: "POST",
body: {
docId: $('#id').val(),
stripeId: USER_ID
},
mode: 'cors',
headers: { 'Content-Type': 'application/json'}
}
fetch(SERVER_URL + "/link", request).then(res => {
document.getElementById("label").innerHTML = res.msg
}).catch(err => {
document.getElementById("label").innerHTML = res.msg
})
}
Node.js server:
var express = require('express'),
stripeConnect = require('./routes/connect'),
cors = require('cors'),
bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cors());
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', 'true');
next();
});
app.use('/connect', connect);
app.listen(process.env.PORT || 5000);
routes/connect.js looks like:
const express = require('express');
const router = express.Router();
const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.cert({
projectId: process.env.projectId,
clientEmail: process.env.clientEmail,
privateKey: process.env.privateKey.replace(/\\n/g, '\n'),
clientId: process.env.clientId
}),
databaseURL: process.env.databaseURL
});
const STRIPE_SK = 'sk_test_KEY';
const stripe = require('stripe')(STRIPE_SK);
// #route POST /stripeConnect/link
// #desc save stripe user account id to their firebase profile
// #access public
router.post('/link', (req, res) => {
console.log('\nSTRIPE-LINK-REQUEST-BODY => ');
console.log(req.body);
return admin
.firestore()
.collection('users')
.doc(req.body.docId)
.update({ stripeId: req.body.stripeId })
.then((success) => res.json({ msg: 'Stripe account ID added to profile.' }))
.catch((err) => res.json({ msg }));
});
module.exports = router;
the error I receive server-side is:
SyntaxError: Unexpected token o in JSON at position 1
2020-03-13T00:10:29.151249+00:00 app[web.1]: at JSON.parse
() 2020-03-13T00:10:29.151251+00:00 app[web.1]: at
parse (/app/node_modules/body-parser/lib/types/json.js:89:19)
2020-03-13T00:10:29.151251+00:00 app[web.1]: at
/app/node_modules/body-parser/lib/read.js:121:18
2020-03-13T00:10:29.151251+00:00 app[web.1]: at invokeCallback
(/app/node_modules/raw-body/index.js:224:16)
2020-03-13T00:10:29.151251+00:00 app[web.1]: at done
(/app/node_modules/raw-body/index.js:213:7)
2020-03-13T00:10:29.151252+00:00 app[web.1]: at
IncomingMessage.onEnd (/app/node_modules/raw-body/index.js:273:7)
2020-03-13T00:10:29.151253+00:00 app[web.1]: at
IncomingMessage.emit (events.js:323:22)
2020-03-13T00:10:29.151253+00:00 app[web.1]: at endReadableNT
(_stream_readable.js:1204:12) 2020-03-13T00:10:29.151253+00:00
app[web.1]: at processTicksAndRejections
(internal/process/task_queues.js:84:21)
How can I fix this to successfully submit the post request?
Your server-side error does not indicate a CORS error. That indicates a JSON parsing error.
It appears to me that you are not correctly sending JSON content so the recipient is getting a JSON parsing error. With fetch(), you have to manually turn your data into JSON before sending. Change this:
body: {
docId: $('#id').val(),
stripeId: USER_ID
},
to this:
body: JSON.stringify({
docId: $('#id').val(),
stripeId: USER_ID
}),
See JSON sending example on MDN.

Node/Mongoose Error: ValidationError

This is my server.js. When I run node server.js then use PostMan to post json, it gives me the following error.
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
app.use(bodyParser.json())
app.get('/api/posts', function(req, res) {
res.json([
{
username: '#rodandrew95',
body: 'node rocks!'
}
])
})
app.listen(3000, function() {
console.log('Server listening on', 3000)
})
var Post = require('./models/post')
app.post('/api/posts', function(req, res, next) {
// console.log('post received')
// console.log(req.body.username)
// console.log(req.body.body)
// res.sendStatus(201)
var post = new Post({
username: req.body.username,
body: req.body.body
});
post.save(function (err, post) {
if (err) { return next(err) }
res.sendStatus(201).json(post)
})
})
The error:
(node:6863) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
ValidationError: Post validation failed
at MongooseError.ValidationError (/Users/andrewrodrigues/Desktop/write_modern/ch_1/node_modules/mongoose/lib/error/validation.js:23:11)
at model.Document.invalidate (/Users/andrewrodrigues/Desktop/write_modern/ch_1/node_modules/mongoose/lib/document.js:1486:32)
at /Users/andrewrodrigues/Desktop/write_modern/ch_1/node_modules/mongoose/lib/document.js:1362:17
at validate (/Users/andrewrodrigues/Desktop/write_modern/ch_1/node_modules/mongoose/lib/schematype.js:705:7)
at /Users/andrewrodrigues/Desktop/write_modern/ch_1/node_modules/mongoose/lib/schematype.js:742:9
at Array.forEach (native)
at SchemaString.SchemaType.doValidate (/Users/andrewrodrigues/Desktop/write_modern/ch_1/node_modules/mongoose/lib/schematype.js:710:19)
at /Users/andrewrodrigues/Desktop/write_modern/ch_1/node_modules/mongoose/lib/document.js:1360:9
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
I'm trying to learn the MEAN stack through "Write Modern Web Apps with the MEAN Stack" but I'm running into issues all the time, even when I follow the code and instructions exactly. Can anyone help understand this error, and possibly recommend some good resources for learning the mean stack?
This error is triggered because you have provided a mongoose validation in
your schema (in /models/post) and that validation is failing.
For instance, if you provided your model like this :
var postSchema = new Schema({
"username": String,
"body": String,
"email": {
type: String,
required: true
}
});
var Post = mongoose.model('Post', postSchema);
This would fail because email required validator is not respected. Find a full list of validators here.
Side note : res.sendStatus(201).json(post) will set the json body and content-type header after sending a response with 201 status. To send both use :
res.status(201).json(post)

Categories

Resources