React/Express - Axios get request help needed - node.js

Trying to make an API get request from front-end (React) to back-end (Express/MongoDB) using Axios. If I use Postman to make the request it works fine (you can enter a user ID in the request body and get back an array of objects containing that user ID, which is what I want), but doing it from a front-end built in React doesn't work, I just get an empty array returned. As far as I can tell my API call from the front-end is exactly the same as the one I'm making in Postman! Can anyone shed any light on this?
This is the code making the get request from the front end:
const getActivities = async (currentUser) => {
const config = {
crossdomain: true,
headers: {
"Content-Type": "application/json"
},
body: {
"user": `${currentUser[0].id}`,
}
}
try {
const res = await axios.get('http://localhost:5000/api/activities', config)
console.log(res)
dispatch({
type: GET_ACTIVITIES,
payload: res.data
})
} catch (error) {
console.log(error)
}
}
And this is the route on the back-end handling this particular request:
router.get('/', async (req, res) => {
try {
const activities = await Activities.find({ user: req.body.user }).sort({ date: -1 })
if (!activities) {
res.json({msg: "Nothing found. Go forth and exercise!" })
}
res.json(activities).send()
} catch (err) {
res.send(err.message)
}
})
Thanks in advance!

You cannot send a request body with GET method see API AXIOS only for request methods 'PUT', 'POST', 'DELETE , and 'PATCH'.
for example if you want to keep a GET method use params
// React
const config = {
crossdomain: true,
headers: {
"Content-Type": "application/json"
},
params: {
user: `${currentUser[0].id}`,
}
}
try {
const res = await axios.get('http://localhost:5000/api/activities',config)
console.log(res.data)
}catch(err){
...
}
// Express
router.get('/', async (req, res) => {
console.log(req.query.user)
}

Related

JSON String not getting to the server (should be easy to solve if you know express js)

I am using express js but for some reason, the server is logging an empty object {} instead of the actual JSON string that I sent. I have worked with so many other technologies like flask, this makes no sense.
Code:
function upload () {
fetch("http://localhost:8080/chat", {
method: "POST",
body: JSON.stringify({
name: "Deska",
email: "deska#gmail.com",
phone: "342234553"
})
}).then(result => {
// do something with the result
console.log("Completed with result:", result);
}).catch(err => {
// if any error occured, then catch it here
console.error(err);
});
}
app.post('/chat', function(req, res) {
let test = req.body;
console.log(test);
}
On the "upload" function I do not get the anything logged, and in the server, I get the an empty object {} I mentioned.
If you are to know my issue, I would appreciate help.
Thank you.
UPDATE:
Issue should be in the prontend, as sending the post request with postman works.
I think the error could be happening because you are missing the Content-Type header. You could try this:
function upload () {
fetch("http://localhost:8080/chat", {
headers: {
'Content-Type': 'application/json',
},
method: "POST",
body: JSON.stringify({
name: "Deska",
email: "deska#gmail.com",
phone: "342234553"
})
}).then(result => {
// do something with the result
console.log("Completed with result:", result);
}).catch(err => {
// if any error occured, then catch it here
console.error(err);
});
}
You should also make sure that in your server you are using the express.json middleware, this way:
app.use(express.json());

Router.push is not redirecting me; Nextjs with Express server

I'm trying to build a basic login page with a dashboard using Express server and Nextjs. After the user logs in with proper credentials, they are authenticated and then redirected to the dashboard... Or that's what's supposed to happen at least. It seems that when Router.push("/Dashboard") is called, an improper request is made. However, if I just type http://localhost:3000/Dashboard into the address bar it works.
Get dashboard route
server.get('/Dashboard', checkSignIn, (req, res) => {
console.log("In dashboard")
if(req.session.page_views){
req.session.page_views++;
} else {
req.session.page_views = 1;
}
console.log("Page views: ", req.session.page_views)
return handle(req, res)
})
Log in and redirect from client side
const router = useRouter();
const attemptLogin = async (event: KeyboardEvent) => {
const username: string = event!.target!.username!.value;
const password: string = event!.target!.password!.value;
fetch("http://localhost:3000/SignIn", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({ username, password }),
})
.then((res) => {
if (res.status === 200) {
console.log("Status is 200");
return router.push("/Dashboard");
}
})
.catch((err) => console.log("err is", err));
};
Here is what the request looks like when I manually type http://localhost:3000/Dashboard into the address bar
And here is what the request looks like when router.push is called
Hope someone can help with this. Thanks.
Edit: I get these errors (and output) in the console while rediredirecting
So I figured out the issue. It's because I was submitting a form without calling event.preventdefault(), which I think was making an improper fetch request (hence the error above), as well as reloading the page. The new working code for attemptLogin (the function I call on form submit) is
const attemptLogin = async (event: KeyboardEvent) => {
event.preventDefault();
const username: string = event!.target!.username!.value;
const password: string = event!.target!.password!.value;
fetch("http://localhost:5000/SignIn", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({ username, password }),
})
.then((res) => {
if (res.status === 200) {
console.log("Status is 200");
return router.push("/Dashboard");
}
})
.catch((err) => {
console.log("err is", err);
event!.target!.reset();
});
};

How do I call a different REST API within a express route?

I have an express.js REST API that I have created with a variety of routes. I'd like to create a route to call another REST API and then return the result. Ideally, it should look something like the following:
router.post('/CreateTicket', cors(corsOptions), function(req, res, next) {
//make a call to another rest api and then res.send the result
}
The REST API route that I am calling is a POST request and will take in a JSON body with the information for the ticket. It then will return a JSON response containing the ticket information and ticket link.
Essentially, I just want to pass req.body as the body of the API call and then res.send() the response of the API call. I was trying to figure out some way to use fetch or requests, but was just getting confused.
Thank you so much for any help that anyone can offer!
I would suggest to use axios if you want to call the third-party API. The simple way of doing is to create an options(config) pass it to the axios object.
npm i axios --save
Axios config
const options = {
'method': 'POST',
'url': 'https://URL',
'headers': {
'Content-Type': 'application/json'
},
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
};
try {
const result = await axios(options);
console.log(result);
} catch (e) {
console.log(e);
}
In your route file:
const axios = require('axios');
const getData = async (body) => {
const options = {
'method': 'POST',
'url': 'https://URL',
'headers': {
'Content-Type': 'application/json'
},
data: {
body
}
};
try {
const result = await axios(options);
console.log(result);
return result;
} catch (e) {
console.log(e);
}
}
router.post('/CreateTicket', cors(corsOptions), async function(req, res, next) {
//make a call to another rest api and then res.send the result
try {
const response = await getData(req.body);
res.send(response);
} catch (e) {
//wrap your error object and send it
}
}
Note: if you want to pass the data to your own created route you can use res.redirect and it will send the response back. You can check the axios details in the link above.
You would have to use something like axios or http (code originates from link):
const https = require('https')
const options = {
hostname: 'example.com',
port: 443,
path: '/todos',
method: 'GET'
}
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
return d
})
}

Proxy API request through Express return pending Promise instead of response

I am currently trying to work with the Atlassian Jira rest API. In order to not get a CORS error I go through the recommended route of not sending the request from the browser but proxy it through my express server.
Now as I am doing this, all I receive back in the app is a pending promise. I assume that I have not correctly resolved it at one point but I cant figure out where.
API Handler sending the request to the proxy:
const baseURL = `${apiConfig}/jiraproxy`;
export const testConnection = integration => {
return fetch(`${baseURL}/get`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(integration)
})
.then(handleResponse)
.catch(handleError);
};
Jira Proxy Endpoint on the Express Server
const baseURL = `rest/api/3/dashboard`;
router.post("/get", (req, res) => {
fetch(req.body.link + baseURL, {
method: "GET",
headers: { Accept: "application/json" },
auth: {
username: req.body.credentials.username,
password: req.body.credentials.token
}
})
.then(handleResponse)
.catch(handleError);
});
handleResponse & handle Error Methods:
async function handleResponse(response) {
if (response.ok) {
return response.json();
}
if (response.status === 400) {
const error = await response.text();
throw new Error(error);
}
throw new Error("Network response was not ok.");
}
function handleError(error) {
// eslint-disable-next-line no-console
console.error(`API call failed. ${error}`);
throw error;
}
Goal:
Send the request of sending a request to the proxy and return the resonse of the proxy as the return of the initial "testConction" method.
Error:
No errors thrown, but the response received in the Browser is a pending promise.
Change to the Jira Proxy router fixed it. Thanks to #jfriend00.
router.post("/get", (req, res) => {
return fetch(req.body.link + baseURL, {
method: "GET",
headers: { Accept: "application/json" },
auth: {
username: req.body.credentials.username,
password: req.body.credentials.token
}
})
// This is the part that changed
.then(response => handleResponse(response))
.then(jiraResponse => res.status(200).json(jiraResponse))
.catch(handleError);
});

SurveyMonkey API Create a Survey using NodeJS

I created a small server using NodeJS/Express and I'm using node-fetch to interact with SurveyMonkeys API. I currently have two surveys on my account which I can view through their Postman collection. But when I try to use my own endpoints, it doesn't seem to work. The GET request to view all of the surveys returns a status code of "200" but responds with:
{
"size": 0,
"timeout": 0
}
The POST request to create a survey gives me a status code of "400" but returns the same response. Here is my code so far.
const router = require("express").Router();
const fetch = require("node-fetch");
const TOKEN = process.env.SM_ACCESS_TOKEN;
const BASEURL = process.env.SM_BASEURL;
const options = method => ({
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
method: method
}
});
/*
GET a list of surveys
*/
router.get("/", async (req, res) => {
try {
const surveys = await fetch(`${BASEURL}surveys`, options("GET"));
console.log(surveys);
if (surveys) {
return res.status(200).json(surveys);
}
} catch (err) {
console.log(err);
res.status(500).send({ message: "Server error", err });
}
});
router.post("/create-survey", (req, res) => {
const surveyData = req.body;
fetch(`${BASEURL}surveys`, {
method: "POST",
body: surveyData,
headers: {
Authorization: `bearer ${TOKEN}`,
"Content-Type": "application/json"
}
})
.then(data => {
return res.status(data.status).json(data);
})
.catch(err => console.log(err));
});
module.exports = router;
Additional information:
I am able to complete all of these actions using the POSTMAN collection provided by SurveyMonkey with my Access Token. BASEURL = "https://api.surveymonkey.com/v3/".
ServeyData = { "title": "Some Title" }
Resolved this issue by switching out of node-fetch and instead using axios. Could be the fetch vs xhr request I think.

Resources