Angular2 http.post not working - node.js

Service:
postJson() {
var json = JSON.stringify({
"key": "CT",
"values": ["FSP", "HMC", "PHYP","hell"]
});
let headers = new Headers({'Content-Type':'application/json'});
//let options = new RequestOptions({headers: headers});
//headers.append('Access-Control-Allow-Origin', '*');
return this._http.post('http://localhost:8080/add',json,headers)
.map(res => res.json());
}
Component:
postData;
onTestPost() {
this._httpService.postJson()
.subscribe(
data=> this.postData = JSON.stringify(data),
error=> alert(error),
() => console.log("finished")
)
}
Node.js Script
var express = require('express');
var path = require('path');
var app = express();
var fs = require("fs");
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use("/node_modules", express.static('node_modules'));
console.log( __dirname);
app.post('/add', (req, res) => {
console.log('Received request'+JSON.stringify(req.body));
fs.writeFile(__dirname + '/CTRoot/data.json', JSON.stringify(req.body), (err) => {
//if (err) throw err;
console.log('File written to JSON.json');
res.setHeader('Access-Control-Allow-Origin', '*')
//Add as many Headers as you want to line below
//If you use "Authentication" Header, insert it like 'Content-type, Authentication'
res.setHeader('Access-Control-Allow-Headers', 'Content-type')
res.setHeader("Content-type", "application/json");
res.setHeader('Access-Control-Allow-Methods',
'GET,PUT,POST,DELETE,OPTIONS')
res.send('File written to JSON.json')
})
});
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
I have tried adding many headers, but it's not working.
following output is coming
File written to JSON.json
req.body is coming empty, but in web network request header and body is as expected

Why are you using JSON.stringify to create the request body? that makes the request body type text instead of application/json.
So try:
postJson() {
let json = {
"key": "CT",
"values": ["FSP", "HMC", "PHYP","hell"]
};
let headers = new Headers({'Content-Type':'application/json'});
return this._http.post('http://localhost:8080/add',json,headers)
.map(res => res.json());
}
I ran a quick test trying to send request body as text, where my api expects application/json, I get this error back:
{"code":500,"message":"Content type 'text/plain;charset=UTF-8' not supported"}

Related

Angular post request to NodeJS JSON error

So i am sending a POST request to a nodeJS app, my request in Angular looks like this:
export class SearchComponent {
constructor(private http: HttpClient) {}
newWord = '';
keyword = '';
onClick() {
const headers = new HttpHeaders()
.set('Authorization', 'my-auth-token')
.set('Content-Type', 'application/json');
this.http
.post('http://localhost:3000/search', JSON.stringify(this.keyword), {
responseType: 'text',
headers: headers,
})
.subscribe((data) => {
this.newWord = data;
});
}
}
When i try to console.log the request i get an Unexpected token " in JSON at position 0 error even though i tried all the solutions i could find on stackoverflow this is how my NodeJS app is set and the error:
const bodyParser = require("body-parser");
const express = require("express");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.all("/*", function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
res.header(
"Access-Control-Allow-Headers",
"Content-Type, Authorization, Content-Length, X-Requested-With"
);
next();
});
app.listen(3000, () => {
console.log("Server is running on port 3000");
});
app.post("/search", (req, res) => {
res.send(req.body);
});
The error i get is this:
SyntaxError: Unexpected token " in JSON at position 0
at JSON.parse (<anonymous>)....
Note that the this.keyword gets its value from a input field if i dont use JSON.stringify no error is happening but the req variable is "undefined".
Assuming you are asking how to get back the data. I'm not sure if this will work, but you can give it a try:
Under comments, see that you mean this.keyword. Here is the change I would make
going by axis format, this may be incorrect
.post('http://localhost:3000/search', JSON.stringify(this.keyword), {
responseType: 'text',
headers: headers,
})
instead, try:
.post('http://localhost:3000/search', {
keyword: this.keyword, // changed this
responseType: 'text',
headers: headers,
})
also in your server, you can change to this:
const app = express();
app.use(express.json())
app.use(express.text())
app.use(express.urlencoded({ extended: true }))
(body parser included in express now)
new to the mern stack (have never used Angular) so kind of iffy but hopefully that can help

Message received from background. Values reset

I'm sending post request from "angular->port 4200" to "expressjs server->port 8000".
As an example i'm folowing this example: https://github.com/kuncevic/angular-httpclient-examples/blob/master/client/src/app/app.component.ts
I'm getting two error :
1)undefined from Nodejs(data and req.body.text)
2)Message received from background. Values reset
Angular side:
callServer() {
const culture = this.getLangCookie().split("-")[0];
const headers = new HttpHeaders()
headers.set('Authorization', 'my-auth-token')
headers.set('Content-Type', 'application/json');
this.http.post<string>(`http://127.0.0.1:8000/appculture`, culture, {
headers: headers
})
.subscribe(data => {
});
}
expressjs side:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
var path = require('path');
app.all("/*", function(req, res, next){
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
next();
});
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
app.post('/appculture', function (req, res) {
var currentCulture = `${req.body.text} from Nodejs`;
req.body.text = `${req.body.text} from Nodejs`;
res.send(req.body)
})
app.listen(8000, () => {
console.log('server started');
})
Either you are not sending anything of there is no value in body.text
Try to console.log(req.body) instead of req.body.text.
Try to console.log(culture) and this.getLangCookie() on the client side to see if you are actually sending something.
You can also make use of the network tab in the browser to inspect the request that you are sending.
Angular side:
callServer() {
const culture = this.getLangCookie().split("-")[0];
const headers = new HttpHeaders()
headers.set('Authorization', 'my-auth-token')
headers.set('Content-Type', 'application/json');
this.http.get(`http://127.0.0.1:8000/appculture?c=` + culture, {
headers: headers
})
.subscribe(data => {
});
}
Nodejs side:
app.get('/appculture', function (req, res) {
currentCulture = req.query.c;
res.send(req.body)
})

Post req.body is always empty object

I'm using Typescript Fetch wrapper to do post and get requests and getting empty object on post(get works fine) (Before I used Vanilla Js and all worked fine)
Nodejs:
const express = require('express');
const fs = require('fs');
const app = express();
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept'
);
next();
});
app.use(express.json());
app.post('/login', (req, res) => {
let isLogged = login(req.body);
console.log(req.body);
res.status(200).json(isLogged);
});
My Typescript fetch Wrapper:
async function fetchWrapper<T>(path: string, config: RequestInit): Promise<T> {
const request = new Request(path, config);
const response = await fetch(request);
if (!response.ok) {
throw new Error(
`name: ${response.status}, message: ${response.statusText}`
);
}
// return empty object
return response.json().catch(() => ({}));
}
export async function post<T, U>(
path: string,
body: T,
config?: RequestInit
): Promise<U> {
const init = { method: 'post', body: JSON.stringify(body), ...config };
return await fetchWrapper<U>(path, init);
}
my post request:
const res = await fetch.post(`${url}/login`, {
body: inputData,
headers: { 'Content-Type': 'application/json' },
});
input data is not empty
The problem here that you are using wrong Content-Type header value. express.json parses application/json content type, while you are sending application/x-www-form-urlencoded. The solution is either to change the content-type you are sending, or add another middleware like bodyparser to parse application/x-www-form-urlencoded body.

Node JS header problems with ionic

So i am using ionic framwork to make my app and using nodeJS as my backend but i am still a noob in this and i can't seem to figure it out still after 4 days so hopefully someone could answer this problem to me and why would be appreciated.
So for my ionic client side i do this to make a http.post request
progress() {
var headers = new HttpHeaders();
headers.append('Accept', 'application/json');
headers.append('Content-Type', 'application/json');
let options = {headers: headers};
let postData = {
username: this.username,
email: this.email,
password1: this.password1,
password2: this.password2
};
this.http.post('localhost:4000/api/users', postData, options,).subscribe(
data => {
console.log(data);
},
error => {
console.log(error);
});
}
and this is what i am doing to get the data from the server but that's not working
// Packages
let express = require('express');
var request = require('request');
var bodyParser = require('body-parser');
var cors = require('cors');
const app = express();
app.use(cors({origin: 'http://localhost:8100'}));
const port = 4000;
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// Whenever you enter localhost:4000/ //
app.get('/', function (req, res) {
res.send(('Server runs'));
});
app.listen(port, () => console.log(`app listening on port ${port}!`));
app.get('/api/users', (req, res) => {
res.send('api/users page');
request.get({
uri: 'http://localhost:8100/create-account'
}, function (err, res, body) {
console.log('error:', err); // Print the error if one occurred and handle it
console.log('statusCode:', res && res.statusCode); // Print the response status code if a response was received
res.send(body);
});
});
i also tried 'http://localhost:8100' & 'localhost:8100'
so someone help me
You need to add a handler for your POST request. To do this use app.post, and it looks like this
app.post('/api/users', (req, res) => {
// You can find your data here
const data = req.body;
console.log(data);
// Send back a response
res.sendStatus(200);
});

Receiving Multipart form data in node js

I am trying to send multipart form-data from postman to my nodejs restify server. But the request.files is coming undefined.
Below is my code and a screenshot from my postman.
//Code
var restify = require('restify');
var os = require('os');
var server = restify.createServer({
name: 'New App',
version: '1.0.0'
});
server
.use(restify.acceptParser(server.acceptable))
.use(restify.fullResponse())
.use(restify.bodyParser({mapParams: true,
mapFiles: true,
keepExtensions: true,
uploadDir: os.tmpdir()
}));
server.post({path: '/api/image', version: '1.0.0'},controllers.image.addImage);
exports.addImage = function (req, res, next) {
console.log("Files : "+req.files);
}
OutPut :
Files : undefined
screenshot :
https://i.stack.imgur.com/0hTX0.png
You can use restify-multipart-body-parser - see:
https://www.npmjs.com/package/restify-multipart-body-parser
Simply use : https://www.npmjs.com/package/multi-part-form-data-upload
It automatically parse files and another type of multipart data:
// Express
const uploader = require('multi-part-form-data-upload')(options /* config options */ );
const app = express();
app.post('/uploads',uploader, (req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ body: req.body }));
});
// OR Http
const http = require('http');
const uploader = require('multi-part-form-data-upload')(options /* config options */ );
const server = http.createServer(async (req, res) => {
if (req.url === '/uploads' && req.method.toLowerCase() === 'post') {
await uploader(req, res, () => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ body: req.body }));
});
return;
}
}

Resources