Send data to Express backend - javascript

I'm having trouble sending data to the Backend. I want to send data f1 to QueryBackend.js but when I try to console.log(req.body.f1) it's always undefined but in Services.js get the value.
Toolbar.js
handlePrintLetter = async(fieldName, fieldValue) => {
const { formId, selectedRows, displayData, onNotification } = this.props;
const idSelected = selectedRows.data.map(d => displayData[d.dataIndex].id);
const res = await getBookmarkDocument(idSelected); // Send Data to Backend
if (res.success) {
onNotification({ mode: 'success', text: 'success' });
} else {
onNotification({ mode: 'error', text: fieldName + ' ' + fieldValue });
}
}
Service.js
export const getBookmarkDocument = async (f1) => {
console.log(f1) // get value from Toolbar.js
const token = localStorage.getItem('token');
return axios.get(API + 'doc/show', { f1 },
{
headers: {
Authorization: `Bearer ${token}`
}
})
.then((response) => response.data || [])
.catch((error) => {
ErrorAPI(error);
return [];
});
}
How to get data f1 in here?
QueryBackend.js
router.get('/show', async (req, res) => {
try {
console.log(req.body.f1) // undefined
const pool = await poolPromise;
const result = await pool.query('SELECT sid_ddocument_key FROM sid_ddocument WHERE sid_ddocument_key = $1', ['I WANNA PUT DATA 'f1' IN HERE']); // Put Data f1
res.status(200).json({
success: true,
data: result.rows
});
} catch (err) {
res.status(500).json({
success: false,
response: err.message
});
}
});

GET requests can't have bodies. Encode the data in the query string and read it with req.query
const f1 = 'example';
const API = 'http://example.com/';
const url = new URL(`${API}doc/show`);
url.searchParams.append("f1", f1);
console.log(url.toString());

Related

baseQueryWithReauth not handling 401 errors, also noticed the prepareHeaders returns an empty object

const baseQuery = fetchBaseQuery({
baseUrl: 'url',
prepareHeaders: (headers, { getState }) => {
const token = getState().auth.token
// If we have a token set in state, let's assume that we should be passing it.
if (token) {
headers.set('authorization', `Bearer ${token}`)
}
return headers
}
})
const baseQueryWithReauth = async (args, api, extraOptions) => {
let result = await baseQuery(args, api, extraOptions)
if (result?.error?.originalStatus === 401) {
//I noticed result.error.originalStatus always returned undefine
console.log('sending refresh token')
const refreshResult = await baseQuery({
url: '/users/generateTokens',
method: 'POST'
}, api, extraOptions)
console.log(refreshResult)
if (refreshResult?.data) {
const user = api.getState().auth.user
api.dispatch(setCredits({ ...refreshResult.data, user }))
result = await baseQuery(args, api, extraOptions)
console.log(result)
} else {
api.dispatch(logOut())
}
}
return result
}

Fetching data from firebase realtime database returns invalid json response

Here I am making a fetch request to an api -
export async function getServerSideProps(ctx) {
let id = ctx.params.id;
let userObject;
let userId;
const cookie = parseCookies(ctx);
if (cookie.auth) {
userObject = JSON.parse(cookie.auth);
userId = userObject.id;
}
if (!userId) {
return {
redirect: {
permanent: false,
destination: '/',
},
};
}
const res = await fetch(`http://localhost:3000/api/tests/${id}`);
console.log(await res.json());
const data = await res.json();
console.log(data);
// return {
// props: { product: data },
// };
return {
props: {},
};
}
Here I am reading data from firebase realtime database -
export default async (req, res) => {
const { id } = req.query;
console.log(id);
let obj;
firebase
.database()
.ref('/test/' + id)
.once('value')
.then(snapshot => {
console.log('here');
const data = snapshot.val();
obj = data;
})
.then(() => res.status(200).json(obj))
.catch(err => console.log(err));
};
Which gives me this error -
Server Error FetchError: invalid json response body at https://localhost:3000/api/tests/-MUT5-DbK6Ff6CstPSGc reason: Unexpected end of JSON input
Everything seems to work except the json response I am getting after making fetch request. I can't even console.log to see what response I am actually getting. What am I missing?
Edit - Here's my firebase database structure, where test node is root node
There is no return in your promise. That's why obj is null. Instead of then just send the response in first capture.
export default async (req, res) => {
const { id } = req.query;
console.log(id);
let obj;
firebase
.database()
.ref('/test/' + id)
.once('value')
.then(snapshot => {
console.log('here');
const data = snapshot.val();
obj = data;
res.status(200).json(obj)
})
.catch(err => console.log(err));
};

TypeError: Cannot destructure property `queryResult` of 'undefined' or 'null'

I have the following error message in the server console.
property queryResult of 'undefined' or 'null'. TypeError: Cannot
My code is below
invoke:async (conversation, done) => {
// Get query from incoming message
const text = conversation.text();
var query = conversation.properties().query;
conversation.logger().info('Query '+query );
// Set modules
const soapRequest = require('easy-soap-request');
const path = require('path');
const fs = require('fs');
const xml2js = require('xml2js');
const { match } = require('assert');
//SOAP URL
const url = 'https://cap.zudo.com/ws/apf/ticketing/MOS?WSDL';
//Set headers
const sampleHeaders = {
'user-agent': 'sampleTest',
'Content-Type': 'application/xml;charset=UTF-8',
};
const filenameIn = path.join(__dirname, '/request.txt');
const filenameOut = filenameIn
//Replace Query variable inside request.txt fileContent
var REGEX = /<TKT:ProjectNum>(.+)<\/TKT:ProjectNum>/;
var fileContent = fs.readFileSync(filenameIn, 'utf8');
fileContent = fileContent.replace(
REGEX,
'<TKT:ProjectNum>' + query + '</TKT:ProjectNum>'
);
//Write the query
fs.writeFileSync(filenameOut, fileContent, 'utf8');
const xml = fs.readFileSync(path.join(__dirname, '/request.txt'), 'utf-8');
//Callback
let { queryResult } = await soapRequest({ url: url, headers: sampleHeaders, xml: xml, timeout: 10000}).then(results => {
return results;
}).catch(e => {
conversation.logger().info("ERROR "+e);
conversation.reply(e).transition('NOK').keepTurn(true);
done();
});
let { headers, body, statusCode } = await queryResult ;
xml2js.parseString(body,{ mergeAttrs: true }, (err, result) => {
if(err) {
conversation.logger().info("ERROR "+err);
conversation.reply(e).transition('NOK').keepTurn(true);
done();
}
conversation.logger().info("res: "+result);
conversation.reply(result).transition('OK').keepTurn(true);
done();
})
}
Can any one help me how to resolve the issue.
Before destructure an object, please carefully check if it's undefined or null.
const res = await soapRequest({ url: url, headers: sampleHeaders, xml: xml, timeout: 10000 }).then(results => {
return results;
}).catch(e => {
conversation.logger().info("ERROR " + e);
conversation.reply(e).transition('NOK').keepTurn(true);
done();
});
if (res === undefined || res === null) {
// do something when res is undefined or null
} else {
const { queryResult } = res; // safely destructure res now
// further processing...
}
You have one more error in your code:
let { headers, body, statusCode } = await queryResult;
queryResult is not a function, you don't need to use await with it.

How to save files into AWS using signedURLs and ReactJS?

I'm trying to attach images with regular text inputs into my form in order to submit to my MongoDB.
This is what my function to create a post looks like:
const [postData, setPostData] = useState({
text: '',
images: null,
postedto: auth && auth.user.data._id === userId ? null : userId
});
const { text, images, postedto } = postData;
const handleChange = name => e => {
setPostData({ ...postData, [name]: e.target.value, images: e.target.files });
};
const createPost = async e => {
e.preventDefault();
await addPost(postData, setUploadPercentage);
};
From there I move into my action addPost; on this function I call two API routes:
// #route POST api/v1/posts
// #description Add post
// #access Private
// #task DONE
export const addPost = (formData, setUploadPercentage) => async dispatch => {
try {
// ATTACH FILES
let fileKeys = [];
for(let file of formData.images) {
const uploadConfig = await axios.get(`${API}/api/v1/uploads/getS3url?type=${file.type}`);
await axios.put(uploadConfig.data.url, file, {
headers: {
'Content-Type': file.type
}
});
fileKeys.push(uploadConfig.data.key);
}
console.log(fileKeys);
// INSERT NEW BLOG
const config = {
headers: {
'Content-Type': 'multipart/form-data; application/json'
},
onUploadProgress: ProgressEvent => {
setUploadPercentage(
parseInt(Math.round(ProgressEvent.loaded * 100) / ProgressEvent.total)
);
// Clear percentage
setTimeout(() => setUploadPercentage(0), 10000);
}
};
formData.images = fileKeys;
const res = await axios.post(`${API}/api/v1/posts`, formData, config);
dispatch({
type: ADD_POST,
payload: res.data
});
dispatch(setAlert('Post Created', 'success'));
} catch (err) {
const errors = err.response && err.response.data.errors;
if (errors) {
errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
}
dispatch({
type: POST_ERROR,
payload: { msg: err.response && err.response.statusText, status: err.response && err.response.status }
});
}
};
My getS3url function looks exactly like this:
exports.uploadFile = asyncHandler(async (req, res, next) => {
const { type } = req.query;
const fileExtension = type.substring(type.indexOf('/') + 1);
const key = `${process.env.WEBSITE_NAME}-${req.user._id}-${
req.user.email
}-${Date.now().toString()}.${fileExtension}`;
const params = {
Bucket: process.env.AWS_BUCKET_NAME,
Key: key,
ContentType: type
};
s3.getSignedUrl(`putObject`, params, (err, url) => {
if (err) {
return next(
new ErrorResponse(
`There was an error with the files being uploaded`,
500
)
);
}
return res.status(201).json({ success: true, key: url });
});
});
I would like to point out that every post might have more than one image file and the function should return a signedURL for each single file; let's say I upload two files, I then should have two URLS retrieved in order to attach them into my post.
I'm sure there's nothing wrong with the way I;m managing state to submit data because it always return what I expect when using on console.log(postData) , even the files are shown.
Now I'm assuming the problem resides on my action, especially the code before the /// INSERT NEW BLOG comment because when I console.log(fileKeys) nothing is returned, not even an error/undefined/null.....I mean just nothing!.
My uploadFile is working fine when used with a single file....well not really because yes, it returns an URL of the 'supposed' uploaded file but when I get into my AWS console/bucket, there's nothing..but thats for its own post.
What I need help with?
Well, I'm trying to upload one/multiple files into my AWS using signedURL to return them as strings and attach them into my post. Is there any problem with my action file?.
Thanks!!.
for my case, I have been looping through the images and generating signed URLs and returning them since s3 doesn't support the signed URL option for multiple files at once.
In the end I found my own solution, here it is:
export const addPost = (formData, images, setUploadPercentage) => async dispatch => {
try {
let fileKeys = [];
for(let i = 0; i < images.length; i++) {
/// STEP 3
const token = localStorage.getItem("xAuthToken");
api.defaults.headers.common["Authorization"] = `Bearer ${token}`
const uploadConfig = await api.get(`/uploads/getS3url?name=${images[i].name}&type=${images[i].type}&size=${images[i].size}`);
// STEP 1
delete api.defaults.headers.common['Authorization'];
await api.put(uploadConfig.data.postURL, images[i], {
headers: {
'Content-Type': images[i].type
}
});
fileKeys.push(uploadConfig.data.getURL);
}
// INSERT NEW BLOG
const config = {
onUploadProgress: ProgressEvent => {
setUploadPercentage(
parseInt(Math.round(ProgressEvent.loaded * 100) / ProgressEvent.total)
);
setTimeout(() => setUploadPercentage(0), 10000);
}
};
// STEP 2
const token = localStorage.getItem("xAuthToken");
api.defaults.headers.common["Authorization"] = `Bearer ${token}`
const res = await api.post(`/posts`, {...formData, images: fileKeys}, config);
dispatch({
type: ADD_POST,
payload: res.data
});
dispatch(setAlert('Post Created', 'success'));
} catch (err) {
const errors = err.response && err.response.data.errors;
if (errors) {
errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
}
dispatch({
type: POST_ERROR,
payload: { msg: err.response && err.response.statusText, status: err.response && err.response.status }
});
}
};

cannot read property of when trying to send data from React to Express

I'm trying to send some data from a React form to my Express back end. To do this I'm using fetch where I'm trying to send some variable data from react. I'm console logging the data before running the fetch to see if it is there, console log can see the data.
My error states
[0] (node:2966) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'message' of undefined
So it seems like my Express back end can't see the variable data.
How I'm sending the data from react
handleSubmit = async e => {
e.preventDefault();
console.log("Submit was pressed!");
if (this.state.email === "") {
}
const { name } = this.state;
const query = this.state.query;
const subject = "kontakt fra nettside";
const message = { name, query };
console.log(message.name, message.text, "data is");
fetch(
"http://localhost:5000/api/email", variabler
{
method: "POST",
cache: "no-cache",
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true,
content_type: "application/json"
},
body: JSON.stringify(message, subject)
}
); //.then(response => response.json());
};
My file for retrieving the data from the front end in Express
const emailConfig = require("./emailConfig")();
const mailgun = require("mailgun-js")(emailConfig);
exports.sendEmail = (recipient, message, attachment) =>
new Promise((resolve, reject) => {
const data = {
from: "Test <test#test.no>", // Real email removed from this post
to: recipient,
subject: message.subject,
text: message.query,
inline: attachment,
html: message.html
};
mailgun.messages().send(data, error => {
if (error) {
return reject(error);
}
return resolve();
});
});
and sendMail.js
const express = require("express");
const sendMail = express.Router();
const emailUtil = require("./emailUtil");
const { sendEmail } = emailUtil;
sendMail.post("/", async (req, res, next) => {
// const { recipient, message } = req.body;
console.log("Request mottatt");
const recipient = "test#test.no";
const message = req.body.message;
try {
await sendEmail(recipient, message);
res.json({ message: "Your query has been sent" });
console.log("Message has been sent");
await next();
} catch (e) {
await next(e);
console.log("nah", e);
}
});
module.exports = sendMail;
I can't figure out where the error is, any ideas? :)

Categories