Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

AndreLan's avatar

how to solve (Trying to get property of non-object) error, but the same function works well in another function

what is wrong with this controller, I always get this error when update order " Trying to get property of non-object " ,(notice that I'm using the same function for store and it works fine.

I have 4 tables in my database (user_type_id , users , products and orders, orders table contains 4 columns (id , product_id , user_id and qty), user_id and product_id = foreign keys of users and products tables.

also I want something I do not know how to write it correctly, I want when a customer delete an order and it is only one order (quantity = 1), to be deleted permanently and also if he typed the same quantity, to be deleted permanently also because when I tested this function I found that it keeps deleting till -1 -2 -3 etc..

and I want if the product quantity is 0 to hide the product for all users except the admins and the seller who sold it or at least to hide the Add to Cart button for all or replace it with dead button with out of stock instead of Add to Cart and if a user already ordered some of this product he cannot update quantity but can cancel it then it will be added to products again..

and I hope if someone told me how to use the commented spans because I do not know how to do that also :D thanks

    namespace App\Http\Controllers;
    use Illuminate\Http\Request;
    use App\Http\Requests;
    use App\Order;
    use App\Product;
    use Auth;
    use App\User;
    use App\Details;
    use Validator;
    
    class OrderController extends Controller
    {
    
        public function __construct()
        {
            $this->middleware('auth');
        }
    
        public function myorders()
        {
            $orders = Order::where('user_id','=',Auth::user()->id)->orderBy('id','desc')->get();
            return view('order.myorders',compact('products','orders','users'));
        }   
    
    
    
    
    
    
      public function buy(Request $id)
        {
            $product = Product::find($id);
            return view('product.index',compact('product','order','user'));
        }
    
    public function store(Request $request, $id)
        
    
            {
            $validator = Validator::make($request->all(), [
                'qty' => 'required|max:255',
                
            ]);
    
            if ($validator->fails()) {
                return redirect('')
                            ->withErrors($validator)
                            ->withInput();
            }
    
            $product = Product::find($id);
            $order = new Order();
            $order->user_id = Auth::user()->id;
            $order->product_id = $id;
            $order->qty = $request['qty'];
            $product->inv = $product->inv - $order->qty;
            $order->save();
            $product->save();
            return redirect('/');
        }
     
        
    public function edit(Request $id)
        {
            $product = Product::find($id);
            return view('order.myorders',compact('product','order','user'));
        }
    
    
    public function update(Request $request, $id)
        
    
            {
            $validator = Validator::make($request->all(), [
                'qty' => 'required|max:255',
                
            ]);
    
            if ($validator->fails()) {
                return redirect('')
                            ->withErrors($validator)
                            ->withInput();
            }
    
            
            $product = Product::find($id);
            $order = new Order();
            $order->user_id = Auth::user()->id;
            $order->product_id = $id;
            $order->qty = $request['qty'];                                  
  this line $product->inv = $product->inv - $order->qty; (it works in store)
            $order->save();
            $product->save();
    
            return redirect('/myorders');
        
        }
    
    
            public function delete($id)
        {
            $order = Order::find($id);
            return view('order.myorders',compact('product','order','user'));
        }
    
    
              public function destroy(Request $request, $id)
            {
            $validator = Validator::make($request->all(), [
                'qty' => 'required|max:255',
                
            ]);
    
            if ($validator->fails()) {
                return redirect('')
                            ->withErrors($validator)
                            ->withInput();
            }
            $order = Order::find($id);
        $product= Product::find($order->product_id);
        $order->qty = $order->qty - $request->input('qty');
        $product->inv = $product->inv + $order->qty;
        $product->save();
        $order->save();
            return redirect('/myorders');
    
        }  
        
    }

and this is the routes file

Route::get('/myorders', 'OrderController@myorders');
Route::get('/add_order', 'OrderController@buy');
Route::get('/add_order/{id}', 'OrderController@store');
Route::get('/update_order', 'OrderController@edit');
Route::get('/update_order/{id}', 'OrderController@update');
Route::get('/delete_order', 'OrderController@delete');
Route::get('/delete_order/{id}', 'OrderController@destroy');

and this is my view, I am using it with

<div class="klaviyo_modal" id="update_order_qty" style="display:none;">
    <div class="klaviyo_inner">
        <a href="Cancel" class="klaviyo_close_modal klaviyo_header_close">×</a>
            <form method="GET" action="/update_order/{{ $order['id'] }}" enctype="multipart/form-data">
                {{ csrf_field() }}
                    <p class="klaviyo_header">Please update quantity as you need, then order it.</p>
                        <div class="klaviyo_fieldset">
                            <div class="{{ $errors->has('qty') ? ' has-error' : '' }}">
                                <label for="qty" style="display:block;text-align:center;margin-bottom:25px">Ordered New Quantity will be ADDED to your CURRENT Order Quantity</label>
                                    <input type="number" id="qty" class="qty" name="qty" style="display:block;margin:auto" required="required" placeholder="CURRENT Quantity">
                                    @if ($errors->has('qty'))
                                    <span class="help-block">
                                         <strong style="display:block;text-align:center">{{ $errors->first('qty') }}</strong>
                                    </span>
                                    @endif
                            </div>
                        </div>
          <div class="klaviyo_fine_print"></div>
              <div class="klaviyo_form_actions">
                 <button type="submit" class="klaviyo_submit_button">
                        <span>Update Order Quantity Now</span>
                 </button>
              </div>



            <!-- <span class="help-block">
                  <div class="success_message" style="display: block; text-align:center">Order Updated Successfully</div><br>
            </span>   
            <span class="help-block">  
                  <strong class="error_message" style="display: block; text-align:center">Sorry, Product Out of Stock, Try again later</strong>
            </span> -->        



            </form>
    </div>
</div>
0 likes
8 replies
tykus's avatar

Any idea where it fails?

These are a potential candidate as it will result in null if there is not record with primary key equal to $id value:

$product = Product::find($id);

$order = Order::find($id);

You can use findOrFail($id) to ensure you get an object or fail with an appropriate exception.

Similarly, if your user is not authenticated, this will have the same outcome

Auth::user()->id
tykus's avatar

The point is that there are a number of areas in the code you posted where a property of a non-object type error can arise. I suggested using findOrFail($id) in place of find($id).

Similarly, Auth::user()->id assumes there is an authenticated user, whereas auth()->id() would fail gracefully to null.

AndreLan's avatar

@tykus yes, I understood, but using findOrFail($id) in place of find($id) for which function .. or for all of them?

tykus's avatar

All of them... always... as a general rule.

Cronix's avatar

All of them. Isn't it logical to check whether you actually retrieved the data you think you did, before trying to use it?

You're also doing stuff like this quite a bit

public function buy(Request $id)
{
    $product = Product::find($id);
    return view('product.index',compact('product','order','user'));
}

user and order don't even exist, but you're passing them to the view?

Your routes are all using get requests, which is a huge security problem. Get routes are not protected by csrf and should only be used to retrieve (aka get) data, not delete it, or update it, or create it.

Route::get('/myorders', 'OrderController@myorders');
Route::get('/add_order', 'OrderController@buy');
Route::get('/add_order/{id}', 'OrderController@store');
Route::get('/update_order', 'OrderController@edit');
Route::get('/update_order/{id}', 'OrderController@update');
Route::get('/delete_order', 'OrderController@delete');
Route::get('/delete_order/{id}', 'OrderController@destroy');
Snapey's avatar

and this

public function edit(Request $id)
    {
        $product = Product::find($id);
        return view('order.myorders',compact('product','order','user'));
    }

You now have an entire request object referenced by the variable $id. You cannot find a product using the Request object

AndreLan's avatar

ok, thanks for all :) , I fixed it, It was the action of the view form :D action="/update_order/{{ $order['id'] }}" , It should be action="/update_order/{{ $order->product->id }}" ,,

Now :)

I want something I do not know how to write it correctly, I want when a customer delete an order and it is only one order (quantity = 1), to be deleted permanently and also if he typed the same quantity, to be deleted permanently also because when I tested this function I found that it keeps deleting till -1 -2 -3 etc..

and I want if the product quantity is 0 to hide the product for all users except the admins and the seller who sold it or at least to hide the Add to Cart button for all or replace it with dead button with out of stock instead of Add to Cart and if a user already ordered some of this product he cannot update quantity but can cancel it then it will be added to products again..

and I hope if someone tells me how to use the commented spans because I do not know how to do that also :D thanks, again...

Please or to participate in this conversation.