Reputation: 31
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
Upvotes: 1
Views: 221
Reputation: 7445
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:
Context-Type
header does not match the content in the responseThe 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")
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")
Upvotes: 1