[Apologies for the length of this question, and bad code-formatting near the bottom — I tried to fix it, but could not.]
In an Arduino (actually ESP32) project, I’m using this web server. There’s an example that shows how to use form data. I’m trying to mimic it.
When I try to do so (copying the index.htm
file onto my macbook, and creating a “default” file containing the relevant JSON), Chrome gives me an error, saying that response.json
is not a function. So I guess my questions are “How on earth does the code in this example work?” (for pure intellectual interest) and “How can I mak a reasonable imitation of it work on my Mac, so that I can build up the rest of the html files that I’m gonna need for my project. By the way, the project is tiny — I might need to make one or two more HTML files at most.
The key bits in the example are some server code:
void getDefaultValue (AsyncWebServerRequest *request) {
// Send to client default values as JSON string because it's very easy to parse JSON in Javascript
String defaultVal = "{"car":"Ferrari", "firstname":"Enzo", "lastname":"Ferrari","age":90}";
request->send(200, "text/json", defaultVal);
}
which provides a JSON string when you go to server/default
; that’s because in the server setup code, there are these three lines:
server.on("/getDefault", HTTP_GET, getDefaultValue);
server.on("/setForm1", HTTP_POST, handleForm1);
server.on("/setForm2", HTTP_POST, handleForm2);
BTW, the two service routines, handleForm1
and handleForm2
basically just print the data submitted.
The main HTML file, index.htm
, starts with some CSS stuff, and then in the middle of things has this:
<form action="/setForm1" data-result="form1-result" enctype="text/plain" method="post">
<label for="cars">Choose a car brand:</label>
<select id="cars" name="cars">
<option value="Alfa Romeo">Alfa Romeo</option>
<option value="Ferrari">Ferrari</option>
<option value="Lamborghini">Lamborghini</option>
<option value="Maserati">Maserati</option>
</select>
<input type="submit">
</form>
<br><br>
<p id="form1-result"></p>
</div>
Finally, there’s a script
tag that contains, among other things, the following code:
document.addEventListener("DOMContentLoaded", () => {
console.log('Webpage is fully loaded');
// At first, get the default values for form input elements from ESP
fetch('/getDefault')
.then(response => response.json()) // Parse the server response
.then(jsonObj => { // Do something with parsed response
console.log(jsonObj);
document.getElementById('cars').value = jsonObj.car;
document.getElementById('fname').value = jsonObj.firstname;
document.getElementById('lname').value = jsonObj.lastname;
document.getElementById('age').value = jsonObj.age;
});
});
which seems to be designed to populate the values in the HTML proper, although in the case of “cars”, it’s already been hard-coded.
My attempt to mimic this involved a few steps.
-
I created a file,
default.json
, whose contents are this:{
“car”:”Ferrari”,
“firstname”:”Enzo”,
“lastname”:”Ferrari”,
“age”:90
}
because in loading the index.htm
file into Chrome, I could no longer hope to mess with the server code.
-
I edited the relevant bit of the script code to look like this:
document.addEventListener(“DOMContentLoaded”, () => {
console.log(‘Webpage is fully loaded’);// At first, get the default values for form input elements from ESP
fetch(‘default.json’,{
method: ‘POST’,
mode: ‘no-cors’,
headers: {
‘Content-Type’ : ‘application/json’
},
})
.then(response => response.json()) // Parse the server response
.then(jsonObj => { // Do something with parsed response
console.log(jsonObj);
document.getElementById(‘cars’).value = jsonObj.car;
document.getElementById(‘fname’).value = jsonObj.firstname;
document.getElementById(‘lname’).value = jsonObj.lastname;
document.getElementById(‘age’).value = jsonObj.age;
});
});
The no-cors
thing was to get it to have any hopes of loading at all. I get the following error:
index.htm:163 Uncaught (in promise) SyntaxError: Unexpected end of input (at index.htm:163:36)
That’s in the line .then(response => response.json())
, right at the period between response
and json
.
I don’t understand how adding the second argument to “fetch” generated this problem, but then again, I’ve written about 20 lines of javascript in my whole life, so I need all the help I can get.