I am trying to make a Laravel crud application following a tutorial but unable to get my items to show with data individually. I can output all items in the database but unable to output a single item with postman. Hoping someone can help me figure this out, thank you.
In postman, this outputs all the data correctly
http://localhost:8000/api/orders/
However, when I try to look at an individual item, it returns all null for any item ID
http://localhost:8000/api/orders/1 results in null data
http://localhost:8000/api/orders/2 results in null data
http://localhost:8000/api/orders/3 results in null data
etc
output postman http://localhost:8000/api/orders/
"data": [
{
"id": 3,
"details": "CREDITn",
"posting_date": "2023-10-05",
"description": "Online Transfer from CHK ...8760 transaction#: 18639n",
"amount": "950.00",
"type": "ACCT_XFERn",
"balance": "2468.81",
"check_or_slip": "",
"category": "Rent",
"property": "",
"notes": ""
},
{
"id": 2,
"details": "DEBITn",
"posting_date": "2023-09-05",
"description": "Online Transfer to CHK ...8760 transaction#: 18362 09/05n",
"amount": "-1050.00",
"type": "ACCT_XFERn",
"balance": "1518.81",
"check_or_slip": "",
"category": "",
"property": "",
"notes": ""
},
output postman http://localhost:8000/api/orders/3
{
"data": {
"id": null,
"details": null,
"posting_date": null,
"description": null,
"amount": null,
"type": null,
"balance": null,
"check_or_slip": null,
"category": null,
"property": null,
"notes": null
}
}
I have 4 files which I have created with the tutorial but changed it to fit my use.
routes-> api.php
<?php
use AppHttpControllersApiPurchaseOrdersController;
use IlluminateHttpRequest;
use IlluminateSupportFacadesRoute;
use AppHttpControllersApiAuthController;
Route::post('/login', [AuthController::class, 'login']);
Route::post('/register', [AuthController::class, 'register']);
Route::middleware(['auth:sanctum'])->group(function () {
Route::post('/logout', [AuthController::class, 'logout']);
Route::get('/profile', [AuthController::class, 'profile']);
});
Route::apiResource('orders', PurchaseOrdersController::class);
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Models -> Orders.php
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Orders extends Model
{
use HasFactory;
protected $table = 'accounting';
protected $fillable =[
'details',
'posting_date',
'description',
'amount',
'type',
'balance',
'check_or_slip',
'category',
'property',
'notes'
];
}
Resources -> OrderResource.php
<?php
namespace AppHttpResources;
use IlluminateHttpRequest;
use IlluminateHttpResourcesJsonJsonResource;
class OrderResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'details' => $this->details,
'posting_date' => $this->posting_date,
'description' => $this->description,
'amount' => $this->amount,
'type' => $this->type,
'balance' => $this->balance,
'check_or_slip' => $this->check_or_slip,
'category' => $this->category,
'property' => $this->property,
'notes' => $this->notes
];
}
}
App->http->Controllers->Api->PurchaseOrdersController.php
<?php
namespace AppHttpControllersApi;
use AppModelsOrders;
use AppHttpResourcesOrderResource;
use AppHttpControllersController;
use IlluminateSupportFacadesValidator;
use IlluminateHttpRequest;
class PurchaseOrdersController extends Controller
{
public function index()
{
$orders = Orders::get();
if ($orders->count() > 0) {
return OrderResource::collection($orders);
} else {
return response()->json(['message' => 'No record available'], 200);
}
}
//add to database
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'details' => 'required|string|max:255',
'posting_date' => 'string|max:255',
'description' => 'string|max:255',
'amount' => 'decimal:2',
'type' => 'string|max:255',
'balance' => 'decimal:2',
'check_or_slip' => 'string|max:255',
'category' => 'string|max:255',
'property' => 'string|max:255',
'notes' => 'string|max:255',
]);
if ($validator->fails()) {
return response()->json([
'message' => 'All fields are mandatory',
'error' => $validator->messages(),
], 422);
}
$orders = Orders::create([
'details' => $request->details,
'posting_date' => $request->posting_date,
'description' => $request->description,
'amount' => $request->amount,
'type' => $request->type,
'balance' => $request->balance,
'check_or_slip' => $request->check_or_slip,
'category' => $request->category,
'property' => $request->property,
'notes' => $request->notes
]);
return response()->json([
'message' => 'Purchase Order Created Successfully',
'data' => new OrderResource($orders)
], 200);
}
//update database item
public function update(Request $request, Orders $orders)
{
$validator = Validator::make($request->all(), [
'details' => 'required|string|max:255',
'posting_date' => 'string|max:255',
'description' => 'string|max:255',
'amount' => 'decimal:2',
'type' => 'string|max:255',
'balance' => 'decimal:2',
'check_or_slip' => 'string|max:255',
'category' => 'string|max:255',
'property' => 'string|max:255',
'notes' => 'string|max:255'
]);
if ($validator->fails()) {
return response()->json([
'message' => 'All fields are mandatory',
'error' => $validator->messages(),
], 422);
}
$orders->update([
'details' => $request->details,
'posting_date' => $request->posting_date,
'description' => $request->description,
'amount' => $request->amount,
'type' => $request->type,
'balance' => $request->balance,
'check_or_slip' => $request->check_or_slip,
'category' => $request->category,
'property' => $request->property,
'notes' => $request->notes
]);
return response()->json([
'message' => 'Purchase Order Updated Successfully',
'data' => new OrderResource($orders)
], 200);
}
//get from database
public function show(Orders $orders)
{
return new OrderResource($orders);
}
//delete from database
public function destroy(Orders $orders)
{
$orders->delete();
return response()->json([
'message' => 'Purchase Order Deleted Successfully',
'data' => new OrderResource($orders)
], 200);
}
}
I have tried using the update and delete on a single order item http://localhost:8000/api/orders/3 which returns success but no changes in the database guessing because single items are returning null.
{
"details" : "test",
"posting_date" : "2024-09-04 04:21:38",
"description" : "test",
"amount" : "25.00",
"type" : "test",
"balance" : "55.00",
"check_or_slip" : "test",
"category" : "test",
"property" : "test",
"notes" : "test"
}
GET|HEAD / ....................................................................................................................................................................................
POST api/login ................................................................................................................................................... ApiAuthController@login
POST api/logout ................................................................................................................................................. ApiAuthController@logout
GET|HEAD api/orders ......................................................................................................................... orders.index › ApiPurchaseOrdersController@index
POST api/orders ......................................................................................................................... orders.store › ApiPurchaseOrdersController@store
GET|HEAD api/orders/{order} ................................................................................................................... orders.show › ApiPurchaseOrdersController@show
PUT|PATCH api/orders/{order} ............................................................................................................... orders.update › ApiPurchaseOrdersController@update
DELETE api/orders/{order} ............................................................................................................. orders.destroy › ApiPurchaseOrdersController@destroy
GET|HEAD api/profile ............................................................................................................................................... ApiAuthController@profile
POST api/register ............................................................................................................................................. ApiAuthController@register
GET|HEAD api/user .............................................................................................................................................................................
GET|HEAD sanctum/csrf-cookie ................................................................................................ sanctum.csrf-cookie › LaravelSanctum › CsrfCookieController@show
GET|HEAD up ...................................................................................................................................................................................
result of DD in the show function
AppModelsOrders {#1188 // appHttpControllersApiPurchaseOrdersController.php:110
#connection: null
#table: "accounting"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: false
+wasRecentlyCreated: false
#escapeWhenCastingToString: false
#attributes: []
#original: []
#changes: []
#casts: []
#classCastCache: []
#attributeCastCache: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
+usesUniqueIds: false
#hidden: []
#visible: []
#fillable: array:10 [
0 => "details"
1 => "posting_date"
2 => "description"
3 => "amount"
4 => "type"
5 => "balance"
6 => "check_or_slip"
7 => "category"
8 => "property"
9 => "notes"
]
#guarded: array:1 [
0 => "*"
]
}
2
Answers
the issue is on the naming of your route parameters while using a resource route. The route parameters are named in singular case "order".
You can verify this by:
php artisan route:list --path=api/
To fix it you must rename your route parameters to match the expected names on the route definition, so:
public function show(Orders $order)
Since you’re doing implicit model binding, your type hinted variable has to match the URI parameter name. Based on your route definition:
Your $orders variable in the show() method is not matching that, so model binding doesn’t work here, and wont return any results.
Change your method definition to this:
You can read more here: https://laravel.com/docs/11.x/routing#implicit-binding