Livewire - Missing required parameters for route - laravel

When livewire is rendering a view, I get an error message:
Missing required parameters for [Route: book.show]
But if I just print the value, like {{ $slug }} , the view is rendered correctly.
It looks like the model data is not available at render time. Where I am going wrong?
Snippet of my view
<a href="{{ route('book.show', $slug) }}">
Show book
</a>
My component
class BookForm extends Component
{
public $slug;
public $name;
public $summary;
protected $listeners = ['fillForm1' => 'editList'];
public function editList($id)
{
$book = Book::find($id);
$this->slug = $book->slug;
$this->name = $book->name;
$this->summary = $book->summary;
}
public function render()
{
return view('livewire.books.book-form');
}
}
My route
Route::get('/book/{slug}', 'BookController#show')->name('book.show');
My BookController / show method
public function show($slug)
{
...
}
I'm using "laravel/framework": "^7.0" and "livewire/livewire": "^2.5"

I think there must be a limitation for livewire not to send the model data when rendering the view. I used the following workaround, if you have a way to improve this please let me know.
public function editList($id)
{
$book = Book::find($id);
$this->slug = route('book.show', $book->slug);
$this->name = $book->name;
$this->summary = $book->summary;
}

Related

Exporting all clients does not work, the file is saved with no name and no extension

I am trying to export the data in my database; in particular all the customers present but also a single chosen customer.
I tried to set the code only that when I click the button to export all clients a file with no name and no extension is saved.
ClientsExport Class
class ClientsExport implements FromCollection
{
private $client = null;
public function __construct($client = null)
{
$this->client = $client;
}
public function collection(Client $client=NULL)
{
if ($this->client) {
return collect([$this->client]);
}
return Client::all();
}
}
Taking a few tries I found that if I remove the if in the code below, then leaving it alone
return Excel::download(new ClientsExport, 'clients.xlsx');
it works properly, So it seems that the problem is giving it the if
ClientController
public function export(Client $client)
{
if($client){
return Excel::download(new ClientsExport($client), $client->surname . ' ' . $client->name . '.xlsx');
} else {
return Excel::download(new ClientsExport, 'clients.xlsx');
}
}
Routes
Route::get('client-export/{client?}', [ClientController::class,'export'])->name('client.export');
View Blade
Button where I want to export all clients
<a class="btn btn-warning mb-5 py-3 px-4 mt-3 me-3 fs-5" href="{{ route('client.export') }}">Export all clients</a>
Button where I want to export the individual client
<a class="btn btn-warning" href="{{ route('client.export' , compact('client')) }}">Export</a>
The issue is that when using route model binding, defining your controller method as: public function export(Client $client) will supply you with a new "empty" instance of \App\Models\Client when the client id in your route definition is "empty". Hence, the check below in your controller method will always be truthy.
ClientController::export(\App\Models\Client $client)
if($client){
// ...
} else {
// ...
}
To fix that, you will have to explicitly set the Controller method's parameter to NULL. This will instruct Laravel's route model binding system to supply you with a NULL $client variable instead of an "empty" instance of the Client model (new \App\Models\Client) when the client id in your route definition is "empty". ie:
ClientController class
// ...
public function export(\App\Models\Client $client = null)
{
}
// ...
FULL SOLUTION
ClientsExport Class
class ClientsExport implements FromCollection
{
public function __construct(private ?\App\Models\Client $client = null)
{
}
public function collection()
{
return is_null($this->client)
? Client::all()
: collect([
$this->client
]);
}
}
ClientController class
// ...
public function export(\App\Models\Client $client = null)
{
return Excel::download(new ClientsExport($client),
is_null($client)
? 'clients.xlsx'
: $client->surname . ' ' . $client->name . '.xlsx'
);
}
// ...

How to save the id and the model in polymorphic (laravel 6)?

I try these to save my comments:
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}
and
class Review extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
the routes:
Route::get('/reviews', 'front\ReviewController#Holder')->name('ReviewHolder');
Route::get('/reviews/{slug}', 'front\ReviewController#index')->name('Review');
Route::post('/reviews', 'front\ReviewController#Sendcm')->name('SendComment');
and my controller:
class ReviewController extends Controller
{
public function Holder(){
$reviews = Review::latest()->with('partners')->paginate(6);
return view('front.review.holder.main', compact('reviews'));
}
public function index($slug){
$item = Review::where('slug','=', $slug)->with('partners')->first();
return view('front.review.main.main',compact('item'));
}
public function Sendcm(Request $request){
$review = Review::find($id);
$comment = new Comment;
$comment->name = $request->name;
$comment->email = $request->email;
$comment->body = $request->body;
$review->comments()->save($comment);
return redirect()->back();
}
}
but i can't save the comment and show me an error
Undefined variable: id
how to find the id and model from my blade or in another way to save the comments?
and i try the:
public function Sendcm(Request $request, $slug){
$review = Review::find($slug);
$comment = new Comment;
.
.
.}
but the error is:
Too few arguments to function App\Http\Controllers\front\ReviewController::Sendcm(), 1 passed and exactly 2 expected
Undefined variable $id is because the function doesn't know where the $id is coming from. One option is to inject the review model as the second parameter like so:
public function Sendcm(Request $request, Review $review){
$review = Review::find($slug); //you can get rid of this.
$comment = new Comment;
.
}
Then update your route like so:
Route::post('/reviews/{review}', 'front\ReviewController#Sendcm')->name('SendComment');
Laravel will automatically give you the Review model associated with the id you post.
The error in the second example is because you did not update your route to accept a second parameter. You could have avoided that error by updating your route like so:
Route::post('/reviews/{slug}', 'front\ReviewController#Sendcm')->name('SendComment');
On a different note, it is advisable to follow PSR standards and Laravel's naming conventions. In that regard, it is best if you use snake case with dot notation while naming your routes. So, SendComment is better as reviews.send_comment
I changed a little the above answer in Controller to the:
public function Sendcm(Request $request, $slug){
$review = Review::find($slug);
$comment = new Comment;
$comment->name = $request->name;
$comment->email = $request->email;
$comment->body = $request->body;
$review->comments()->save($comment);
return redirect()->back();
}
and
{!! Form::open(['url' => route('send_comment', $item->id), 'method' => 'POST']) !!}
and the routes to:
Route::post('/reviews/{review}', 'front\ReviewController#Sendcm')->name('send_comment');
an now it's working but save the commentable_type without the 'App\' in comments table

Display reviews for a specific restaurant Laravel

I am trying to display reviews and ratings on a restaurant profile.
<div>
<h1>Reviews</h1>
#foreach($reviews as $review)
<hr>
<div class="row">
<div class="col-md-12">
#for ($i=1; $i <= 5 ; $i++)
<span class="glyphicon glyphicon-star{{ ($i <= $review->rating) ? '' : '-empty'}}"></span>
#endfor
{{ $review->user ? $review->user->name : 'Anonymous'}}
<p>{{{$review->value}}}</p>
</div>
</div>
#endforeach
</div>
Error
Undefined variable: reviews (View:
C:\xampp\htdocs\restaurantFinder\resources\views\restaurants\viewer.blade.php)
Reviews Controller
class ReviewsController extends Controller
{
public function index()
{
//
}
public function create()
{
//
}
public function store(Request $request)
{
if (!Auth::check()) {
return redirect('/index');
}
$review = new Review;
$review->user_id = auth()->user()->id;
$review->restaurant_id = $request->get('restaurant_id');
$review->value = $request->input('value');
$review->rating = $request->input('rating');
$review->save();
}
public function show($restaurant)
{
// $restaurant=Restaurant::find($id);
return view('restaurants.review', compact('restaurant'));
}
public function edit($id)
{
//
}
public function update(Request $request, $id)
{
//
}
public function destroy($id)
{
//
}
}
you are looking in the wrong place. to track the problem start with your route file. Search for the URL in the web.php file you will find the route there. ones you get the route, you will also get which controller and action are making this page render.
this issue is shown when you use a variable in a blade template but do not set it in the controller for use. In the controller, you can set this variable and you are good to go.
hope this help. incase of any issue feel free to ask.
update your ReviewsController.php
public function show($restaurantID)
{
$reviews = Reviews::find($restaurantID); // Find all reviews model by restaurantID
return view('viewer',compact('reviews ')); // This will do $reviews = reviews
// now you can foreach over reviews in your blade
}
this Link is useful

Passing values from one controller to another

Been at this for ages, can't find a solution. I've searched and none of the posts help, possibly me not getting it as I'm new to Laravel (5.4)
I want to be able to be able to access $site_settings from one controller to another. Also $site_settings need to be accessible on all controllers and views. I also need to get variable from URL (hence Request in __construct( Request $request ) ) but it doesn't work either.
Would really appreciate any assistance.
Thanks.
See code below:
//BaseController
class BaseController extends Controller {
public function __construct( Request $request )
{
$slug = $request->slug;
$site_settings = \DB::table('sites_settings')->where('slug', $slug)->first();
View::share( 'site_settings', ['slug' => $slug, 'color' => $color] );
}
}
class SettingsController extends BaseController
{
// SettingsController
public function index( )
{
//how do I access $site_settings here and pass it on to the view?
// return view('settings.index');
}
}
---- UPDATE with Session ----
//BaseController
class BaseController extends Controller {
public function __construct()
{
$slug = Route::input('slug');
if(Session::get('slug') == $slug)
{
dd(Session::get('slug'));
}
else
{
$site_settings = \DB::table('sites_settings')->where('slug', $slug)->first();
Session::put('slug', $site_settings->slug);
}
}
}

Controller Routing with Parameters

got a little n00b problem with Laravel 4. I have following routes:
Route::get('search', 'MovieController#search');
Route::get('edit/{$id}', 'MovieController#edit');
Route::get('/', 'MovieController#index');
and the following controller:
class MovieController extends BaseController {
protected $layout = 'layouts.master';
public function index()
{
$movies = Movie::paginate(30);
return View::make('index')->with('movies', $movies);
}
public function search()
{
if(isset($_REQUEST['sq'])) {
Cache::forever('sq', $_REQUEST['sq']);
}
$movies = Movie::where('title', 'LIKE', '%'.Cache::get('sq').'%')->paginate(30);
return View::make('index')->with('movies', $movies);
}
public function edit($id) {
return View::make('edit')->with('id', $id);
}
}
Now a call like this won't work:
<a href="edit/{{ $movie->movie_id }}">
I get a "NotFoundHttpException". The URL seems right: laravel/public/edit/2 e.g.
If i remove all the $id stuff from the code, so I route only to edit, it works.
Hopefully I could express myself enough, so somebody can help me. It's driving me nuts.
regards
In your routes.php, it's not Route::get('edit/{$id} ... but Route::get('edit/{id}

Resources