@kokurate How can someone easily identify what is the 500 error without reading it? Could you please add your error message?
Console [HTTP/1.1 500 Internal Server Error ]
** I think the problem in the jquery
In my current Laravel 9 project,
I have encountered an issue where my data does not get saved in the database upon clicking the submit button. However, when an image is included, it is successfully uploaded to the storage.
Upon inspecting the response, I have observed that it indicates a "500 Internal Server Error."
I am facing difficulty in pinpointing the source of this error, as I believe that everything was functioning correctly previously. I am perplexed by the fact that this code is now experiencing issues.
here's in my form
<form action="{{ route('author.posts.create') }}" method="post" id="addPostForm" enctype="multipart/form-data">
@csrf
<div class="row">
<div class="col-md-9 my-3">
<div class="card">
<div class="progress card-progress">
<div class="progress-bar bg-red" style="width: 20%" role="progressbar" aria-valuenow="20"
aria-valuemin="0" aria-valuemax="100" aria-label="20% Complete">
{{-- <span class="visually-hidden">20% Complete</span> --}}
</div>
</div>
<div class="card-body">
{{-- <h3 class="card-title">
<a href="#">{{ auth()->user()->name }}</a>
<span class="badge bg-danger ms-2">{{ auth()->user()->authorType->name }}</span>
</h3> --}}
<div class="mb-3">
<label class="form-label">Judul Post</label>
<input type="text" class="form-control @error('post_title') is-invalid @enderror"
name="post_title" placeholder="Masukkan judul...">
<span class="text-danger error-text post_title_error"></span>
</div>
<div class="mb-3">
<label class="form-label">Content</label>
<textarea class="ckeditor form-control @error('post_content') is-invalid @enderror"
name="post_content" id="post_content" rows="8" placeholder="Content.."></textarea>
<span class="text-danger error-text post_content_error"></span>
</div>
</div>
</div>
</div>
<div class="col-md-3 my-3">
<div class="card">
<div class="progress card-progress">
<div class="progress-bar bg-green" style="width: 20%" role="progressbar" aria-valuenow="20"
aria-valuemin="0" aria-valuemax="100" aria-label="20% Complete">
<span class="visually-hidden">20% Complete</span>
</div>
</div>
<div class="card-body">
{{-- <h3 class="card-title">
<a href="#">Tabler React</a>
</h3> --}}
<div class="mb-3">
<label class="form-label">Kategori</label>
<div>
<select class="form-select @error('post_category') is-invalid @enderror" name="post_category">
<option value="">Pilih Kategori</option>
@foreach(\App\Models\Category::with('subcategories')->get() as $category)
<optgroup label="{{ $category->category_name }}">
@foreach($category->subcategories as $subcategory)
<option value="{{ $subcategory->id }}">{{ $subcategory->subcategory_name }}</option>
@endforeach
</optgroup>
@endforeach
@foreach(\App\Models\SubCategory::where('parent_category', 0)->get() as $uncategorized)
<option value="{{ $uncategorized->id }}">{{ $uncategorized->subcategory_name }}</option>
@endforeach
</select>
<span class="text-danger error-text post_category_error"></span>
</div>
</div>
<div class="mb-3">
<div class="form-label">Featured Image</div>
<input type="file" class="form-control" name="featured_image" id="image-input">
<span class="text-danger error-text featured_image_error"></span>
</div>
<div class="image_holder mb-2" style="max-width: 250px">
<img src="" alt="" class="img-thumbnail" id="image-previewer">
</div>
<button type="submit" class="btn btn-primary">Simpan Post</button>
</div>
</div>
</div>
</div> <!-- End Row -->
</form>
Javascript (I'm already put link like CKEDITOR, Toastr etc...)
<script>
// start Image Preview and validation
$(function () {
// Get references to the file input and image element
var fileInput = document.getElementById('image-input');
var imagePreview = document.getElementById('image-previewer');
// Add an event listener to the file input
fileInput.addEventListener('change', function () {
// Check if a file is selected
if (fileInput.files && fileInput.files[0]) {
// Check allowed extensions
var allowedExtensions = ['jpg', 'jpeg', 'png'];
var fileExtension = fileInput.files[0].name.split('.').pop().toLowerCase();
var isAllowedExtension = allowedExtensions.indexOf(fileExtension) !== -1;
if (!isAllowedExtension) {
alert('Ekstensi gambar yang diperbolehkan: jpg, jpeg, png');
// Clear the file input to prevent submission
fileInput.value = '';
} else {
// Check image shape (assuming you have specific dimensions for rectangular images)
var image = new Image();
image.src = window.URL.createObjectURL(fileInput.files[0]);
image.onload = function () {
var width = this.width;
var height = this.height;
// Define your rectangular shape criteria here
var isRectangular = width > height;
if (!isRectangular) {
alert('Bentuk gambar harus landscape');
// Clear the file input to prevent submission
fileInput.value = '';
}
//preview the image if there's not error validation
var reader = new FileReader();
reader.onload = function (e) {
// Update the image preview
imagePreview.src = e.target.result;
};
reader.readAsDataURL(fileInput.files[0]);
};
}
}
});
});
// End Image Preview and validation
// form submit
$('form#addPostForm').on('submit', function(e){
e.preventDefault();
toastr.remove();
var post_content = CKEDITOR.instances.post_content.getData();
var form = this;
var fromdata = new FormData(form);
fromdata.append('post_content', post_content);
$.ajax({
url:$(form).attr('action'),
method:$(form).attr('method'),
data:fromdata,
processData:false,
dataType :'json',
contentType:false,
beforeSend:function(){
$(form).find('span.error-text').text('');
},
success:function(response){
toastr.remove();
if(response.code == 1){
$(form)[0].reset();
$('div.image_holder').html('');
CKEDITOR.instances.post_content.setData('');
toastr.success(response.msg);
}else{
toastr.error(response.msg);
}
},
error:function(response){
toastr.remove();
$.each(response.responseJSON.errors, function(prefix,val){
$(form).find('span.'+prefix+'_error').text(val[0]);
});
}
});
});
</script>
route
Route::prefix('author')->name('author.')->group(function(){
Route::prefix('posts')->name('posts.')->group(function (){
Route::post('/create', [AuthorController::class,'createPost'])->name('create');
});
});
Controller
public function createPost(Request $request)
{
$request->validate([
'post_title' => 'required',
'post_content' => 'required',
'post_category' => 'required|exists:sub_categories,id',
// 'featured_image' => 'required|image|mimes:jpeg,jpg,png|max:2048',
'featured_image' => 'image|mimes:jpeg,jpg,png|max:2048',
],[
'post_title.required' => 'Judul tidak boleh kosong',
'post_content.required' => 'Content tidak boleh kosong',
'post_category.required' => 'Kategori harus dipilih',
'post_category.exists' => 'Kategori tidak terdaftar',
// 'featured_image.required' => 'Gambar tidak boleh kosong',
'featured_image.image' => 'Format gambar tidak benar',
'featured_image.mimes' => 'Hanya boleh tipe file jpeg,jpg,png',
'featured_image.max' => 'Maksimal 2mb',
]);
if($request->hasFile('featured_image')){
$path = "images/post_images/";
$file = $request->file('featured_image');
$filename = $file->getClientOriginalName();
$new_filename = time().'_'.$filename;
$upload = Storage::disk('public')->put($path.$new_filename, (string) file_get_contents($file));
if($upload){
$post = new Post();
$post->author_id = auth()->id();
$post->category_id = $request->post_category;
$post->post_title = $request->post_title;
// $post->post_slug = Str::slug($request->post_title);
$post->post_content = $request->post_content;
$post->featured_image = $new_filename;
$saved = $post->save();
if($saved){
return response()->json(['code' => 1 , 'msg' => 'Post baru telah berhasil ditambahkan']);
}else{
return response()->json(['code' => 3 , 'msg' => 'Ada yang salah saat menyimpan data post']);
}
}else{
return response()->json(['code' => 3 , 'msg' => 'Ada yang salah saat proses unggah image']);
}
}else{
$post = new Post();
$post->author_id = auth()->id();
$post->category_id = $request->post_category;
$post->post_title = $request->post_title;
$post->post_content = $request->post_content;
$saved = $post->save();
if($saved){
return response()->json(['code' => 1 , 'msg' => 'Post baru telah berhasil ditambahkan']);
}else{
return response()->json(['code' => 3 , 'msg' => 'Ada yang salah saat menyimpan data post']);
}
}
}
there some tricky method to post data with and without file with ajax.
in your ajax code add some logic to chek whatever form contain an file or not. because just using this code below
$.ajax({
url:$(form).attr('action'),
method:$(form).attr('method'),
data:fromdata,
processData:false, // this mean jquery will not process data as query string because ajax can't directly accessed file, with set this to false it can proccess the file but it cant process text only, so form must have file.
dataType :'json',
contentType:false, // this is too
// your rest of code here . . .
with the code you provided will post data and return error like your issue
However, when there are no validation errors, and I submit the form, the response in the console looks like this: XHR POST http://127.0.0.1:8000/author/posts/create [HTTP/1.1 500 Internal Server Error 168ms]
try this with logic to check if have file or not
$.ajax({
url:$(form).attr('action'),
method:$(form).attr('method'),
data = serialize();
contentType = data("ajax-content-type")? data("ajax-content-type") : "application/x-www-form-urlencoded";
processData = data("ajax-process-data") == "false" ? false : true;
hasFile = find("input[type='file']").not("[disabled]").length;
if (hasFile) {
data = new formdata();
contentType = false;
processData = false;
}
// your rest ajax code here . . .
from this code you can see the logic if the form have file or not. if not it will do a standart contentType and processData for text only without file to post.
Please or to participate in this conversation.