I'm creating a simple ReactJs and I created a Searchbar component that does a post request when the user types something into the searchbar. This is the function that does the call:
const searchApi = searchTerm =>
axios.post('http://localhost:3000/findMovie', {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
params: searchTerm
});
and it is being called in the onChange function like this:
handleInput = async (ev) => {
const value = ev.target.value;
const resultsBody = await searchApi(ev.target.value);
and this is what I do in my server.js file:
app.post('/findMovie', (req, res) => {
console.log('request:', req.params);
// axios.get('http://www.omdbapi.com/?apikey='+
// process.env.OMDB_API_KEY + '&s=' +)
})
I expected the console.log in the backend to show me the request parameters so that I can later do my api call to the external api and return the results, but the console.log show an empty object.
I'm quite new to this but shouldn't I do a post request for something like this? I also tried the same with a get request but it also didn't work.
Your problem is caused by naming confusion between axios and express. params property in axios is sent as search parameters in the url.
In express url search parameters are available through query property, not params. So, try this:
app.post('/findMovie', (req, res) => {
console.log('request:', req.query);
})
params property on an express request object refers to named route parameters, as in /users/:userId/edit.
More on that in express docs: https://expressjs.com/en/guide/routing.html#route-parameters
Update
Also, in order for the axios.post method to work properly, you need to change your call a little bit. It expects the post data a second argument. Since you're not sending any data in the body, you can provide an empty object:
const searchApi = searchTerm =>
axios.post('http://localhost:3000/findMovie', {} /* <-- this guy */, {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
params: searchTerm
});
Without it, your config object is wrongfully treated as post data.
Try your axios function like this, set the params property as an object:
const searchApi = searchTerm =>
axios.post('http://localhost:3000/findMovie', {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
params: { searchTerm }
});
And on the server you need to use req.query:
app.post('/findMovie', (req, res) => {
console.log('request:', req.query);
})
You should be able to get the param as req.query.searchTerm
Related
I've been trying to send a JSON data using fetch but the backend receives an empty object.
In my Client JS I have
const user = "company1";
const username = "muneeb";
const data = {user, username};
fetch("http://127.0.0.1:3000/users/api/login", {
method: 'POST',
body: JSON.stringify(data)
}).then((response) => {
console.log(response);
});
The server side has:
router.post('/users/api/login', async (req, res, next) => {
try {
// console.log(request.body);
const request = JSON.stringify(req.body);
let imageTitles = [];
console.log(request);
*its random from here on out but you get the idea*
await components.getImages(imageTitles);
const finalKey = imageTitles.join("");
let images = await components.output(req.body.user ,req.body.username);
res.send(components.jsonConverter(imageTitles, images)); //---Top priority
db.setPassword(req.body.user, req.body.username , finalKey);
} catch (err) {
console.log(err);
res.send(err).sendStatus(500);
};
})
A few things I have already tried :
It works perfectly in Insomnia(postman).
express.json() is present , it helped me go from undefined to blank JSON.
I have enabled cors settings.
That's it for now.
The body parser express.json will only be applied for requests with Content-Type: application/json. You have to add the content type to your fetch call:
fetch("http://127.0.0.1:3000/users/api/login", {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
Could someone please explain to me how this line works:
https://github.com/sveltejs/realworld/blob/master/src/routes/login/index.svelte#L13
const response = await post(auth/login, { email, password });
post is being called from utils.js, which is this:
utils.js
export function post(endpoint, data) {
return fetch(endpoint, {
method: 'POST',
credentials: 'include',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
}).then(r => r.json());
}
So the function enters here, and then fetches the endpoint provided, which was auth/login.
This confuses me becauseauth/login is not an endpoint, it's a file that exports a function, under auth/login.js. Does this second post function in auth/login.js get called automatically? I am unsure where this (req, res) gets passed in as well, since we are just fetching this file from above and not passing any arguments.
auth/login.js
import * as api from 'api.js';
export function post(req, res) {
const user = req.body;
api.post('users/login', { user }).then(response => {
if (response.user) req.session.user = response.user;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(response));
});
}
This is where the user is being set in a cookie, which my code isn't currently doing, and the session is lost upon refresh. I am trying to understand how to persist sessions in Sapper.
This line is making a call to a relative path:
const response = await post(auth/login, { email, password });
So the url that fetch is calling is something like : http://yourdomain.com/auth/login
According to the docs, what happens when a route ending in .js is called is that Sapper looks for a function with the name of the HTTP request method on that file.
More info here : sapper.svelte.dev/docs#Server_routes
I made a simple express app with the api, with the jwt authentication. I am trying to extend the app to serve pages recycling my /api/.. routes. But I cannot figure this out.
app.use('/', entry)
app.use('/myProfile', myProfile)
app.use('/api/auth', auth)
In my public folder I have entry.js which saves/retrieves the token via local storage. Script is then included into a pug template and served via '/' route
In my entry.js I have for example
function myProfile() {
const url = 'api/users/myProfile'
const token = getTokenFromLocalStorage()
const params = {
method: "get",
headers: {"x-auth-token": token}
}
fetch(url, params)
.then(res => res.json())
.then(data =>
//...now ???
)}
I'd like to get redirected to /myProfile page using pug with acquired data from response body.
You are using the myProfile function as an express middleware.
So it will be called with the request, the response and the next callback as arguments.
Once you have fetched the data you just need to send it via the response object:
function myProfile(request, response, next) {
const url = 'api/users/myProfile';
const token = getTokenFromLocalStorage();
const params = {
method: "get",
headers: {"x-auth-token": token}
};
fetch(url, params)
.then(res => res.json())
.then(data =>
response.send(JSON.stringify(data))
);
}
app.use('/myProfile', myProfile);
You're already hitting the '/myProfile' route when doing that so there is no need for redirect.
I am trying to send data through axios request to my backend script, but the body looks empty.
Here's a request sent from front-end:
axios.request({
method: 'GET',
url: `http://localhost:4444/next/api`,
headers: {
'Authorization': token
},
data: {
next_swastik: 'lets add something here'
},
}).then((res)=>{
console.log("api call sucessfull",res);
}).catch((err)=>{
console.log("api call unsucessfull",err);
this.props.toggleLoading(false);
})
Here's a back-end:
app.get('/next/api', verifyToken, function(req, res) {
console.log(req.body);
})
But I am getting {} empty body. I am getting headers and other data but not data.
GET requests should not have a body.
Change the method from 'GET' to 'POST'
Like so:
axios.request({
method: 'POST',
url: `http://localhost:4444/next/api`,
headers: {
'Authorization': token
},
data: {
next_swastik: 'lets add something here'
},
})
and change your api to expect a post
app.post('/next/api', verifyToken, function(req, res) {
console.log(req.body);
});
or
Change the data property to params
axios.request({
method: 'GET',
url: `http://localhost:4444/next/api`,
headers: {
'Authorization': token
},
params: {
next_swastik: 'lets add something here'
},
})
and change the api to log out the params
app.get('/next/api', verifyToken, function(req, res) {
console.log(req.params);
});
and like #MaieonBrix said, make sure that your headers contain the content type that you are sending.
It looks like you only have two points left to make it work :
one : the http method should be set to POST instead of GET since you want to send something.
two : you can then add the http header (like what you did with the authorization header) Content-Type: 'application/json`
On the back-end don't forget to use some kind of body parser utility package like this one : body-parser and set it up with your app.
I suppose your server is using express, here is how you will do it with express :
const express = require('express');
const app = express();
const bodyParser = require('body-parser')
const jsonParser = bodyParser.json();
app.use(jsonParser); // use it globally
app.get('your_route', jsonParser, otherMiddleware, (req, res) => ...); // use it for specific routes
/* ... rest of your code */
If you get an error that "bodyParser is deprecated", try this -
app.use(express.json()); //To parse JSON bodies (Applicable for Express 4.16+)
And use "post" method, if you want to get data from body of the HTTP request.
Try this
this.axios('realties', { params: this.filter })
I'm sending data in my React component via the Fetch API, and returning the result as JSON. When POSTED on my Express server, I use the jsonParser method from bodyParser to parse through the data, but insead I'm only getting back a empty object. I do not understand what's the issue with jsonParser, because if I use textParser, my data get sent fine.
Edit: When printing out the request (req) on the server, it is showing that nothing was received in the body. This only happens with jsonParser though, and not textParser.
Fetch:
fetch('./test',{
method: 'POST',
body: ["{'name':'Justin'}"]
})
.then((result) => {
return result.json();
})
.then((response) => {
console.log(response);
})
.catch(function(error){
//window.location = "./logout";
console.log(error);
});
Express:
app.use('/test', jsonParser, (req,res) =>{
res.json(req.body);
})
Assuming you want to post the {name: 'Justin'} object, you'll want something like
fetch('test', {
method: 'POST',
body: JSON.stringify({name: 'Justin'}),
headers: new Headers({
'Content-Type': 'application/json; charset=utf-8'
})
})
The body parameter does not accept an array (which is what you were passing).
If you did mean to post an array, simply change the body value to
JSON.stringify([{name: 'Justin'}])