I am trying to pass data to my Node.js backend in order to use it in a get request to an API.
For example:
Server.js
const PORT = 8000
const axios = require('axios').default
const express = require('express')
const app = express()
const cors = require('cors')
app.use(cors())
require('dotenv').config()
app.use(express.json())
app.get('/convertedAmount', (req, res) => {
const contentBody = req.body
const options = {
method: 'GET',
url: 'https://currency-converter5.p.rapidapi.com/currency/convert',
params: {format: 'json', from: contentBody.primaryCurrency, to:
contentBody.secondaryCurrency, amount: contentBody.primaryCurrencyAmount},
headers: {
'x-rapidapi-host': process.env.RAPIDAPI_HOST,
'x-rapidapi-key': process.env.RAPIDAPI_KEY,
},
}
axios
.request(options)
.then((response) => {
res.json(response.data)
})
.catch((error) => {
console.error(error)
})
})
app.listen(PORT, () => console.log(`server running on PORT ${PORT}`))
The issue is, I don't know how to pass data to the backend from the frontend, without making it a POST request. But that doesn't work if I make a POST request to the rapidAPI url. So the backend needs to stay the same.
My question is, how would I write the frontend part for this?
Using a POST request in the frontend sends the data with the req.body, but I cant get the data to display in my browser on localhost:8000/convertedAmount.
Thank you
My attempt is:
Frontend.js
...
axios.post('/convertedAmount', {
primaryCurrency: 'USD',
secondaryCurrency: 'GBP',
primaryCurrencyAmount: 1
})
.then((response) => {
console.log(response);
}, (error) => {
console.log(error);
})
...
You shouldn't be trying to send data in the body (such as in req.body) through a GET request. That is what a POST request is for.
With a GET request, you should pass data (such as a user id) as a parameter. Basically, in the url string.
FRONTEND
axios.get("/convertedAmount/USD/GBP/1")
BACKEND
app.get("/convertedAmount/:primaryCurrency/:secondaryCurrency/:primaryCurrencyAmount", (req, res)=>{
console.log(req.params.primaryCurrency);
console.log(req.params.secondaryCurrency);
console.log(req.params.primaryCurrencyAmount);
});
Alternatively, you could use query strings, which would look like this:
FRONTEND
axios.get("/convertedAmount?primaryCurrency=USD&secondaryCurrency=GBP&primaryCurrencyAmount=1")
BACKEND
app.get("/convertedAmount*", (req, res)=>{
console.log(req.query.primaryCurrency);
console.log(req.query.secondaryCurrency);
console.log(req.query.primaryCurrencyAmount);
});
Related
I have this hook on react for my frontend to perform http requests to get data to show on page
useEffect(() => {
const options = {
method: "GET",
url: `http://localhost:8080/api/v1/postersgrid`,
params: { query: props.query },
};
axios
.request(options)
.then((res) => {
console.log(res);
setResults(res.data.results);
setTotalPages(res.data.total_pages);
setSuccessfulRequest(true);
})
.catch((err) => {
console.log(err);
setSuccessfulRequest(false);
});
}, [props.query]);
as you can see that endpoint is mine because i made a little backend for my app
const express = require("express");
const cors = require("cors");
const axios = require("axios");
const PORT = 8080;
const app = express();
app.use(cors());
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
app.get("/api/v1/postersgrid", (req, res) => {
const options = {
method: "GET",
url: `https://api.themoviedb.org/3/search/movie?api_key=${APIKEY}&query=${req.query}`,
};
axios
.request(options)
.then((response) => {
res.json(response.data);
})
.catch((error) => {
console.log(error);
});
});
this backend communicates with an api of which i have the api key.
What i want is:
frontend queries backend where api key is hidden
backend queries api and returns data to frontend
Now the problem is when i try to pass parameters from frontend to backend
const options = {
method: "GET",
url: `http://localhost:8080/api/v1/postersgrid`,
params: { query: props.query },
};
here i try to pass it to backend but as soon as i use it in the url to perform http requests to the api it's like it's undefined or null
url: `https://api.themoviedb.org/3/search/movie?api_key=${APIKEY}&query=${req.query}`,
to prove this works, if i change the query to be static
url: `https://api.themoviedb.org/3/search/movie?api_key=${APIKEY}&query=war`
everything works as intended, where am I wrong? btw I'm doing all of this instead of performing requests directly from frontend to hide my api key correctly
Had to change this
url: `https://api.themoviedb.org/3/search/movie?api_key=${APIKEY}&query=${req.query}
to this
url: `https://api.themoviedb.org/3/search/movie?api_key=${APIKEY}&query=${req.query.query}
for storage space issues i cannot save images in server so i had to store it in cloudinary
and for seo purposes I had to serve it from my domain not cloudinary's
so i thought to get img files from cloudinary and send it directly to browser (to be served from my domain name )
what i am missing is converting the img file i got from cloudinary api into the right form so i can send it using response object in nodejs
here is the code
app.get('/uploads/img/:imgName', (req, res) => {
axios.get('https://res.cloudinary.com/dkhccaa25/image/upload/blog_img/${req.params.imgName}')
.then(response => {
console.log(response);
/* how to convert response into the right format so it can be sent */
//
//
//
})
.then (response => {
/*converted response */
res.sendFile(response)
})
.catch(error => {
console.log(error);
});
how I can be able to send the file from node server to browser so it can be displayed using
<img src="img url...">
You do not have to use res.sendFile, this will require saving it to the filesystem. Basically - accept the response and pass it directly with the correct content-type header send by the upstream response to the client.
Minimal example:
const express = require('express');
const axios = require('axios');
const app = express();
app.get('/', (req, res) => {
axios.get('https://static.pexels.com/photos/45201/kitty-cat-kitten-pet-45201.jpeg').then((axiosResp) => {
res.header('content-type', axiosResp.headers['content-type']).send(axiosResp.data);
});
});
app.listen(3000);
finally the problem solved by editing on #madflow answer (thanks for him )
const express = require('express');
const axios = require('axios');
const app = express();
app.get('/', (req, res) => {
axios.get('https://static.pexels.com/photos/45201/kitty-cat-kitten-pet-45201.jpeg', {responseType: 'stream'})
.then((axiosResp) => {
res.set({
'Content-Type': axiosResp.headers['content-type']
})
axiosResp.data.pipe(res)
});
});
app.listen(3000);
I have a React web application which currently does fetch calls client-side to update a dashboard with live information (let's say current weather, as an example), meaning that with an increase in users it will cause unnecessary traffic calls and could potentially crash this weather website.
What I am trying to understand is how can I make those fetch calls be server-side? I have looked into creating a Node.js Express server, but I am unsure if it has the functionality to make fetch calls to a remote host.
Here is my code with request-weather which does not really work, unfortunately.
const { response } = require('express');
const express = require('express');
const app = express();
var fetch = require('node-fetch');
const port = process.env.PORT || 5000;
app.use(express.json());
// This displays message that the server running and listening to specified port
app.listen(port, () => console.log(`Listening on port ${port}`));
// create a GET route
app.get('/request-info', (req, res) => {
res.send({ information: 'information call successful' });
});
app.get('/request-weather', (req, res) => {
fetch('http://thisotherwebsite.com/weather-query-that-returns-json',
{method: 'GET',
headers: {' Accept': 'application/json'}})
.then(res => {
return res;
})
});
Couple things:
Your /request-weather handler makes the request to thisotherwebsite but doesn't do anything with the response.
Your .then(res => { return res; }) doesn't actually do anything. You're just taking what fetch already returns and returning it.
If you want to send the response back to the browser you might do something like this:
fetch(...) // make the request
.then(result => result.json()) // extract the data
.then(data => {
res.json(data); // send it to the browser
})
If you want to do additional processing you could await the fetch call and then do whatever else you need to do with it:
app.get('/request-weather', async (req, res) => { // make handler async
// get data from the other site
const data = await fetch(...)
.then(response => response.json());
// package it up with some other stuff
responseData = {
fromOtherSite: data,
myExpressStuff: {
foo: 1,
bar: 2,
}
}
// return it to the browser
res.json(responseData);
Reference:
fetch: response.json() - Extracting data from a fetch response
express response.json() - Sending json to the response (usually to the browser)
This question already has answers here:
How to access the request body when POSTing using Node.js and Express?
(15 answers)
Closed 2 years ago.
I am trying to send a post request using Axios and I also want to access the data from the server. My code is
axios({
method: 'post',
url: '/register/',
headers: {'Content-Type' : 'application/json'},
body: JSON.stringify({fname, lname, username, email, pass})
})
.then((res) => {
console.log(res)
})
.catch(err => {
console.log(err)
})
// and my backend code is
const express = require('express')
const router = express.Router()
router.post('/', async (req, res, next) => {
const firstname = ''
})
Request is send properly and my server also accepts the request. but i do not know how to get the values from my server.
please help me. code is working fine just help me in getting the values on server side code
Unlike fetch, axios does not require you to stringify the body of the post request. You can just post like so:
axios({
method: 'post',
url: '/register/',
headers: {'Content-Type' : 'application/json'},
body: {fname, lname, username, email, pass}
})
...
Assuming you are posting to the correct endpoint (e.g. /register), on the server side, you would access it this way:
router.post('/register', (req, res) => {
const fname = req.body.fname;
...
})
Note that this assumes your backend is properly configured. If all you're running is the code you showed, it won't work as you would need stuff like:
const app = express();
app.use(express.json());
...
...
app.listen(YOURPORT, () => {
console.log(`Listening to requests on port YOURPORT...`);
});
My server code as following:
var app = express();
app.use(express.urlencoded());
app.use(express.json());
app.post('/user', function (req, res) {
console.log("request body:"+req.body+" params:"+req.params);
})
my client code using react js as following:
handleSubmit(event) {
event.preventDefault();
const post ={
name:"Tom"
}
axios.post('http://localhost:9111/user', { post })
.then(res => {
this.setState({response:res.data})
})
}
I'm sure the server side did get the request from client, but I got 'undefined' when I tried to get the data from client request via req.body or req.params in server side code.
The second parameter to axios.post needs to have a data key. eg { data: post }