Cannot save email in React.js + Express - node.js

So I have a function getProfile(). Inside it I am trying to fetch users from the server using a POST call, however it's throwing a CORS error in its response.
Here is the getProfile:
const getProfile = async () => {
try {
const res = await fetch("http://localhost:5000/dashboard/", {
method: "POST",
headers: {
jwt_token: localStorage.token,
"Content-Type": "application/json",
Accept: "application/json",
},
});
const parseData = await res.json();
setEmail(parseData.email);
console.log("Try success");
console.log(parseData.email);
} catch (err) {
console.log("Try failed");
console.error(err.message);
}
};

if you are handling your nodeServer by your own you need to add CORS package
please check this and follow their docs
https://www.npmjs.com/package/cors
1.install package
2. in your app.js file add following
var cors = require('cors')
app.use(cors())
and change you frontend function getProfile() to following:
const getProfile = async () => {
let token = localStorage.getItem("token");
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", "bearer" + token);
try {
await fetch("http://localhost:5000/dashboard/", {
method: "POST",
headers: myHeaders,
})
.then((r) => r.json().then((data) => ({ status: r.status, data })))
.then((obj) => obj.status === 200 && console.log("data", obj.data));
} catch (err) {
console.error("Try failed", err.message);
}
};

Related

how to use access token to call another post request?

I have this post request to get access token and its working fine but would like to know how can I use this access token to call another post request ? Or how do I use async or promises to use in this ?
Here is my code :
function getAccessToken() {
const querystring = require('querystring');
const https = require('https')
const postData = querystring.stringify({
'grant_type': 'client_credentials'
});
const options = {
"hostname":'api.xxx.com',
"method": "POST",
"path" : "/token",
"port" : 443,
"encoding": "utf8",
"followRedirect": true,
"headers": {
"Authorization": 'Basic ' + Buffer.from("client_id" + ':' + "client_secret").toString('base64'),
"Content-Type": 'application/x-www-form-urlencoded',
"Content-Length": Buffer.byteLength(postData),
},
'muteHttpExceptions': true
}
const body = []
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', (chunk) => body.push(chunk))
res.on('end', () => {
const access_token = Buffer.concat(body).toString()
console.log(access_token)
})
})
req.on('error', error => {
console.error(error)
})
req.write(postData);
req.end()
}
getAccessToken();
You can save token in database,file or other memory database and use it in all requests in the Authorization header but depends on type of token,for example for set JWT token:
request.setHeader('Authorization', 'Bearer '+accessToken)
OR in option object:
options = {
host: '<URL>',
path: '<path of endpoint>',
port: '<portNumber>',
headers: {'Authorization', 'Bearer '+accessToken}
};
also for the async request to another endpoint, you can use Axios axios example:
const axios = require('axios').default;
const sendGetRequest = async () => {
try {
const resp = await
axios.get('https://jsonplaceholder.typicode.com/posts', {
headers: {
'authorization': 'Bearer YOUR_JWT_TOKEN_HERE'
}
});
console.log(resp.data);
} catch (err) {
// Handle Error Here
console.error(err);
}
};
sendGetRequest();

Redirect to a Url is not working after POST response

I am sending a post request from the frontend and i am getting a response with a confirmation url, i want to redirect to that url, but it is not doing so
iam using:-
koajs as framework
backend code:-
router.post("/api/pricing/:token/:shop", koaBody(), async (ctx) => {
try {
let shopname = await ctx.params.shop;
let dataBody = await ctx.request.body;
let bodyStringyfy = JSON.stringify(dataBody);
let tokenjson = await ctx.params.token;
const options = {
method: "POST",
body: bodyStringyfy,
headers: {
"X-Shopify-Access-Token": tokenjson,
"Content-Type": "application/json",
},
};
let url = `https://${shopname}/admin/api/2021-01/recurring_application_charges.json`;
await fetch(url, options)
.then((response) => response.json())
.then((res) => {
ctx.redirect(
`https://cors-anywhere.herokuapp.com/${res.recurring_application_charge.confirmation_url}`
);
});
} catch (e) {
console.log(e);
}
});

Why is expressjs POST request returning [object Object]?

app.post("/api/orders", async(request, response) => {
try {
await client.connect();
console.log("Connected correctly to server");
const db = client.db(dbName);
// Use the collection
console.log("search options " + json(request));
const col = db.collection("Orders");
// const inserted = await col.insertOne();
response.send("thanks")
} catch (err) {
console.log(err.stack);
}
});
/
let orderData = {subject: "subject", location: "location", price:"price", spaces: "spaces"};
const optionsPOST = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(orderData)
};
console.log(JSON.stringify(orderData))
fetch("/api/orders", optionsPOST);
I am trying to post some data that then is added to mongodb atlas, however, when I post my data I get undefined.
Try using a simple fetch request
fetch('/api/orders', optionsPOST)
.then(response => response.json())
.then(data => console.log(data));
This should also help: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Server not sending correct response to frontend?

I am trying to make my server a middleman so that the frontend queries the server with a searchedValue, the server queries the API with the searchedValue, and the server returns the API response to the frontend.
Currently, the server is querying the API correctly. Here is the code and responses:
Query: http://localhost:3000/optionsAPI/AAPL
Code [server.js]:
app.get("/optionsAPI/:ticker", (req, res) => {
var tempJSON = [];
const searchString = `${req.params.ticker}`;
const url = `API URL HERE, HIDING FOR SECURITY`;
fetch(url, { headers: { Accept: 'application/json' } })
.then(res => res.json()
.then((json) => {
tempJSON = json;
console.log(tempJSON);
}))
.catch(err => console.error(err)); // eslint-disable-line
res.send({ message: tempJSON });
});
Here is the code in the component:
Code [Component.js]:
useEffect(() => {
const fetchData = () => {
const url = `/optionsAPI/${searchedValue}`;
fetch(url, { headers: { Accept: 'application/json' } })
.then(res => res.json()
.then((json) => {
setOptions(json.option_activity || []);
}))
.catch(err => console.error(err)); // eslint-disable-line
};
debounce(fetchData());
}, [searchedValue]);
The console log is perfect! It logs tempJSON as I would expect to see it, but the res.send message is simply {"message":[]}. Therefore, the response my frontend gets is an empty []. This doesn't; make sense - the console is logging the response, so why is the frontend receiving a blank []?
Thanks in advance.
In your code you are calling an api which returns a promise, so to handle the data returned by the promise you should add your code inside .then() function, meaning you have to wait for the promise to be resolved before accessing the data and sending it to the client
app.get("/optionsAPI/:ticker", (req, res) => {
var tempJSON = [];
const searchString = `${req.params.ticker}`;
const url = `API URL HERE, HIDING FOR SECURITY`;
fetch(url, { headers: { Accept: 'application/json' } })
.then(res => res.json()
.then((json) => {
tempJSON = json;
console.log(tempJSON);
// the response should be sent from here
res.send({ message: tempJSON });
}))
.catch(err => {
console.error(err);
// you also need to send a response when catching erros
res.status(400).send({ err });
});
});
you can use async / await to make your code much cleaner
app.get("/optionsAPI/:ticker", async (req, res) => {
var tempJSON = [];
const searchString = `${req.params.ticker}`;
const url = `API URL HERE, HIDING FOR SECURITY`;
try {
const result = await fetch(url, { headers: { Accept: 'application/json' } })
const json = await result.json()
tempJSON = json;
console.log(tempJSON);
res.send({ message: tempJSON });
} catch (error) {
console.error(error);
res.status(400).send({ error });
}
});

How can I get Axios to send a request with FormData?

I'm unable to get the server that I'm calling to recognize the FormData that I'm providing when I use axios. It keeps telling me that I'm not providing the right FormData even though it works in Postman and Node native http (see below):
import { Router } from "express";
import axios from "axios";
import * as FormData from "form-data";
const router = Router();
const cookieHeader = {
Cookie: "XXX",
};
router.get("/", async (_req, res) => {
try {
const formData = new FormData();
formData.append("key1", JSON.stringify(["value1"]));
formData.append("key2", "value2");
formData.append("key3", "value3");
const response = await axios.post("https://xxx", formData, { headers: { "Content-Type": "multipart/form-data; boundary=--------------------------811161660471543283806813" } });
res.send(response.data);
} catch (error) {
console.log(error);
}
});
module.exports = router;
I am able to get it working in Postman and used that to export using Node's native http, which also works:
import { Router } from "express";
import { https } from "follow-redirects";
const router = Router();
router.get("/", () => {
const options = {
method: "POST",
hostname: "xxx",
path: "/xx/xxx",
headers: {
"Content-Type": "multipart/form-data; boundary=--------------------------811161660471543283806813",
Cookie: "xxx",
},
maxRedirects: 20,
};
const req = https.request(options, (res: any) => {
const chunks: any[] = [];
res.on("data", (chunk: any) => {
chunks.push(chunk);
});
res.on("end", () => {
const body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", (error: any) => {
console.error(error);
});
});
const postData = `------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"key1\"\n\n[\"value1\"]\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"key2\"\n\nvalue2\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"key3\"\n\nvalue3\n------WebKitFormBoundary7MA4YWxkTrZu0gW--`;
req.setHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
req.write(postData);
req.end();
});
module.exports = router;
I figured it out after reading through https://github.com/axios/axios/issues/318. It wasn't until near the end that Googrosh posted that he used .getHeaders(). Lo and behold, I added that to my headers too and it worked.
So updating my code, here's what it looks like:
const response = await axios.post("https://xxx", formData, { headers: formData.getHeaders() });
onst formUrlEncoded = x =>
Object.keys(x).reduce((p, c) => p + `&${c}=${encodeURIComponent(x[c])}`, '')
var axios = require("axios");
axios({
url: 'https://login.xyz.com/oauth/v2/token',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: formUrlEncoded({
client_id: '***',
client_secret: '***',
grant_type: 'authorization_code',
})
})
.then(function(response) {
console.log(response.data)
})
.catch(function(error) {
console.log(error)
})

Resources