Empty object being sent to DB - reactjs

I'm writing a basic search function to query a postgresql db. When I'm running it and with console.logs up, I keep seeing that it's sending and returning a 200, however the object it is sending is blank. Below is my function followed by my curl command I'm sending. When I run the search function during the DB seed, it's able to find what I'm looking for.
curl http://localhost:5000/api/company/parts/GCS
companyRouter.get("/parts/:id", async (req, res, next) => {
const partNumber = req.body;
console.log("request 19", partNumber, req.body);
try {
const part = await searchPartsNumber(partNumber);
res.send({ part });
} catch ({ name, message }) {
next({ name, message });
}
});

SOLUTION -1:
you are not passing any body to the request . you are passing a url parameter. that's why your body is an empty object. if you want to get the parameter ( in your case GCS ) in your server you should do something like this
const partNumber = req.param('id');
SOLUTION - 2
otherwise if you want to pass body using curl you should modify your request like this.
curl --header "Content-Type: application/json" \
--request POST \
--data '{"partNumber":"YOUR_PART_NUMBER"}' \
http://localhost:5000/api/company/parts/GCS
and as req.body is an object. you should extract your partNumber like this
const {partNumber} = req.body;

Related

Problem receiving Axios post data from reactjs app using Golang

I have a locally hosted webpage using reactjs that sends an Axios post to port 9000. I have a Golang server listening to that port and it recieves the post. It then decodes the post but never gets any of its data. Below is the portion of code that sends the axios post in the reactjs app.
onSubmit = (event) => {
event.preventDefault();
let { task } = this.state;
console.log("printing new task title:", task);
if (task) {
axios
.post(
endpoint + "/api/task",
{task},
{headers: {"Content-Type": "application/x-www-form-urlencoded"}}
)
.then((res) => {
this.getTasks();
this.setState({task: ""});
console.log(res);
});
}
};
The below is the portion of the golang server that handles the post.
// CreateTask create task route
func CreateTask(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Context-Type", "application/x-www-form-urlencoded")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
var newTask listItem
_ = json.NewDecoder(r.Body).Decode(&newTask)
fmt.Println(newTask)
insertOneTask(newTask)
json.NewEncoder(w).Encode(newTask)
}
Below is the listItem struct
type listItem struct {
ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
Title string `json:"title,omitempty"`
Completed bool `json:"completed,omitempty"`
}
I've tried renaming it to title instead of task, and just passing in a static variable but to no avail.
In the console it correctly prints the inputed text, but when the console outputs the axios response from the golang server, its response never includes the task name.
This is an example of what the data portion of the response from the golang server should look like: data: {_id: '000000000000000000000000', title:'Test'}.
It only ever outputs this data: {_id: '000000000000000000000000'}
The golang terminal output after the post is recieved is as follows:
{ObjectID("000000000000000000000000") false}
Inserted a Single Record ObjectID("63decde2a336b8e7cdc2b865")
It seems the task attribute is listed as '' in the new . My problem is the new task doesn't have the inputted text from the webpage. If you need more of the code it's below
Main Repository
ReactJS file
Main Go file
It's recommended to use DevTools to debug such kind of problem.
The screenshot shows that the payload is form-url-encoded. But the server tries to read it with a json decoder (_ = json.NewDecoder(r.Body).Decode(&newTask)). If you do not ignore the error from Decode, it should report that the content is not a valid json. To fix the issue, just remove {headers: {"Content-Type": "application/x-www-form-urlencoded"}} from client/src/To-Do-List.js.
After the change, the payload will be:
Other errors:
1. Context-Type header does not match the content in the response
The func CreateTask in go-server/main.go has another issue too. The response is encoded as json:
json.NewEncoder(w).Encode(newTask)
Which conflicts with:
w.Header().Set("Context-Type", "application/x-www-form-urlencoded")
The header should be replaced with:
w.Header().Set("Context-Type", "application/json")
2. The CORS is not set correctly
r.HandleFunc("/api/task", GetAllTasks).Methods("GET", "OPTIONS")
r.HandleFunc("/api/task", CreateTask).Methods("POST", "OPTIONS")
The OPTIONS requests will be handled by GetAllTasks. In order to allow the Content-Type header in the POST request, the following line should be added to GetAllTasks:
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
And since CreateTask does not handle the OPTIONS request, the following lines can be removed:
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

Passing files from react-dropzone to express server

I'm currently trying to send my files to my express server but every time I try and send my request the body is empty. After some research, it seems like they would not be stored in req.body so I'm not sure how to actually access the files that I've stored in my formdata.
Clientside code
export default async function UploadToFireStorage(accepetedfiles,fileVals){//Index are 1-1
const formData = new FormData();
formData.append('files', accepetedfiles);
try{
const response = await fetch(`https://someUrl`,{
method:"POST",
body: JSON.stringify(formData)
})
const jsonData = await response.json()
console.log(jsonData) //Attempt to see how my req is formed
}catch(error){
console.log(error)
}
}
express code
app.post('/uploadNewFiles',async(req,res)=>{
try{
const files = req.? // im not sure what to access after sending my formdata
for(let file = 0;file < files.length;file++){
let storageRef = ref(storage, `files/${files[file].path}`);
let uploadTask = await uploadBytesResumable(storageRef, files[file]);
}
res.json(files)
}catch(error){
res.json('Error: ' + error)
}
})
So just to clarify my question. I know when I make a fetch request I can package data that needs to be sent so I can post it and then extract it using something like let someVar = req.body.someVar and I've tried that with my file array but am unable to get my file array back and i'm not totally sure how to access it from req.
To properly post the files, don't use JSON.stringify. Set the body equal to formData directly. See this answer for more detail.
On the server side, you'll need to use a body parser that can handle multi-part form data, like multer . See this answer for more detail.

How to use Axios.post() in a post request containing a json object request-body and a multipart form data (MP4)

Hi I Was wondering how I can send a a single axios post request containing a json object as the request body and also multipart form data (Mp4 file).
In my example I want to send 'details' and 'file'. I have tried sending details and file as 2nd and 3rd arguments to the axios.post() method but from what I can tell axios.post only accepts 2 args.
I have also tried appending the details and then the file, to the form data, but this does not work either.
If I split these into 2 seperate post calls, it works fine, but my application requires these to happen together.
I am getting the following error in my spring console:
[org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=----WebKitFormBoundaryqKyZ0R2SyFeDNCVp;charset=UTF-8' not supported]
Here is the error in my web dev tools console:
xhr.js:210 POST http://localhost:9191/api/123/file/upload 415
Id really appreciate any suggestions
const FileUpload = () => {
const [file, setFile]= useState(null)
const[details, setDetails] = useState({consent:false,
idConfirmed:false,
label:"",
roundId:""})
const changeHandler=(e)=>{
setFile(e.target.files[0]);
setDetails(prevDetails=>({
...prevDetails,
consent:true,
idConfirmed:true,
label:"test_Label"
}));
};
const handleSubmission=(e)=>{
e.preventDefault();
const data = new FormData();
data.append("file", file)
data.append("file", details)
console.log("Data: ", data)
axios.post(`${process.env.REACT_APP_URL_NEW_ROUND_VID}/123/file/upload`, data,
{
headers:{
"Content-Type":"multipart/form-data"
}
})
.then(res=>{
console.log("Data: ",res.data)
console.log("success")
})
.catch((e)=>{
console.log("Error", e)
})
//})
};
Here is my rest end point in Springboot:
#PostMapping(
path = "{patientId}/file/upload",
consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public void addWardRound(#PathVariable("patientId") String patientId,
#RequestParam("file") MultipartFile file,
#RequestBody WardRequest wardRequest){
WardRoundService.isFileEmpty(file);
WardRound round = service.saveRound(wardRequest);
String roundId = round.getRoundId();
service.uploadVid(patientId, roundId, file);
}
you can stringify and send the JSON data. but by using this method you need to parse it in the server!. it could be difficult
The best method is splitting it into 2 APIs
you can merge both API requests in UI by merging both APIs using promise.All
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
const promise1 = axios.get(URL1);
const promise2 = axios.post(URL2, data);
Promise.all([promise1, promise2]).then(function(values) {
console.log(values);
});
or else if you need to use the result of first API
then call the second API inside the response of first API itself

File Upload Angular2 via multipart/form-data, 400 Error

I need to upload a file together with some meta info via multipart/form-data like this:
Header
----boundary
Meta
----boundary
File
----boundary
For some reason I always get a 400 Error, the Backend server tells me, that the Meta-Field is missing. However, if I look into the Hex/Ascii dump with Wireshark, the field is definitely there.
The following Curl-command works perfectly fine and the file gets uploaded successfully:
curl -H "Expect:" -v -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: "token" -F "File=#/location" -F 'Meta={"access":"token"}' http://path
Therefore this doesn't seem to be a Backend failure. My Angular (4.1.3) request must be bad, but I can't figure out what's wrong with it.
Template-Code:
<input #file_input type="file" (change)="onFileInputChange($event)" multiple>
Angular2-Code:
onFileInputChange(event) {
let fileList: FileList = event.target.files;
for (let i = 0; i < fileList.length; i++) {
let fp: File = fileList[i];
let formData: FormData = new FormData();
formData.append('File', fp, fp.name);
const body = JSON.stringify({
'access': "token"
});
this.formData.append('Meta', body);
let RequestHeader = new Headers();
// auto set content type
RequestHeader.append('Content-Type', '');
RequestHeader.append('Accept', 'application/json');
RequestHeader.append('Authorization', "token");
this.http.post(this.backend_url, formData, RequestHeader).map(
res => res.json()).subscribe(
data => console.log('success'),
error => console.log(error))
}
}
What am I missing here?
I finally found the solution.
The Content-Type header was malformed:
Content-Type: , multipart/form-data; boundary=----WebKit12345
The content type header in the actual code was preset.
By calling
headers.set('Content-Type', '');
I assumed, that the header content type was overwritten, but actually an empty string was prepended to it, so that there was a comma, which could not be parsed, of course.
I solved this by deleting the content type header completely:
headers.delete('Content-Type');

How to answer back with images in wit.ai?

I am trying to create a fb_messenger bot using wit.ai.In wit.ai,i can only do answering and question which is only text.But I want to answering back to user by showing images.How to do it?Please guide me.
Thank you very much.
You need to send the image in your Wit action using the messenger Bot:
Example if you're using Node js:
const actions = {
/**
* This is used by the "Bot sends" action in Wit
* #param sessionId
* #param text
* #returns {Promise.<T>}
*/
send({sessionId}, {text}) {
// Our bot has something to say!
// Let's retrieve the Facebook user whose session belongs to
const recipientId = sessions[sessionId].fbid;
if (recipientId) {
// Yay, we found our recipient!
// Let's forward our bot response to her.
// We return a promise to let our bot know when we're done sending
//bot is a simple wrapper for Messenger node code provided [here][1]
return bot.sendTextMessage(recipientId, text)
.catch((err) => {
console.error(
'Oops! An error occurred while forwarding the response to',
recipientId,
':',
err.stack || err
);
});
} else {
console.error('Oops! Couldn\'t find user for session:', sessionId);
// Giving the wheel back to our bot
return Promise.resolve()
}
},
['my-custom-action']({sessionId, context, entities, message}) {
//Api calls ...
//now i got an image URL i want to send to the user
return bot.sendImageMessage(recipientId, image_url);
return Promise.resolve(context)
},
Don't forget to delete the "Bot sends" part from your story on Wit.ai, this is so you don't send both the Image and the URL.
Hope this helps!
You need to use the image attachment template.
curl -X POST -H "Content-Type: application/json" -d '{
"recipient":{
"id":"<USER_ID>"
},
"message":{
"attachment":{
"type":"image",
"payload":{
"url":"<IMAGE_URL>"
}
}
}
}' "https://graph.facebook.com/v2.6/me/messages?access_token=<PAGE_ACCESS_TOKEN>"
More information here:

Resources