I'm using the open weather API to make a get request based on a zipcode passed in as a query parameter. When I run the endpoint in Postman I receive a successful response and can see the data. When I run the request from my app (even with a hard coded value for testing) I get a 404 not found.
Endpoint from my server file:
const weatherCtlr = require('./controllers/weatherController);
app.get('/api/weather', weatherCtlr.getWeather);
My Controller
const axios = require('axios');
const {APIKEY} = process.env;
module.exports ={
getWeather :(req, res)=>{
const {zipcode} = req.body;
axios.get(`https://api.openweathermap.org/data/2.5/weather?zip=${zipcode}&APPID=${APIKEY}`)
.then(()=>{
res.sendStatus(200);
})
.catch(err=>console.log(err))
}
}
Client Side, (axios is imported)
getWeather =()=>{
const {zipcode} = this.state.canyon;
axios.get('/api/weather', {zipcode})
.then(res=> this.setState({weather: res.data)})
.catch(err=>console.log(err))
}
I call the method on an on click
onClick={()=>this.getWeather()}
I'm not really sure what the issue is. I know the api key is good because I when I test my actual endpoint localhost.../api/weather and send a zipcode in the body it works.
What stands out is that you send a body to your server using get:
getWeather =()=>{
const {zipcode} = this.state.canyon;
axios.get('/api/weather', {zipcode})
.then(res=> this.setState({weather: res.data)})
.catch(err=>console.log(err))
}
The GET method does not accept a body. Then on the server side you parse it out like this:
const {zipcode} = req.body;
I would be very surprised if you actually get that zipcode. Most likely that will be undefined.
So I would try changing your client side request to:
axios.post('/api/weather', {zipcode})
Once you get the response back from the API, you can send it back to your app like so:
axios.get(`https://api.openweathermap.org/data/2.5/weather?zip=${zipcode}&APPID=${APIKEY}`)
.then((response) => {
res.json(response.data);
})
.catch(err => {
console.log(err);
res.json({msg: 'Error'})
})
Related
I am trying to build a wikipedia web scraper api and this is my code:
const app = express()
const port = 3000
const url = "https://en.wikipedia.org/wiki/Yeti_Airlines_Flight_691"
axios.get(url).then(async (res) => {
try {
if (res.status == 200) {
const result = // Doing cheerio stuff here
app.get('/', (req, res) => {
res.status(200).send(result)
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
}
} finally {
//
}
});
How can I send url dynamically to backend using express and do some stuff then send result back to frontend?
Client side:
This is a function you define in your frontend. You set a request link, which must be known here on client side and server side. Thus take something like /request. Then use axios to send a request to the server. You can pass any parameters with „dynamic“ Information as you called it. The server will receive these informations and can handle them.
const getData = () => {
// insert your server url here instead, with the /request at the end
const requestLink = `http://localhost:3001/request`;
axios
.get(requestLink, {
params: { url: "wikipedia.de/test123" },
})
.catch((error) => {
// here you can implement error handling
console.log(error);
})
.then((res) => {
// print result, received from the server
console.log(res);
});
};
Server side:
The backend is going to wait for a request to the defined link /request.
If he receives such a request, he is executing the code. The req variable contains your dynamic data, such as the wiki url.
Use res.json to send data back to your frontend.
app.get(`/request`, (req, res) => {
// do something with the request here
console.log(req.query);
// send result to the frontend
res.json({
status: "This could be an answer to the frontend.",
});
});
My frontend code:
const user = useSelector(selectUser)
function getWatchLater(name){
axios.get('http://localhost:5000/watchlater', {user:name})
.then((response)=>{
// console.log(response.data)
setWatchLater(response.data)
})
}
The user variable holds the username and the function sends that username to the backend to get the data. Don't worry, the user variable does hold the username, i have checked it thoroughly.
My backend code:
const mysql = require('mysql2')
const express = require('express')
const cors = require('cors');
const app = express()
app.use(cors());
app.use(express.json())
app.get("/watchlater", (request, response)=>{
const user = request.body.user;
//console.log(user);
});
So basically, it will get the username and run the query. The problem is it does not get the username at all from the frontend. I tried console logging the variable user but to no avail. It returns empty.
The second argument in the axios.get() function is expecting a config object. Checkout the axios documentations on instance method and request config.
In short, in the frontend part, pass your payload into the data field of the config object, as shown in the example below.
const config = {
headers: { Authorization: token },
data: { user:name }
}
const response = await axios.get(`${url}`, config)
You need to send parameter using params object of config in case of get request. Your frontend request should change to this,
const user = useSelector(selectUser)
function getWatchLater(name){
axios.get('http://localhost:5000/watchlater', { params: { user: name }
}).then((response)=>{
// console.log(response.data)
setWatchLater(response.data)
})
}
In your express endpoint you should receive it as,
app.get("/watchlater", (request, response)=>{
const user = request.params.user;
//console.log(user);
});
i came up with this problem with ReactJS and ExpressJS: So basically user uploads some info on /info route with React & axios. then user gets route params from server side to redirect to:
axios.post('/info', SomeData)
.then(res => res.data)
.then(data =>{
window.location.replace(`/info/${data.id}`)
})
this is piece of cake but when user redirects to that page problem occurs, i need to get data from that page. i can get route params and perform request on client side like this:
componentDidMount(){
const { match: { params } } = this.props;
axios.get(`/api/info/${params.id}`)
}
but how can i get request on server side? how can express access that "id" to search it in database and query data with it to send back to client? like:
app.get('/api/info/:id', async (req,res)=>{
await db.find({id: req.params.id}, (data) =>{
res.status(200).send({data})
})
})
Any help? Thanks!
From the component itself same as the GET use your param and call your service same thing to POST
postUserInfo = () => {
const userInfo ={};
axios.post(`/api/info/${params.id}`,userInfo).then(()=>{
console.log("user info posted");
})
}
Example:
<Form onSubmit={this.postUserInfo}> </form>
I am trying to fetch data from Mongodb and i want that data to show up on my web page.The problem is i don't know how to send the whole fetched object to a specific port (the response) so that i'll be able to fetch it from Angular and how will i be able to access data from Angular
Fetching data from Mongodb
app.get('/api/getdata',async (req,res) =>
{
const {value} = req.body
const resp=await person.find({value})
if(!resp){
console.log('not found')
}
else{
//this needs to be done
}
})
Please, have a look at express API reference
then your code would look like :
app.get('/api/getdata', async (req,res) => {
const {value} = req.body
const resp = await person.find({value})
if (!resp) {
res.status(404).send('not found')
}else{
// give your data to express response to the http request
res.json(resp); // or res.send(resp);
}
});
In my Express app I am receiving a payload from an external POST request:
router.post('/liveReleaseStore', (req,res) => {
let thing = req.body.myPayload
...
I also handle a GET request from my client:
router.get('/liveReleaseStore', (req, res) => {
let myResponse = ...
res.send(myResponse);
});
I need to reroute the payload so that when my client sends a GET to the server I am able to send back the data or tell the client that I haven't received any data yet.
What is the best way to about about this?
Thanks
You could initialize the data outside the two functions to null. And then send the data if it's been initialized by the post function.
let thing = null;
router.post('/liveReleaseStore', (req,res) => {
let thing = req.body.myPayload
...
}
router.get('/liveReleaseStore', (req,res) => {
if (thing === null)
return res.send('no data yet');
res.send(thing);
}