Getting POST requests to work with Axios, Kemal (crystal lang), vue.js

In picockpit.com, I am using AJAX requests to communicate with the backend for update operations. For instance,

image

if you want to change the name of this Pi, you would select:

image

which shows an inline form:

image

how to show this inline form with vue.js is besides the point of this post (even though very interesting!)

Clicking on Cancel will cancel the renaming, clicking on OK will initiate an AXIOS request, which will talk to the backend.

Here’s the JS code:

commitEdit: function (event) {
     let name = this.name;
     let serial = this.serial;
     let pointer = this;
     this.renameSpinnerMode = true;
     axios.post(‘/mypis/’ + serial + ‘/changename’,
         {
             name: name
     })
     .then(function (response) {
         pointer.renameMode = false;
         pointer.renameSpinnerMode = false;
         pointer.backupName = pointer.name;
     })
     .catch(function (error) {
         info(“Sorry, name of ” + ‘”‘ + pointer.backupName  + ‘”‘ + ” could not be changed. ” + error );
         pointer.name = pointer.backupName;
         pointer.renameMode = false;
         pointer.renameSpinnerMode = false;
       });
}

As you can see, I am using the default axios syntax which is suggested.

Furthermore, I am passing in a pointer (“pointer”) to “this” (this referring to the Vue.js component!), so that I can modify the component’s state in the callbacks from Axios.

In the Kemal powered backend, I have this code:

post “/mypis/:serial/changename” do |env|
     returncode = 400
     (…)
     newname = “”
     serial = “”

     if env.params.url.has_key?(“serial”)
         serial = env.params.url[“serial”].not_nil! if !env.params.url[“serial”].nil?
         json_raw = env.request.body.as(IO).gets_to_end
         data = Hash(String, String).from_json(json_raw)
         if data.has_key?(“name”)
             newname = data[“name”].not_nil!
         end
     end

(…)

end

As you can see, we are actually receiving the data JSON encoded!

That was the big problem before, I was trying to receive the data form-encoded (env.params.body[“name”]) in Kemal, and not JSON encoded!

In case the data is JSON encoded, env.params.body will be empty!

It is much easier to switch the backend implementation to handle JSON, than to try and convince AXIOS to encode the data as a form.

Axios “params” solution

By the  way, often on the web you will find the suggestion to set the params key for Axios. This is bad in my opinion, as it will actually encode the data as part of the URL.

You would have to rewrite the URL to get the query string, and interpret the data in Kemal.

And: the URL is subject to a lenght limitation.

Therefore, with POST requests, the parsing JSON route is the more solid one, IMHO.

We are for hire – consulting, development, project management …

Daily rate: 1500 € net. If you are looking for a flexible developer with a focus on the Raspberry Pi, we might be a good fit for you.

Contact us.