jonathan anders
jonathan anders

Reputation: 31

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

Upvotes: 1

Views: 221

Answers (1)

Zeke Lu
Zeke Lu

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.

DevTools - form data

After the change, the payload will be:

DevTools - json


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")

Upvotes: 1

Related Questions