Search code examples
jqueryhtmlajaxlaravelforms

Update Laravel Form with Ajax


I'm trying to update data using ajax to prevent page reload. This is already populated form from the profile model. Even though this is pretty straightformward I am unable to submit this request via ajax.

This code gives me the following error :

Creating default object from empty value

Can anyone kindly help me understand what I have done incorrectly here?

blade file

<form class="form-horizontal" id="editProfile" data-parsley-validate>
  @method('PUT')
  @csrf

  <div class="row">
      <div class="col-md" style="padding:0px;">
          <input type="hidden" name="usr_id" id="usr_id">
          <input type="hidden" name="user_id" id="user_id" value="{{ $profile->user_id }}">
          <input type="hidden" name="username" id="username" value="{{ $profile->username }}">
          <input type="hidden" name="emp_id" id="emp_id" value="{{ $profile->emp_id }}">
          <input type="hidden" name="site" id="site" value="{{ $profile->site }}">

      <div class="form-group">
          <label for="firstname" class="col-sm-4 control-label">First Name</label>
          <div class="col-sm-10">
              <input type="text" class="form-control" id="first_name" value="{{$profile->first_name}}" placeholder="First Name">
          </div>
      </div>

      <div class="form-group">
          <label for="lastname" class="col-sm-4 control-label">Last Name</label>
          <div class="col-sm-10">
              <input type="text" class="form-control" id="last_name" value="{{$profile->last_name}}" placeholder="Last Name">
          </div>
      </div>

 <div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" id="submit" value="submit" class="btn btn-danger">Update</button>
</div>
</div>
    </div>
   </div>
</form>

Controller:

public function update(Request $request, $usr_id)
{
   $profile = Profile::find($usr_id);

   $profile->first_name = $request->input('first_name');
   $profile->last_name = $request->input('last_name');
   $profile->update();
}

Ajax Script:

<script>
    $(document).ready(function() {
    // Update Data

        $.ajaxSetup({
            headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });

        $('#editProfile').on('submit', function(e){
            e.preventDefault();

            var usr_id = $('#emp_id').val();

            $.ajax({
                type: "PUT",
                url: "/profile/edit/" + usr_id,
                dataType: $('#editProfile').serialize(),
                success: function (response) {
                    console.log(response);
                    alert("Data Updated");
                    location.reload();
                },
                error:function(error){
                    console.log(error);
                }
            });
        });

    });

</script>

Route

Route::put('/profile/edit/{usr_id}', 'ProfileController@update')->name('profile.update');

Solution

  • Creating default object from empty value

    This error is caused by this code

    $profile->update();
    

    You're attempting to update an empty object because

    $profile = Profile::find($usr_id);
    

    returns null

    Because find accepts a primary key that is an ineteger and you're passing it an empty value (assuming that's what you mean by emp_id)

    Here's the code that validates the ID to exist

    <meta name="csrf-token" content="{{ csrf_token() }}">
    <form class="form-horizontal" id="editProfile" data-parsley-validate>
        @method('PUT')
        <div class="row">
            <div class="col-md" style="padding:0px;">
                <input type="hidden" name="usr_id" id="usr_id">
                <input type="hidden" name="emp_id" id="emp_id" value="{{ $profile->emp_id }}">
            </div>
        </div>
        <button type="submit" id="submit" value="submit" class="btn btn-danger">Update</button>
    </form>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
    

    Ommitted irrelevant parts for brevity

    and validate the value before dispatching the Ajax request

    $(document).ready(function () {
        // Update Data
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });
    
        $('#editProfile').on('submit', function (e) {
            e.preventDefault();
    
            var usr_id = $('#emp_id').val();
    
            if (usr_id < 1) {
                alert("Error: user id is null! make sure it has a value from the {{ $profile->emp_id }}");
                return;
            }
    
            $.ajax({
                type: "PUT",
                url: "/profile/edit/" + usr_id,
                dataType: $('#editProfile').serialize(),
                success: function (response) {
                    console.log(response);
                    alert("Data Updated");
                    location.reload();
                },
                error: function (error) {
                    console.log(error);
                }
            });
        });
    });
    

    And in your update function die and dump the passed id by route using dd

    public function update(Request $request, $usr_id)
    {
       // dd($usr_id);
       $profile = Profile::find($usr_id);
    
       $profile->first_name = $request->input('first_name');
       $profile->last_name = $request->input('last_name');
       $profile->update();
    }
    

    Check that you receive a valid id from the form