Can't send JSON data via res.json - json

when I send a fetch request for JSON data, it returns the response object, but not the data itself.
Can't figure out why
I've tried added headers, stringifying the data
My Express server
const productData = require('./storeProducts.json');
app.use(cors());
app.get('/products', (req, res) => {
res.json(JSON.stringify(productData));
});
app.listen(PORT, () => console.log(`Now listening on ${PORT}`));
my fetch request
const fetchProducts = async () => {
const data = await fetch('http://localhost:3001/products');
console.log(data)
};
when I console.log the data i am receiving, instead of the JSON object, im getting
Response {type: "cors", url: "http://localhost:3001/products", redirected: false, status: 200, ok: true, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:3001/products"
proto: Response
any help would be appreciated

You need to do something like:
const fetchProducts = async () => {
let data = [];
await fetch('http://localhost:3001/products')
.then(res => res.json())
.then(response => {data = response;})
console.log(data)
};
When you use fetch, it returns an object and res.json() method extracts the JSON data from that object and returns a promise, that promise can be used to perform our operations on the result. e.g mapping data on a table, making graphs, chart, authentication etc.
Hope this solves your problem.

Related

POST Request Body is empty

Task
Parse a CSV file
Send the data to an API enpoint
Save data to MySql database
Problem
The request body is showing up empty when I send data via fetch. However, I can send and see the body data if I use Postman.
I've added a console.log(req.body) and it's printing out {} to the console.
Parse and Send Data to Endpoint
const changeHandler = (event) => {
Papa.parse(event.target.files[0], {
header: true,
skipEmptyLines: true,
complete: function (results) {
results.data.forEach(entry => {
// Create the data object.
let data = {};
let keys = ['Date', 'Description', 'Debit Amount'];
for (let key in entry) {
if (keys.includes(key)) {
data[key.toLowerCase().replaceAll(' ', '_')] = entry[key];
}
}
// Send data to server
fetch('http://localhost:3001/api/create_transactions', {
method: 'POST',
mode: 'no-cors',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
}).then(function (response) {
console.log(response);
})
});
},
});
// Reset file input
event.target.value = null;
};
Save Data to MySql
app.use(express.json());
const crypto = require('crypto');
app.post("/api/create_transactions", (req, res) => {
console.log(req.body);
/*
let hash = crypto.createHash('md5').update(req.body['date'] + req.body['description'] + req.body['debit_amount']).digest('hex');
let data = [
hash,
req.body['date'],
req.body['description'],
req.body['debit_amount'],
];
db.query('insert into transactions (`hash`, `date`, `description`, `debit_amount`) values (?, ?, ?, ?)', data, (err, result, fields) => {
if (err) {
console.log(err);
} else {
console.log(result);
res.send(JSON.stringify({"status": 200, "error": null, "response": result}))
}
});
*/
});
app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
});
According to this post Fetch: post json data, application/json change to text/plain you can not change the Content-Type to application/json if you are using no-cors. So I will have to enable cors if I want to use fetch.
Using this tutorial https://www.section.io/engineering-education/how-to-use-cors-in-nodejs-with-express/ I was able to enable cors on my nodejs server and receive the proper headers.
Try to use express's bodyParser app.use(express.bodyParser());

I need to fetch API to get a raw value from response same as the result in POSTMAN but fail?

I am new from here. Just stuck on some problem of fetching the data from frontend(react) to the raw value in JSON. For the login part, when I enter the email and password, supposedly the response are same as the result in POSTMAN, but i get the error. I am figure out this issue for almost oneweek. I would be appreciate for those who help me to solve on this issue. I will elaborate further on below about my situation:
Here is the response of API from postman (supposedly I should get this response):
The result I get in the browser:
Source Code:
constructor (props){
super(props);
this.state ={
loginEmail: '',
loginPassword: ''
}
this.login = this.login.bind(this);
this.onChange = this.onChange.bind(this);
}
login(){
PostData('api/users/login', this.state).then ((result) => {
let responseJSON = result;
console.log(responseJSON);
});
}
PostData:
export function PostData(type, userData = {}){
let BaseUrl = "https://ems-unimas-58134.herokuapp.com/"
return new Promise((resolve, reject) => {
fetch(BaseUrl+type,{
method: "POST",
body: JSON.stringify(userData),
Accept: 'application/json',
// headers:{
// 'Content-Type': 'application/json'
// }
}).then(res => res.json())
.then((responseJson) => {
resolve(responseJson);
})
.catch((error)=>{
console.error('Error:', error);
})
});
}
Commend down here if anyone of you need more code.
The problem is you need to allow CORS.
You can read more about CORS in here

keeps fetching the old json data?

I'm trying to fetch a json file from a https link however, no matter what link a give the result does not change!?
I validated all the json files. in case they had an error.
the responseData stays the same, and even when I force the data to change by instead returning responseData returning a json manually written; it changes right back to the old json data that just doesnt change when I return responseData back.
And the responseData that I requested to be be posted on the console gives the wrong information
The url given is correct.
but the output doesnt correspond to the data when I fill the link in the internetbrowser.
constructor(props){
super(props);
this.state = {
connected: false,
}
this.init = this.init.bind(this);
this.getJson = this.getJson.bind(this);
this.updateVisited = this.updateVisited.bind(this);
}
init = async ({json})=>{
if(json==null){
await AsyncStorage.setItem('database', "");
alert('error occured');
} else {
await AsyncStorage.setItem('database', JSON.stringify(json));
this.setState({
connected: true
});
}
}
getJson = async ()=>{
var url = await AsyncStorage.getItem("database_url");
console.log(url);
return fetch(url,
{
method: "GET",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(responseData => {
this.updateVisited(url);
console.log(responseData);
return responseData;
})
.catch(error => {
alert('Could not connect!');
return null;
})
}
connect = async ({url})=>{
await AsyncStorage.setItem("database_url", url);
this.getJson().then(json => this.init({json}));
}
"a_json": [{"name": "greg"}]
"test": [{"name": "sheldon"}]
"temp": [{"name": "bob"}]
when the url points to the json test it gives bob expecting sheldon
when the url points to the json temp it gives bob expecting bob
when the url points to the json a_json it gives bob expecting greg
when returning a json without trying to fetch it from the internet at the place of responseData; it gives the expecting value
If you need more information, feel free to ask.
Thank you for your time reading my question.
The problem was the Cache-Control.
I added 'Cache-Control': 'no-cache' to the header of the fetch, which fixed the problem!
This was pointed out by #Pritish Vaidya in the comments

Fetch in react with json always returns an error

For the following created code in react, after I search similar question, I get always an error (seems that the error is return of a promise).
I am using webpack version 3.1.9
In web-pack configuration I did (don't know whether it is necessary):
module.exports = {
...
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
"Access-Control-Allow-Headers": "*"
}
},
...
Here is my code:
var options = {
method: 'get',
mode: 'no-cors',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Origin': '*'
}
};
let _url = 'my url ... web api returns json';
fetch(_url, options)
.then(response =>
response
.json()
.then(data => ({
data: data,
status: response.status
}))
.catch(err =>
/******ERROR: always catch the error *****/
({ error_data: err })
)
)
.then(res => {
console.log(res);
// console.log(res.status, res.data.title)
})
.catch(err => {
console.log(err);
});
The error in the line with the asterisks, as code above
SyntaxError: Unexpected end of input at eval
The code was checked for restful api in C#:
I did in the controller code:
public ActionResult Index()
{
ActionResult x = Json(db.Trainees.ToList(),
JsonRequestBehavior.AllowGet);
//return Content(db.Trainees.ToList().ToString(),
"application/json");
return Json(db.Trainees.ToList(), JsonRequestBehavior.AllowGet);
// return View(db.Trainees.ToList());
}
I assume it is related to fact that json returns a Promise, as described in: json returns promise
I see that json is problematic. When I change response.json() to response.text() there is no error, but I realize that even I send the options with 'no-cors', I see an information message:
Cross-Origin Read Blocking (CORB) blocked cross-origin response ... with MIME type application/json
Seems that the fetch ignore the options with 'no-cors'.
Any clues, why the code encounters an error?!
Thanks.
Problem had been fixed.
In react I did the changes:
var options = {
method: 'GET',
}
...
In C# restfull api controller I did the changes:
Response.AddHeader("Access-Control-Allow-Origin", "*");
return Json(db.Trainees.ToList(), "application/json",
JsonRequestBehavior.AllowGet);

How to log Mocha/Chai HTTP requests

Hi I am new to Mocha/Chai.
I am trying to test some HTTP requests. If would be nice if I could log the actual test request to debug it.
The code I am using looks something like
describe('Get token for super user', () => {
it('it should get a valid token set', (done) => {
let req = chai.request(app)
req
.get('/oauth/token')
.set('Content-Type','application/x-www-form-urlencoded')
.set('Authorization','Basic blah')
.field('grant_type', 'password')
.field('username', superUser)
.field('password', superPass)
.end((err, res) => {
console.log('*******' , req)
res.should.have.status(200)
done()
})
})
})
How would I log the request itself, I don't see a neat way of doing this from the API docs ?
Simplest way to get and log all info about request - response object:
chai.request('http://...')
.post('/endpoint')
.send('{"a":1}')
.end((err, response) => {
console.log(response);
done();
});