I have tried prepopulating the forms from DB records, not happening for child form, I have use all conventions for Laravel table, pivot table etc., still nothing. The array display with the dd('$allTariffs') but doesn't show on view file, please help am stuck with
ErrorException foreach() argument must be of type array|object, null given
Edit Component Code
<?php
namespace App\Http\Livewire\Admin;
use App\Models\Products;
use App\Models\Tariffs;
use Livewire\Component;
class AdminEditTariffsComponent extends Component
{
// public $productId;
public $tariffId;
public $allTariffs = [];
public $rowProducts = [];
public $tariffName;
public function mount ($tariffId)
{
$this->rowProducts = Products::all();
$tariff = Tariffs::where('id', $tariffId)->first();
$this->tariffName = $tariff->tariff_name;
// $allTariffs = $tariff->products()->where('tariffs_id', $tariffId)->get()->toArray();
$allTariffs = $tariff->products->find($tariffId);
// var_dump($allTariffs) ;
// dd( $allTariffs);
foreach ($allTariffs->products as $product)
{
['productId' => $product->pivot->products_id, 'basicCharge' => $product->pivot->basic_charge, 'additionalCharge' => $product->pivot->additional_charge];
}
}
public function updateStatus()
{
$tariff = Tariffs::find($this->tariffId);
$tariff->tariff_name = $this->tariffName;
$tariff->created_by = auth()->user()->id;
$tariff->save();
foreach ($this->allTariffs as $product) {
$tariff->products()->sync($product['productId'],
['basic_charge' => $product['basicCharge'],
'additional_charge' => $product['additionalCharge']]);
}
session()->flash('message', 'Tariff added successfully!');
return redirect('/admin/tariffs/');
}
public function addProduct()
{
$this->allTariffs[] = ['productId' => '', 'basicCharge' => '', 'additionalCharge' => ''];
}
public function removeProduct($index)
{
unset($this->allTariffs[$index]);
$this->allTariffs = array_values($this->allTariffs);
}
public function render()
{
$rowProducts = Products::all();
return view('livewire.admin.admin-edit-tariffs-component',['rowProducts'=>$rowProducts])->layout('layouts.admin.base');
}
}
Edit View
<div class="container-fluid">
<!-- Begin Page Content -->
<!-- Page Heading -->
<div class="row">
<div class="col-lg-8">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Edit Tariff</h6>
</div>
<div class="card-body">
<form wire:submit.prevent="editTariff">
@csrf
<div class="form-row">
<!-- Default input -->
<div class="form-group col-md-8">
<input type="text" class="form-control" placeholder="Enter Tariff Name"
wire:model="tariffName" required>
</div>
</div>
<hr>
<div class="card">
<div class="card-header">
<h6 class="text-primary">Products, Basic and Weight Charges</h6>
</div>
<div class="card-body">
<table class="table" id="products_table">
<thead>
<tr>
<th>Product</th>
<th>Basic Charge</th>
<th>Weight Charge</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach ($allTariffs as $index => $allTariff)
<tr wire:key="tariff-{{ $value->wireKey }}">
<td>
<select
wire:model="allTariffs.{{$index}}.productId"
class="custom-select custom-select-sm form-control form-control-sm">
<option value="">Select Product</option>
@foreach ($rowProducts as $product)
<option value="{{ $product->id }}">
{{ $product->product_name }}
</option>
@endforeach
</select>
</td>
<td>
<input type="text"
class="form-control custom-select-sm form-control form-control-sm"
placeholder="Basic Charge"
wire:model="allTariffs.{{$index}}.basicCharge" required>
</td>
<td>
<input type="text"
class="form-control custom-select-sm form-control form-control-sm"
placeholder="Weight Charge"
wire:model="allTariffs.{{$index}}.additionalCharge" required>
</td>
<td>
<a href="#" wire:click.prevent="removeProduct({{$index}})" class="btn btn-danger btn-circle btn-sm">
<i class="fas fa-trash"></i>
</a>
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="row">
<div class="col-md-12">
<a href="#" wire:click.prevent="addProduct" class="btn btn-success btn-circle btn-sm">
<i class="fas fa-plus"></i>
</a>
</div>
</div>
</div>
</div>
<hr>
<div class="form-row">
<div class="form-group col-md-3">
<button type="submit" class="form-control btn btn-small btn-primary">Edit
Tariff</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- /.container-fluid -->
</div>
Model File
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Tariffs extends Model
{
use HasFactory;
protected $table = "tariffs";
public function products()
{
return $this->belongsToMany(Products::class, 'products_tariffs',
'products_id', 'tariffs_id')
->withPivot('basic_charge', 'additional_charge');
}
public function productstariffs()
{
return $this->hasMany(ProductsTariffs::class);
}
}
I have tried prepopulating the forms from DB records, not happening for child form, I have use all conventions for Laravel table, pivot table etc., still nothing. The array display with the dd('$allTariffs') but doesn't show on view file, please help am stuck with
ErrorException foreach() argument must be of type array|object, null given .thankyou
In your foreach
in your mount
function, you are creating an array but you aren't assigning it to anywhere. Therefore, $allTariffs
is empty.
Also, you're casting your variables by default as an array
. You are setting $rowProducts
as a Collection
, however. But then in your render you are also getting the $rowProducts
again. I'd suggest removing the = []
and removing the fetching of the $rowProducts
each render.
public $allTariffs = [];
public $rowProducts;
public $tariffName;
public function mount ($tariffId)
{
$this->rowProducts = Products::all();
// This assumes the $tarrifId always exists. If this isn't the case, perhaps
// wrap the related code in an "if ($tariff instanceof Tariff)"
$tariff = Tariffs::find($tariffId);
$this->tariffName = $tariff->tariff_name;
foreach ($tariff->products as $product) {
$this->allTariffs[] = ['productId' => $product->id, 'basicCharge' => $product->pivot->basic_charge, 'additionalCharge' => $product->pivot->additional_charge];
}
}
public function render()
{
return view('livewire.admin.admin-edit-tariffs-component')->layout('layouts.admin.base');
}