How handle errors with JS fetch again Laravel Api - javascript

My Goal
I would like to display the error messages in the Form. But for this I would need to have access to the JSON?
Code
HTML blade
<form>
<input name="name">
<p class="text-red-500 text-xs italic">Please fill out this field.</p> {{-- $message --}}
<button id="submit">SUBMIT</button>
</form>
javascript
<script>
const submitBtn = document.getElementById('submit');
submitBtn.addEventListener('click', (e) => {
e.preventDefault();
const fel = document.getElementById('commentForm');
const formData = new FormData(fel);
const url = '/api/comments';
let fetchData = {
method: 'POST',
body: formData,
headers: new Headers()
}
fetch(url, fetchData)
.then(response => {
if (!response.ok) {
return Promise.reject(response);
}
return response.json();
})
.then(data => {
console.log("Success");
console.log(data);
})
.catch(error => {
if (typeof error.json === "function") {
error.json().then(jsonError => {
console.log("Json error from API");
console.log(jsonError);
}).catch(genericError => {
console.log("Generic error from API");
console.log(error.statusText);
});
} else {
console.log("Fetch error");
console.log(error);
}
});
</script>
Response after a faulty request
HttpStatus: 400
// console.log(res) output
Response { type: "basic", url: "http://127.0.0.1:8000/api/comments", redirected: false, status: 400, ok: false, statusText: "Bad Request", headers: Headers, body: ReadableStream, bodyUsed: false }
​
body: ReadableStream { locked: false }​
bodyUsed: false​
headers: Headers { }​
ok: false​
redirected: false​
status: 400​
statusText: "Bad Request"​
type: "basic"​
url: "http://127.0.0.1:8000/api/comments"
​
<prototype>: ResponsePrototype { clone: clone(), arrayBuffer: arrayBuffer(), blob: blob(), … }
repellendus-dolor-quibusdam-sint-qui-news:147:29
Problem
In the Devtool Network tab, when I go to response of the request, I get a JSON
JSON: {"comment_content":["The comment content field is required."],"comment_name":["The comment name field is required."]}
When I output res.json() via the console within my fetch method, I get a Promise:
XHRPOSThttp://127.0.0.1:8000/api/comments
[HTTP/1.1 400 Bad Request 100ms]
Promise { <state>: "pending" }​
<state>: "fulfilled"​
<value>: Object { comment_content: (1) […], comment_name: (1) […] }​​
comment_content: Array [ "The comment content field is required." ]​​
comment_name: Array [ "The comment name field is required." ]​​
<prototype>: Object { … }
Additional question:
Is there a better way to display the errors from the response in the form? Maybe with the help of the form data object?

Considering you are making the request from JavaScript means you will also need to update the UI to reflect any error states. This includes targeting the right input elements based on the validation errors and appending them to the DOM. There may be libraries which can make this easier on the JS side but ultimately, you will need to write this logic.
As an aside, if you were using a traditional POST request, Laravel provides the $errors variable and #error blade directive. These help check for / display validation errors and are available in your application views. Since you are using blade, you may want to consider this.

Related

Using HTTP in NativeScript to send Post-data to a TYPO3-Webservice

I'm trying to send form data from a NativeScript app to a TYPO3-Webservice.
This is the JavaScript I'm using:
httpModule.request({
url: "https://my.domain.tld/webservice?action=login",
method: "POST",
headers: { "Content-Type": "application/json" },
content: JSON.stringify({
username:username,
password:password
})
}).then((response) => {
console.log("got response");
console.log(response.content);
//result = response.content.toJSON();
callback(response.content.toJSON());
}, (e) => {
console.log("error");
console.log(e);
});
But I can't read this data in the controller. Even with this:
$rest_json = file_get_contents("php://input");
$postvars = json_decode($rest_json, true);
$postvars is empty. $_POST is empty, too (which is - according to some docs - because the data is sent as JSON and thus the $_POST-Array isn't populated.
Whatever I do, whatever I try, I can't get those variables into my controller.
I tried it with fetch as well as with formData instead of JSON.stringify, same result.
I might have to add, that when I add the PHP-part in the index.php of TYPO3, $postvars is being populated. So I guess something goes missing, until the controller is called.
Any ideas?
the nativescript part seems ok, your problem must be corrected in the server side.
i use similare call and its works
// send POST request
httpModule.request({
method: "POST",
url: appSettings.getString("SERVER") + '/product/list',
content: JSON.stringify(data),
headers: {"Content-Type": "application/json"},
timeout: 5000,
}).then(response => { // handle replay
const responseAsJson = response.content.toJSON();
console.log('dispatchAsync\n\tresponse:', responseAsJson);
}, reason => {
console.error(`[ERROR] httpModule, msg: ${reason.message}`);
});

How to update existing fields of a document in Firestore with the REST API

I have a project with Cloud Firestore as database. Now I want to update the data in one document using the fetch method. My Cloud Firestore stucture is the following:
Logging (Collection)
[userID] (Document)
Notifications (Collection)
[notificationID] (Document)
active: "true"
type: "T1"
And I use the fetch call below:
fetch("https://firestore.googleapis.com/v1/projects/[ID]/databases/(default)/documents/Logging/[userID]
+"/Notifications/[notificationID]?updateMask.fieldPaths=active", {
method: 'PATCH',
body: JSON.stringify({
"active": "false"
}),
headers: {
Authorization: 'Bearer ' + idToken,
'Content-Type': 'application/json'
}
}).then( function(response){
console.log(response);
response.json().then(function(data){
console.log(data);
});
}).catch(error => {
console.log(error);
});
Executing the fetch method I'm running in an error with message
"Invalid JSON payload received. Unknown name "active" at 'document': Cannot find field."
How can I update the existing fields of a document of Firestore with the REST API? Can anyone help me out? I've tried a lot of different "urls" and methods, but nothing works for me.
As explained in the Firestore REST API doc, You need to pass an object of type Document in the body, as follows:
{
method: 'PATCH',
body: JSON.stringify({
fields: {
active: {
stringValue: 'false',
},
},
}),
}
I made the assumption that your active field is of type String (since you do "active": "false"). If it is of type Boolean, you need to use a booleanValue property instead, as follows. See this doc for more details.
{
method: 'PATCH',
body: JSON.stringify({
fields: {
active: {
booleanValue: false,
},
},
}),
}

Cache Storage API, can't get header back

I would like to a check for max-age so I remove items from cache when they get old, but I can't get my own header back for some reason.
export function cacheResponse(url, response) {
caches.open('my-cache').then(function(cache) {
cache.put(url, new Response(JSON.stringify(response), {
headers: {
'Cache-Control': 'max-age=1',
'Content-Type': 'application/json;charset=UTF-8'
}
}));
});
}
cacheResponse('/hello', {hello: "world"})
I can see this working in the Application tab in chrome and I can see those 2 headers in the preview, but when I pull the item back out the headers object is null.
cache.match(url).then(async function(object) {
console.log(object.headers) // null
var body = await object.clone().json(); // {hello: "world"}
})
The object looks like this
object: Response
body: ReadableStream
bodyUsed: false
headers: Headers
__proto__: Headers
ok: true
redirected: false
status: 200
statusText: ""
type: "default"
url: ""
Seems like I should be able to lookup the headers from calling match() no?
That should work; you should be able to call response.headers.get('cache-control') to retrieve the value (assuming this is a same-origin response).
Here's a snippet of code that I just tested which worked when run in the JS console:
async function test() {
const constructedResponse = new Response('test', {
headers: {'cache-control': 'max-age=1'}
});
const cache = await caches.open('test');
cache.put('/test', constructedResponse);
const matchedResponse = await cache.match('/test');
console.log(`cache-control: ${matchedResponse.headers.get('cache-control')}`);
}

Javascript not showing notification from GET springboot rest api

I am totally new to javascript . I just want to show a notification using notify.js when a button is clicked.
Following is my RestController code:
#RequestMapping(value = "/checkCurrentBranch" , method=RequestMethod.GET)
public String checkCurrectGitBranch(Model model, HttpServletResponse response) {
String branchName = "";
GitInfo gitInfo = new GitInfo();
JsonFactory factory = new JsonFactory();
String json = apiService.readGitProperties();
ObjectMapper mapper = new ObjectMapper(factory);
JsonNode rootNode;
try {
rootNode = mapper.readTree(json);
Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
while (fieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = fieldsIterator.next();
if (field.getKey().toString().equalsIgnoreCase("git.branch")) {
branchName = field.getValue().toString();
adminAppLogger.info("Current Branch name :: "+branchName);
}
}
} catch (IOException e) {
adminAppLogger.error("Error while getting current Git branch :" + e);
branchName = "Error while fetching branch name";
}
model.addAttribute("res", branchName);
return branchName;
}
Following is my js code:
$('#gitBranch').click(function(res) {
/* <![CDATA[ */
var path = /* [[#{/}]] */'checkCurrentBranch';
/* ]]> */
$.notify(res, "info");
console.log(res);
});
I think I am missing some points but I am stuck. Any suggestions?
I tried using axios following is my js:
$('#gitBranch').click(function(res) {
/* <![CDATA[ */
var path = /* [[#{/}]] */'checkCurrentBranch';
/* ]]> */
axios({
method:'get',
url:path,
responseType:'json'
})
.then(function (response) {
console.log(response)
$.notify(data,"info")
});
});
Following response I get on brwoser console. Now I just want that data field to be shown as notification :
{data: "qc_mediaworker_details", status: 200, statusText: "", headers: {…}, config: {…}, …}
config
:
{adapter: ƒ, transformRequest: {…}, transformResponse: {…}, timeout: 0, xsrfCookieName: "XSRF-TOKEN", …}
data
:
"qc_mediaworker_details"
headers
:
{pragma: "no-cache", date: "Sun, 04 Nov 2018 05:59:32 GMT", x-content-type-options: "nosniff", x-frame-options: "DENY", content-type: "application/json;charset=UTF-8", …}
request
:
XMLHttpRequest {onreadystatechange: ƒ, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
status
:
200
statusText
:
""
__proto__
:
Object
You need to properly use data key in axios response block.
axios({
method:'get',
url:path,
responseType:'json'
})
.then(function (response) {
console.log(response)
$.notify(response.data,"info")
});
In above code, I replaced data by response.data
, because according your give code, data is not declared, that means its undefined. So if you mean data to that data which you get in axios response, then you need to access data by $.notify(response.data,"info") instead of $.notify(data,"info")
You don't have anywhere http request.
I recommend you using axios (because it's simple)
Sample code:
axios.get('host:port/checkCurrentBranch')
.then(response => {
// do what you want to do
})
.catch(error => {
// do something if an error occurs
})

Extracting data from a fetch() in Javascript

I have a simple fetch request like this:
fetch('/data', {method: 'POST', credentials: 'same-origin', body: {'name': 'alice'}}).then(function(response){
console.log('reply:');
console.log(response);
});
Basically it should send a POST request to the local address /data with some parameters in it (same thing as an HTML form does) and then return the reply it gets (the /data page simply prints out "this is a test response")
But when I look at the console.log(response); it looks like this:
Response { type: "basic", url: ".../data", redirected: false, status: 200, ok: true, statusText: "OK", headers: Headers, bodyUsed: false }
The actual string returned by the page /data ("this is a test response") is nowhere to be found.
So how can I retrieve the actual returned string then?
To read the body of the response, you need to actually do that. See the details on MDN (here, here, and here), but in brief, if you want the body as text, then:
fetch(/*...*/)
.then(function(response) {
return response.text();
})
.then(function(responseText) {
// ...
});

Categories