how to send and fetch data from an express backend server - javascript

this is my front end
export default async function get(){
let res = await fetch('http://localhost:4000/data/');
console.log(res.json());
}
and this is my backend
const scraper = require('./scraper.js');
const express = require('express');
const app = express();
app.get('/data', (req,res)=>{
//let img = await scraper.search(req.query.item);
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
res.send("helo");
})
app.listen(4000);
everytime i try to run this code i get the error:
syntaxerror: unexpected token h in json at position 0
should be a really simple task but for some reason it just doesnt want to work.. thanks in advance!

The token "h" that the syntax error returns refers to the first letter of the string you are sending ("helo"). If you want to decode json by using res.json(), you should also be sending json in your response. Otherwise, you have to use another decoding method in React as res.text().
Take a look at the express docs here to make sure, you are sending the correct information/format.
For the React part, you can check the official Fetch docs on how to decode the response here.

You need to console.log(await res.json())

Related

The body that i am trying to send in request is not going with request

Basically, I am using Thunder Client to send the requests and I am using the post request. The failure that I am facing is that whenever I send the request and also send the body contents and have already used content-type application/json in the header and when at the request portion I try to get req.body it returns undefined. I don't know why this error is occurring. Could someone please help?
const express = require('express');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const Admin = require('../Models/Admin');
//Route 1 : Create an ADMIN Account
router.post('/createadmin', async (req, res)=>{
console.log(req.body)
res.json(req.body)
})
module.exports = router
This is a bit late so hopefully you figured it out by now, but you may need to install and then use body parser. So npm i body-parser...then you can use it as necessary demonstrated here:

I can't access my request.body object in Koa JS (I am using body parser middleware but still it's not working)

My main server.js File
const koa = require("koa");
const Router = require("koa-router");
const bodyParser = require("koa-bodyparser");
const app = new koa();
var router = new Router();
// app.use(bodyParser({ enableTypes: ["json", "text"] }));
// I have also tried passing enabletypes parameteres but it still is not working..
app.use(bodyParser());
app.use(router.routes());
app.use(router.allowedMethods());
router.post("/", async (ctx) => {
console.log(ctx);
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server started on port no ${PORT}`));
When i hit this router.post("/") end point ... just for the purpose to see my context object i console logged the context object and it shows the following in the console when I hit this endpoint using postman (i am send JSON body in the request)
My postman request
How do I access my body (JSON object) ?
To access your body object, try the following:
const body = ctx.request.body;
Secondly: because in one of the comments there was a note, why you get a 404. I guess this is because in your route you are not returning anything. So your route could look like:
router.post("/", async (ctx) => {
const body = ctx.request.body;
console.log(body);
return (true) // or whatever you want to return to the client
});
I'd suggest using something to return i.e. if you return nothing you are going to get a 404 with Koa. Just set the body of the ctx i.e. ctx.body="something here".
Other than that depending on what you are using in the app to hit it Postman may work slightly different and pass additional headers etc. I've run into this a handful of times using Thunder Client on VS Code where it works when poking it but in the app something is slightly off. I've ONLY run into this with Koa and never express so might be worth checking and logging along the way WITHIN the app.

https api request is not working with https.get(url)

I need to pull the weather API data from
https://api.weatherapi.com/v1/current.json?key=f5f45b956fc64a2482370828211902&q=London
It gives a response when pasted in the web browser as well as in postman. But, once incorporated in javascript https.get it fails by continuously loading the browsers and hanging the terminal with unwanted informations.
app.js :
//jshint esversion:6
const express = require("express");
const https = require("https");
const app = express();
app.get("/",function(req, res){
const url = "https://api.weatherapi.com/v1/current.json?key=f5f45b956fc64a2482370828211902&q=London";
https.get(url,function(response){
//console.log(response);
response.on("data",function(data){
const weatherData = JSON.parse(data);
const temp = weatherData.current.temp_c;
const weatherDescription = weatherData.current.condition.text;
});
});
res.send("Server is up and running");
});
app.listen(3000, function(){
console.log("Started on port 3000");
});
I tried the specific request that you posted using https.get() and it worked for me. So it will be difficult to figure out what is the exact problem without more information, for example about how exactly it is failing for you. What messages are you seeing on the console? How are you accessing the result of the request, so what makes you think that the request didn't work?
But apart from that, that is not how you usually make requests in Node. The "data" event may be emitted multiple times if the response arrives in multiple chunks, so the way you do it will only work if you are lucky and the response arrives in a single chunk. The proper way to do this by hand would be to listen to all "data" events, concatenate the result, and then when the "end" event is emitted, parse the concatenated data. However, it is rather uncommon to do this by hand.
A more common way to do this would be to use a library such as node-fetch to make the request for you. For example like this: fetch(url).then((res) => res.json()).then((weatherData) => { const weatherDescription = weatherData.current.condition.text; }).

node-fetch help - getting FetchError: invalid json response > body at <url> reason: > Unexpected end of JSON input

I am new to node.js and APIs so I am hoping someone can help! I am trying to use node-fetch to get JSON data from the fantasy premier league API. I have successfully done this in the client, but from my node.js server file I keep getting the error:
UnhandledPromiseRejectionWarning: FetchError: invalid json response
body at https://fantasy.premierleague.com/api/entry/3/ reason:
Unexpected end of JSON input
The response itself has a status of 200, but the size is 0 so it is not returning any data. I know it should work, as the JSON is plainly visible when you visit the url and I have got fetch to work in the client-side code.
Here is the code I am using:
const fetch = require('node-fetch');
async function fetchEntry() {
const api_url = 'https://fantasy.premierleague.com/api/entry/3/';
const fetchEntry_response = await fetch(api_url);
const json = await fetchEntry_response.json();
console.log("json: " + JSON.stringify(json));
};
fetchEntry();
Note: On the client-side code I got a CORS error so needed to use a proxy (https://thingproxy.freeboard.io/fetch/https://fantasy.premierleague.com/api/entry/3/) to get it to work. I'm not sure if this is relevant?
Any help would be greatly appreciated!
Joe
Don't ask me why but adding a 'User-Agent' header seems to fix it:
const response = await fetch(URL, {
headers: {
'User-Agent': 'ANYTHING_WILL_WORK_HERE'
}
});
I think the api you're using is the problem. I tried to make it work, but got the same error. Also tried to use axios but it's the same thing.
I tried to fetch data with Postman and it worked perfectly, so.. my guess is that the api you're trying to use does not support all origin, since the API I tried to use works perfectly with your code.
const api_url = "https://randomuser.me/api";
I was facing the same problem when running the test cases. In my test case, there was the API call and I have used the useEffect react hook for updating the state.
useEffect(() => {
getDetailsFromAPI("param")
}, []);
So, While running the test case, I was getting the same error
FetchError: invalid json response body at reason: Unexpected end of JSON input
at ../../node_modules/node-fetch/lib/index.js:272:32
For solving this error I have mock the promise in the test case, which resolved my issue.
import fetch from 'node-fetch';
const mockJsonPromise = Promise.resolve(mydata); // 2
const mockFetchPromise = Promise.resolve({ // 3
json: () => mockJsonPromise,
ok: () => true
});
fetch.mockImplementation(() => mockFetchPromise);

Confused about how to get req.body

I cannot seem to get the body data shown on my server. I am actually trying to get this in post/put/fetch calls, but to try to fix the problem, i've boiled it down to a simple .get, and it still won't appear. Can anyone see why the body isn't showing on the server? I'm unable to get anything done in more complicated called due to this (like get the body of the req, but sticking to this simple example for now.)
This code is a fully working and sends data, just cant seem to access the body on the server.
server.js
const express = require('express');
const app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
const port = process.env.PORT || 8000;
const Cat = require('./Cat');
const Dog = require('./Dog');
app.route('/animals')
.get(function (req, res) {
console.log(req.body, 'req.body log'); //this returns {}
res.send({ Cat, Dog });
})
app.listen(port, () => console.log(`Listening on port ${port}`));
In react, if I call the following callApi() function, console.log shows the body data just fine on the front end, and the data can be used on the page.
client call
callApi = async () => {
const response = await fetch('/animals');
const body = await response.json();
console.log(body) //shows all the data just fine!
if (response.status !== 200) throw Error(body.message);
return body;
};
Using node 9 and express 4.
I think you're confusing the request and response objects. But aside from that, I'll explain where/how to get data passed in from GET and POST/PUT requests.
When a GET request is made, you can pass data to the server via query params (i.e. /animals?type=cat). These parameters will be available already parsed in an object called req.query.
When a POST or PUT request is made, and you've applied the body parsing middleware (which you have done), the JSON will be available as a parsed object under req.body.
In your example, you have made a GET request, and have no provided any query string parameters. So req.body will return an empty object, as will req.query.
Your client call shows data because you've sent data back in the response via res.send(). This is totally unrelated to why req.body is an empty object in your case.
Try using fetch('/animals?type=cat') in your client call. Then, you will see that req.query returns { type: 'cat' }.

Categories