I am getting error sending status code in laravel apide - json

When sending response code in laravel api, validation does not enter.
I can view it from the network, but when I send the status code, the console prints an error and I cannot print the validations on the blade page. If I don't send status code I can print validations.
Following my code: StudentController
public function store(Request $request): object
{
$validate = Validator::make($request->all(),[
'name' => 'required',
'course' => 'required',
]);
$data = [
'name' => $request->name,
'course' => $request->course,
];
if ($validate->fails()){
return response()->json(['success' => false, 'errors' => $validate->messages()->all()],422);
}
Student::insert($data);
return response()->json(['success' => true, 'message' => "Registration Successful"]);
}
ajax
$(document).ready(function (){
$('#createBtn').on('click',function (e) {
e.preventDefault();
let form = $('#student-add').serialize();
$.ajax({
'url': "{{ route('students.store') }}",
'data': form,
'type': "POST",
success:function (result) {
$('#ajax-validate ul').text("");
if(result.success === true){
console.log("True");
}else {
result.errors.forEach(function (item) {
$('#ajax-validate ul').append('<li>'+item+'</li>');
});
}
}
});
});
});
console
network

You have your response.errors.forEach inside of your success: function(), but 422 (or any 400) code doesn't get handled by the success function, but rather the error function:
$(document).ready(function () {
$('#createBtn').on('click', function (e) {
e.preventDefault();
let form = $('#student-add').serialize();
$.ajax({
url: "{{ route('students.store') }}",
data: form,
type: 'POST',
success: function (result) {
if (result.success === true) {
// Do whatever on `2XX` HTTP Codes
}
},
error: function (response) {
if (response.status === 422) {
let responseJson = response.responseJSON ? response.responseJSON : { errors: [] };
$('#ajax-validate ul').text('');
responseJson.errors.forEach(function (item) {
$('#ajax-validate ul').append('<li>'+item+'</li>');
});
} else {
console.log('Unhandled Error:', response)
}
}
});
});
});
Now when an 422 error is explicitly triggered, you code can properly handle the validation errors.

Related

How to use sweetalert2 preConfirm with httpRequest which needs to be subscribed to within Angular 9 component

I have an Angular form component which sends a http request and subscribes to that request. Now I'm trying to add a sweetalert2 feature to start a loader when the form is submitted (onSubmit()) and the http request is executed (with doSubmit()) and I'd like the sweetalert modal to change to a success or error message when http request returns a response which is subscribed to by the component (resulting in execution of onSuccess() or onError()). For some reason, my swal.preConfirm doesn't change the sweetalert from the loader to a success or error message. Can you please help?
protected doSubmit(): Observable<NewUser> {
swal.queue([{
title: 'Registration',
text: 'Processing your information',
onBeforeOpen: () => {
swal.showLoading()
},
preConfirm: () => {
return this.onSuccess()
.then(() =>
swal.insertQueueStep({
title: 'Success'
})
)
.catch(() =>
swal.insertQueueStep({
title: 'Error'
})
)
}
}])
return this.httpService.callDatabase<NewUser>('post', '/api/users/register', this.value)
}
onSubmit() {
if (this.form.valid) {
this.doSubmit().subscribe(
() => {
this.error = null;
this.onSuccess();
},
err => {
this.error = err
this.onError();
},
() => {
this.submitted = false;
this.completed = true;
}
)
}
}
onSuccess(){
return new Promise((resolve){
resolve('success')
})
onError(){
return new Promise((reject){
reject('error')
})
I figured out a bit of a make shift solution for this issue without using swal.preConfirm. Hopefully, there is a more elegant solution to achieving the same. For now, here's my solution:
protected doSubmit(): Observable<NewUser> {
this.invalidOnError = '';
this.navigationExtras = { queryParams: this.asssignToNavExtras.assignToNavExtras({ username: this.username.value }) };
swal.fire({
title: 'Registration',
text: 'Processing your information',
onBeforeOpen: () => {
swal.showLoading()
}
})
.then
return this.httpService.callDatabase<NewUser>('post', '/api/users/register', this.value)
};
onSubmit() {
if (this.form.valid) {
this.doSubmit().subscribe(
() => {
this.error = null;
this.onSuccess();
},
err => {
this.error = err
this.onError();
},
() => {
this.submitted = false;
this.completed = true;
}
)
}
}
protected onSuccess() {
swal.fire({
title: 'Registration Successful',
text: 'Thank you',
icon: 'success',
confirmButtonText: 'OK',
buttonsStyling: false,
customClass: {
confirmButton: 'btn'
},
timer: 10000,
})
}
protected onError() {
swal.fire({
showConfirmButton: false,
timer: 10,
onAfterClose: () => {
code for where to place focus after sweetalert is closed
}
})
}

TypeError: JSON.stringify(...).then is not a function - React JS

I am trying to connect my react app with the backend for log in page. I am using a promise to return a success message.
login.js
onSubmitSignIn = () => {
fetch('http://localhost:5000/', {
method : 'post',
headers :{ 'Content-Type' : 'application/json'},
body : JSON.stringify({
userId : this.state.userId,
password : this.state.password
}).then(response => response.json())
.then(data => {
if(data === 'success'){
this.props.onRouteChange('home');
}
})
})
}
Backend code -
exports.findById = (req) => {
return new Promise((resolve) => {
var sql = "Select * from users where userid = '" + req.body.userId + "' ;";
connection.query(sql,req, function (error, results, fields) {
var data = JSON.parse(JSON.stringify(results));
var valid = false;
if( data.length !=0 && req.body.userId === data[0].userid && req.body.password === data[0].password)
valid = true;
if(valid) {
resolve({message : "success"});
}else{
reject({ message :"fail"});
}
});
})
};
After clicking on sign in button, I am getting an error "TypeError: JSON.stringify(...).then is not a function"
I tried some solutions from similar questions, it did not work in my case.
The then should be outside of fetch
fetch('http://localhost:5000/', {
method : 'post',
headers :{ 'Content-Type' : 'application/json'},
body : JSON.stringify({
userId : this.state.userId,
password : this.state.password
})
}).then(response => response.json())
.then(data => {
if(data === 'success'){
this.props.onRouteChange('home');
}
})
You have a typo, .then should be on fetch not on JSON.stringify.
onSubmitSignIn = () => {
fetch("http://localhost:5000/", {
method: "post",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
userId: this.state.userId,
password: this.state.password
})
})
//-^
.then(response => response.json())
.then(data => {
if (data === "success") {
this.props.onRouteChange("home");
}
});
};
you have missed a bracket. there should be a closing bracket after JSON.stringify().
onSubmitSignIn = () => {
fetch('http://localhost:5000/', {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: this.state.userId,
password: this.state.password
})
}).then(response => response.json())
.then((data) => {
if (data === 'success') {
this.props.onRouteChange('home');
}
});
};
I had this problem too. Check and confirm that you're not importing or requiring {JSON} in your application. It's most likely referring to that imported JSON rather than the global

How do I change the state of the checkbox here?

I have been able to change the activation status of companies in database on onClick event of the checkbox. Now I am not able to toggle the status of the checkbox, What I am missing Here?
I have looked on various sites, but could not find the solution.
Here is my code in which i am printing the companies.
{this.state.allCompanies.map(com => (
<tr>
<td>{com.cname} </td>
<td>
<a>
<input
type="checkbox"
name="active"
checked={com.is_active == 1 ? "true" : ""}
onClick={
(() => {
this.setState({ cked: !this.state.cked });
},
e => this.handleActivated(e, com.cid))
}
/>
</a>
</td>
</tr>
))}
Here is my function.
handleActivated(e, id) {
const comid = id;
var data = {
comid: id
};
console.log(data);
fetch("http://localhost:5000/edit/company", {
method: "POST",
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(function(response) {
if (response.status >= 400) {
throw new Error("Bad Response from server");
}
return response.json();
})
.then(function(data) {
console.log(data);
if (data === "success") {
// e.target.checked : !e.target.checked;
this.setState({ msg: "Company Edited", active: !e.target.checked });
}
})
.catch(function(err) {
console.log(err);
});
// this.setState({ });
}
You are passing two functions to the onClick and as far as I know (though I am not able to give a source for this or tell you why) react will only use the last value you give to props. This is why setting the state of cked probably did not work.
I would suggest giving it only 1 function like so:
onClick={
(e) => {
this.setState({ cked: !this.state.cked });
this.handleActivated(e, com.cid)
}
}
If you want to only execute the second one after the setState is done(since it is async), you should use the callback function of setState.
onClick={
(e) => {
this.setState({ cked: !this.state.cked }, () => {
this.handleActivated(e, com.cid)
});
}
}

AspNetCore EntityModel can't serialize to Json

I'm working on a project in AspNetCore with EntityFrameworkCore and i would like to use Ajax to get an object but my controller can't serialize this object correctly in Json, so my Ajax call trigger an error instead of a success event.
Here is my controller + test JsonConvert that return null.
[HttpGet]
public async Task<IActionResult> GetPackWithAllCards(int? packId)
{
if (packId == null)
{
return Json("An error has occured");
}
else
{
var pack = await _context.Packs
.Include(p => p.TagPacks)
.ThenInclude(tp => tp.Tag)
.Include(p => p.CardPacks)
.ThenInclude(cp => cp.Card)
.ThenInclude(c => c.FaceCards)
.ThenInclude(fc => fc.Face)
.ThenInclude(fc => fc.Template)
.Include(p => p.CardPacks)
.ThenInclude(cp => cp.Card.FaceCards)
.ThenInclude(fc => fc.Face.Image)
.Include(p => p.CardPacks)
.ThenInclude(cp => cp.Card.FaceCards)
.ThenInclude(fc => fc.Face.Sound)
.SingleOrDefaultAsync(m => m.PackId == packId);
//pack is correctly returned from database
if (pack == null)
{
return Json("An error has occured");
}
var a = JsonConvert.SerializeObject(pack);
return Ok(pack);
}
}
and my ajax call with typescript object:
var pack = new Pack(0, 0, 0, "", "", 0, 0, false, null, null);
$.ajax({
type: "GET",
url: "/pack/GetPackWithAllCards",
dataType: "text",
data: {packId},
async: false,
success: function (response) {
$.extend(pack, response);
alert("succes:"+response.packId);
},
error: function (response) {
$.extend(pack, response);
alert("error:" + response);
}
});
alert(pack);
return pack;
I hope someone could help me, i really don't find a solution to my problem.
I do this:
return new ContentResult
{
Content = JsonConvert.SerializeObject(data, Formatting.None, new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore}),
ContentType = "application/json"
};
Are you getting the packId value in the controller? you may need to use:
data: {packId : packId},

Redirect to diffrent action when reciving json results in my script

i'm getting a list view json results and I would like to redirect to a different view and display the results according to my json
( I hope i'm clear) this what i'm did
<script type="text/javascript">
$(document).ready(function () {
$("#term").autocomplete({
source: function (request, response) {
$.ajax({
url: "Home/GetSubjectsName",
data: "{'term': '" + request.term + "' }",
dataType: 'json',
type: "POST",
contentType: "application/json; charset=utf-8",
dataFilter: function (data) { return data; },
success: function (data) {
response($.map(data, function (item) {
return {
label: item.value,
value: item.value,
id: item.id,
}
var url = '#Url.Action("bla", "blaaaa")';
}))
}
});
},
minLength: 2,
});
});
my jsonlook like this :
public JsonResult GetSubjectsName(string term)
{
var results = db.subjects.Where(s => term == null ||
s.SubjectName.ToLower().Contains(term.ToLower())).Select(x => new
{ id = x.SubjectId, value = x.SubjectName }).Distinct().ToList();
return Json(results, JsonRequestBehavior.AllowGet);
}
and the action I would like to display the results is this (instead of partial view)
public ActionResult bla(string term)
{
IEnumerable serach = from sub in db.subjects.Where(t => t.SubjectName.Contains(term)).Distinct()
select new SearchResultsViewModel
{
Created = sub.Created,
Gender = sub.Gender,
OccupationDecription = sub.OccupationDecription,
Image = sub.Image,
SubjectName = sub.SubjectName
};
ViewBag.term = term;
return RedirectToAction("bla", "home", serach.ToList());
}
my View :
#model IEnumerable<MyProJect.ViewModels.SearchResultsViewModel>
foreach ....
what I need is to go to a different action and display the data
Here's some code that might help. Your post is still a bit unclear, so I'm filling in the missing pieces according to what you have described. I've made no attempt at designing the form layout.
Home/Index.cshtml:
#using( Html.BeginForm("bla") ) {
#Html.LabelFor(model => model.term)
#Html.EditorFor(model => model.term)
<button type="submit">Submit</button>
}
<script type="text/javascript">
jQuery(function ($) {
$("#term").autocomplete({ source: '#Url.Action("GetSubjectsName")', autoFocus: true, minLength: 2 });
});
</script>
Your autocomplete should be changed to:
public JsonResult GetSubjectsName(string term)
{
return Json(db.subjects
.Where(s => term == null ||
s.SubjectName.ToLower()
.Contains(term.ToLower()))
.OrderBy(x => x.SubjectName)
.Select(x => x.SubjectName)
.Distinct(), JsonRequestBehavior.AllowGet);
}
As far as I can tell, everything else should work as intended.