Can't get response body in Axios with express - javascript

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);
});

Related

detect a request using NodeJS without express or accessing the request object outside an express middleware [duplicate]

This question already has answers here:
Access current req object everywhere in Node.js Express
(2 answers)
Closed 8 months ago.
This post was edited and submitted for review 8 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I have the following lines of code:
const express = require('express');
const app = express()
// ... defining the routes, app.get('/api/users', (req, res, next)=>{ }) ...etc
app.listen(3000, ()=> console.log('Listening on port 3000...'))
module.exports = app
I want to be able to read the request object outside an express middleware.
I have another file called mongoose_models.js, inside that file, I don't have the access to the express middleware arguments (req, res, next).
And the only option I have for reading the request body from that file is to import the app and somehow read the request Object.
NodeJs is event-driven, so there must be a way somehow to do so, for instance, inside the file mongoose_models.js I would have maybe something like this code:
// mongoose_models.js
// ... some code
const app = require('../app.js')
app.on('request', (req)=>{
// here I have the request
})
or maybe if express supports:
// mongoose_models.js
// ... some code
const { req } = require('express')
console.log(req.body) // ? maybe something like that ?
or maybe if express supports too:
// mongoose_models.js
// ... some code
const app = require('../app.js')
app.onRequest((req, res) => {
// here I have the access to the request object
})
Is there a way to reach the request object without having to be inside an express middleware in NodeJS?
edit:
Some of you asked me to provide the source code, unfortunately, I wanted to provide a stackblitz or code sandbox instance, but I didn't know how to set up the connections to the database.
Anyway, the following is the file structure of the sample project:
app.js file (full code):
const express = require('express')
const app = express()
const mongoose = require('mongoose')
const RoomModel = require('./mongoose_models')
app.use((req, res, next) => {
// this middleware is the "protect" middleware, it validates a JWT (JSON web token), decodes it, and then stores the user it finds to the req object:
// .... etc some code
// decode the JWT .. some code
// find the user in the DB const userDoc = await UserModel.findOne({ _id: decodedJWT.id )})
const userDoc = {
id: 'abc-123-edf-cds-123-321-qu5-eu4-dc9-182',
name: 'Murat',
// and some other fields ... etc
}
req.$loggedInUser = userDoc
})
app.get('/rooms', async(req, res, next) => {
const docs = await RoomModel.find({})
res.status(200).json({
message: 'here are all the rooms',
results: docs.length,
data: docs,
})
})
app.post('/rooms', async(req, res, next) => {
const doc = await RoomModel.create(req.body)
res.status(201).json({
message: 'the new room which got created:',
data: doc,
})
})
// connecting to the database:
mongoose.connect(
'mongodb+srv://USERNAME:PASSWORD#YOUR_CLUSTER.mongodb.net/?retryWrites=true&w=majority'
)
// starting the HTTP service:
app.listen(3000, () => console.log('app listening on port 3000...'))
mongoose_models.js file (full code):
const mongoose = require('mongoose')
const roomSchema = new mongoose.Schema({
name: String,
by: mongoose.Schema.ObjectId,
})
roomSchema.pre('save', function(next) {
// Here I want to make the by field be the req.$loggedInUser.id but I can't because I have no way to read the request object
const doc = this
// doc.by = req.$loggedInUser.id // < ----- 👈👈👈 HERE, I can't reach the req object
next()
})
const RoomModel = mongoose.model('Room', roomSchema, 'rooms')
module.exports = RoomModel
NodeJS is event driven, so there must be a way somehow to do so, for
instance, inside the file mongoose_models.js I would have maybe
something like this code:
// mongoose_models.js
// ... some code
const app = require('../app.js')
app.on('request', (req)=>{
// here I have the request
})
This approach is, essentially, middleware. So write is as middleware.
const myMiddleware = (req, res, next) => {
// here you have the request
next(); // go to next middleware
}
module.exports = myMiddleware
Attaching something to listen for requests is done with use (for non-method specific functions) and post, get, etc. There is no on method or onRequest method.
// mongoose_models.js
// ... some code
const { req } = require('express')
console.log(req.body) // ? maybe something like that ?
The request object doesn't exist until the client makes a request to the server.
You get a new request object each time a request is made.
The server might be handling multiple requests at the same time.
So no, you can't do anything like that.
Is there a way to reach the request object without having to be inside an express middleware in NodeJS?
No.

How can I get my JSON to return in the browser?

I am building out an API using Node for the first time but a little stuck on something.
I have the following files:
My routes, routes/index.js:
const express = require('express');
const router = express.Router();
const transactionsController = require('../controllers/transactionsController');
const ordersController = require('../controllers/ordersController');
const ordersCountController = require('../controllers/ordersCountController');
router.get('/transactions', transactionsController);
router.get('/orders', ordersController);
router.get('/orders_count', ordersCountController);
module.exports = router;
My controllers, controllers/ordersCountController.js:
const ordersCountService = require('../services/ordersCountService');
const ordersCountController = async () => {
try {
const data = await ordersCountService();
console.log(data);
return data;
} catch(err) {
console.log(err);
}
};
module.exports = ordersCountController;
My service to fetch from an external API, services/ordersCountService.js:
const fetch = require('node-fetch');
const ordersCountService = async () => {
const URL = ....;
const settings = { method: 'Get'};
const res = await fetch(URL, settings);
if (!res.ok) throw new Error('Unable to retrieve data');
return await res.json();
}
module.exports = ordersCountService;
How can I pass the JSON through to the browser?
I have been trying a few things - you'll notice the return data; - but I can't figure out how to return the JSON so that it's displayed in the browser when someone visits ourdomain.com/api/orders_count.
Any suggestions as to what I am doing wrong here? I am still new to JS so sorry if I am missing something completely obvious here.
Thank you all for your time. If there is anything I can add for clarity, please don't hesitate to ask.
In your controller, ordersCountService should have 2 parameters: req and res:
The req object represents the HTTP request and has properties for the request query string, parameters, body, and HTTP headers.
The res object represents the HTTP response that an Express app sends when it gets an HTTP request.
In this case, your controller should be:
const ordersCountController = async (req, res) => {
try {
const data = await ordersCountService();
console.log(data);
res.json({data})
} catch(err) {
console.log(err);
}
};
Save it, and open the express server, and type the route url in the browser, you would see the json format.
You could find more information about Express in this article.
Express Explained with Examples - Installation, Routing, Middleware, and More

Get Request returning 404

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'})
})

How can I solve the problem with forwarding messages?

I'm created a chat-bot using 'botact' library, but
when I'm trying to verificate my bot on vk-community API working page I receive an error in 'Windows PowerShell' (Here I started the server for bot):
TypeError: Cannot read property 'fwd_messages' of undefined
at Botact.getLastMessage (C:\Users\whoami\Desktop\Bot-test\node_modules\botact\lib\utils\getLastMessage.js:2:11)
at Botact.module.exports (C:\Users\whoami\Desktop\Bot-test\node_modules\botact\lib\methods\listen.js:29:28).
The file 'getLastMessage.js' contains this code:
const getLastMessage = (msg) => {
if (msg.fwd_messages && msg.fwd_messages.length) {
return getLastMessage(msg.fwd_messages[0])
}
return msg
}
module.exports = getLastMessage
So I don't know much about botact but according to the code when you are hitting the / route, you need to pass a body containing an object property.
Now as this is bot framework for vk bots maybe it automatically sends the request body. You can make sure by logging the request body.
server.post('/', async (req,res)=>{
console.dir(req.body);
await bot.listen(req, res);
});
/lib/methods/listen.js:
const { type, secret, object, group_id } = framework === 'koa'
? args[0].request.body
: args[0].body
...
...
...
const { events, middlewares } = actions
const forwarded = this.getLastMessage(object)
Now, when you do bot.listen express passes req as first argument. and { type, secret, object, group_id } these fields get distructured from the req.body.
And then object is getting passed to the getLastMessage function.
So for the request body in minimum you would need
{ "object": {} }
Here is the 200 OK output that I got after added that to the request body from Postman
POC Code:
const express = require("express");
const bodyParser = require("body-parser");
const { Botact } = require("botact");
const server = express();
const bot = new Botact({
token: "token_for_my_group_i_just_hided_it",
confirmation: "code_for_my_group_i_just_hided_it"
});
server.use(bodyParser.json());
server.post("/",bot.listen);
server.listen(8080);

Why axios post in react is not read by the node server, when params are sent as object?

The params are sent. I can see the endpoint triggered, and dev tools display them. However, query params are not received by the server or interpreted incorrectly.
Simple axios.post:
async function login(username, password) {
return await axios.post(LOGIN_URL, {
username,
password
},
);
}
This situation is completely different if I'm just writing the query by hand, everything is received:
axios.post(LOGIN_URL + `?username=${username}&password:${password}`);
I want to use my bodyParser in educational purposes.
Interpretation is as simple as possible with just 4 logs:
function bodyParser (req, res, next) {
const body = url.parse(req.url).query;
console.log(req.url); // /auth
console.log(req.query); // {}
console.log(req.body); // undefined
console.log(req.params); // {}
res.body = body;
next();
}
The app:
import express from 'express';
import cors from 'cors';
import bodyParser from './middlewares';
import auth from "./routes/auth.route";
const app = express();
app.use('/', cors());
app.use('/', bodyParser);
app.use('/auth', auth);
export default app;
async function login(username, password) {
return await axios.post(LOGIN_URL, {
username,
password
},
);
}
That's sending username and password in the req.body. So in Node, you need to be checking req.body
A Url like so:
http://someurl.com/api?username=a&password=b
You pick those variables up in req.query.
A Url like so:
http://someurl.com/api/people/some_id_here
You pick that ID up in req.params.
I believe there is an issue with how you're calling axios.post(...). Assuming that when you call axios this way and it works:
axios.post(LOGIN_URL + `?username=${username}&password:${password}`);
The username and password variables passed to axios.post(LOGIN_URL, {username, password}) are string variables. Therefore, you forgot to key the values like so,
async function login(username, password) {
return await axios.post(LOGIN_URL, {
'username': username,
'password': password
},
);
}
Now in your bodyParser function, you should be able to access these variables passed in via req.params.username and req.params.password.

Categories

Resources