'Update MySQL db when element is dropped to new location (PHP & Laravel)
I'm pretty new to all of this (PHP/Laravel, MySQL and to AJAX) and at this point I just keep getting a 500 server error and I can't quite figure out what's going wrong. Any help would be very much appreciated!
I have span elements (course tiles) on a page (mysite.loc/path/page) that can be dragged and dropped into different table cells each with a unique id (set to the day+time of the cell, e.g. W1230). The drag and drop is working, and console.logs are showing that they're attaching/detaching from the elementsas expected.
On the drop, I want to update a courses_users pivot table in my MySQL db to note the new dropped location (i.e. new_day: W, new_time: 1230) by each user as authenticated, without reloading the page.
I call the AJAX to post to the update function in my TimesController, and I'm getting the following console errors at the AJAX call:
POST http://mysite.loc/update 500 (Internal Server Error)
XHR failed loading: POST "http://mysite.loc/update".
Thanks for any help.
Here's my javascript for the drag and drop with the ajax call (inside script tags in my page's main php file):
$(document).ready(function(){
var parent;
$("span").on("dragstart", function (event) {
var tile = event.originalEvent.dataTransfer;
tile.setData('Text', $(this).attr('id'));
parent = event.target.parentNode.id;
});
//prevent default actions on dragenter, dragoover
$('table td').not("#meettime").on("dragenter dragover", function (event) {
event.preventDefault();
});
//the element is dropped.
$('table td').not("#meettime").on("drop", function (event) {
event.preventDefault();
if (event.type === "drop") {
var tile_id = event.originalEvent.dataTransfer.getData('Text',$(this).attr('id'));
var drop_location = $(this).attr("id");
if (drop_location == parent) {
event.preventDefault();
} else {
var crn = tile_id.substr(3, 5); //crn is the course's unique reference number
var new_day = drop_location.slice(-22,-4);
var new_time = drop_location.slice(-4);
de=$('#'+tile_id).detach();
var q = $(de);
q.attr("class","tile changed");
de.appendTo($(this));
tileData = {'crn': crn, 'new_day': new_day, 'new_time': new_time};
$.ajax({
headers: {
'X-CSRF-Token': '{{ csrf_token() }}',
},
type:'POST',
url: '{{url("update")}}',
dataType: 'json',
data: tileData,
success: function(){
alert('Updated');
}
});
}
}
});
});
Here is the route in my web.php
Route::middleware(['auth:sanctum', 'verified'])->post('update', [TimesController::class, 'update']);
The update() function in my TimesController.php
namespace App\Http\Controllers;
use App\Models\Time;
use App\Models\Course;
use App\Models\User;
use Illuminate\Http\Request;
use Auth;
[...]
public function update(Request $request)
{
$user = Auth::user();
$user = $user->id;
$course = $user->courses()->where("crn", "=", $request->crn)->get();
if ($course) {
$course->pivot->new_day = $request->new_day;
$course->pivot->new_time = $request->new_time;
$course->pivot->save();
} else {
$request->user()->courses()->save($course, ['crn' => $request->notes, 'new_day' => $request->new_day, 'new_time' => $request->new_time]);
}
return 'Update complete. Check the `course_user` table to confirm.';
}
Solution 1:[1]
To anyone who may have looked at this, I ended up figuring out from my Laravel logs that my problem was with with the TimesController trying to update pivot values on a non-Object.
In case it's helpful for someone else, here's my updated update() function from my TimesController. Note that this function works to both save a new change (inserting a new record to the course_user pivot table) and to update an existing course.
public function update(Request $request)
{
$crn = $request->crn;
$course = Course::findByCRN($crn);
$user = Auth::user();
$existingcourse = $user->courses()->where('courses.id', $course->id)->first();
if($existingcourse) {
$existingcourse->pivot->new_day = $request->new_day;
$existingcourse->pivot->new_begin_time = $request->new_time;
$existingcourse->pivot->save();
} else {
$user->courses()->save($course, ['new_day' => $request->new_day, 'new_begin_time' => $request->new_time]);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | strugglebus |
