'Laravel: Contract file is not instantiable while building Controller
I am trying to add a shopping cart function to my Laravel application. I installed darryldecode/laravelshoppingcart package from GitHub and have been following instructions in these two websites.
TECHPOOL-Create a Shopping Cart with Laravel 6
LARASHOUT-Laravel E-Commerce Application Development – Checkout
I was able to create most of the shopping cart function with the first website but it didn't cover checkouts and placing orders so I found the second website.
The problem is that the contract file is not working. Here is the error I got.
Illuminate\Contracts\Container\BindingResolutionException Target [App\Contracts\OrderContract] is not instantiable while building [App\Http\Controllers\CheckoutController]. http://localhost:8000/checkout
Where I use the contract file is in the checkout process witch is explained in the second website. I made few changes in the codes so that it will be consistent with the first website but mostly I followed what the website says.
Here are the codes that are mentioned in the error.
OrderContract.php
<?php
namespace App\Contracts;
interface OrderContract
{
public function storeOrderDetails($params);
}
CheckoutController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contracts\OrderContract;
use App\Http\Controllers\Controller;
class CheckoutController extends Controller
{
protected $orderRepository;
public function __construct(OrderContract $orderRepository)
{
$this->orderRepository = $orderRepository;
}
public function getCheckout()
{
return view('checkout');
}
public function placeOrder(Request $request)
{
// Before storing the order we should implement the
// request validation which I leave it to you
$order = $this->orderRepository->storeOrderDetails($request->all());
dd($order);
}
}
OrderRepository.php
<?php
namespace App\Repositories;
use Cart;
use App\Models\Order;
use App\Product;
use App\Models\OrderItem;
use App\Contracts\OrderContract;
class OrderRepository extends BaseRepository implements OrderContract
{
public function __construct(Order $model)
{
parent::__construct($model);
$this->model = $model;
}
public function storeOrderDetails($params)
{
$order = Order::create([
'order_number' => 'ORD-' . strtoupper(uniqid()),
'status' => 'pending',
'grand_total' => Cart::getSubTotal(),
'item_count' => Cart::getTotalQuantity(),
'table_number' => $params['table_number'],
'name' => $params['name'],
'notes' => $params['notes']
]);
if ($order) {
$items = Cart::getContent();
foreach ($items as $item) {
// A better way will be to bring the product id with the cart items
// you can explore the package documentation to send product id with the cart
$product = Product::where('name', $item->name)->first();
$orderItem = new OrderItem([
'product_id' => $product->id,
'quantity' => $item->quantity,
'price' => $item->getPriceSum()
]);
$order->items()->save($orderItem);
}
}
return $order;
}
}
RepositoryServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Contracts\OrderContract;
use App\Repositories\OrderRepository;
class RepositoryServiceProvider extends ServiceProvider
{
protected $repositories = [
OrderContract::class => OrderRepository::class,
];
/**
* Register services.
*
* @return void
*/
public function register()
{
foreach ($this->repositories as $interface => $implementation) {
$this->app->bind($interface, $implementation);
}
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
//
}
}
I'm not really familiar with the contract concept since I only started learning Laravel recently and I'm completely lost here. Maybe the problem is that I haven't created another file that is necessary or maybe something else.
Any help would be appreciated as I have tried multiple methods with no success.
Thank you in advance.
Solution 1:[1]
Yes, this is expected...your contract should point to a Solid class else it's going to fail while trying to resolve it out of the container. So this is what you should do:
Create a class that implements that trait.
Go to your AppServiceProvider and bind it to that contract like this:
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
$this->app->bind(\App\Contracts\OrderContract::class, App\Repositories\ClassImplementingOrderContract::class);
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
}
this should fix your problem.
Solution 2:[2]
This error could caused even if you have forget to add "RepositoryServiceProvider" into "config/app.php" 's serviceProviders array.
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 | |
Solution 2 | gondolas |