Laravel 8: Call to a member function notify() on string - php

I'm working with Laravel 8 to make a forum and now I wanted to send a notification to a user who has asked a question whenever someone answered that question.
So in order to do that, I added this to the Controller:
public function postAnswer(Request $request, $question, $asker) {
$validate_data = $request->validate([
'answer' => 'required',
]);
$answer = Answer::create([
'answer' => $request->answer,
'user_id' => auth()->user()->id,
'question_id' => $question,
]);
$asker->notify(new RepliedToThread($question));
return back();
}
So the $question is the question id and $asker is the user id of the person who has asked the question.
But now I get this error:
Call to a member function notify() on string
Now the interesting part is that, when I use auth()->user()->notify(new RepliedToThread($question));, it is working fine!
But I don't want to notify any authenticated user, I need to notify the person who has asked question, that's why I tried passding $asker...
So if you know how to solve this question, please let me know...
I would really appreciate any idea or suggestion from you guys.
Thanks in advance.
Blade:
<form action="{{ route('questions.answers', ['question' => $show->id, 'asker' => $show->user->id]) }}" method="POST" enctype="multipart/form-data">
#csrf
<div class="mb-4">
<textarea name="answer" id="answer" class="form-control BSinaBold" rows="7" placeholder="Write down answer"></textarea>
#error('answer')
<div class="text-red-500 mt-2 text-sm">
{{ $message }}
</div>
#enderror
</div>
</br>
<button type="submit" class="btn btn-primary">Send</button>
</form>

The problem is that asker is just an id, you should take the other information of the asker from the user table and after that pass your notification to the asker.
$asker = User::findOrFail($asker);
$asker->notify(new RepliedToThread($question));

Based on what you said, the problem is $asker. This parameter should be an instance from User model but the error implies it is string.
In your form change the form tag:
<form action="{{ route('questions.answers', ['question' => $show->id, 'asker' => $show->user]) }}" method="POST" enctype="multipart/form-data">
Remove the id after user.

make sure your Answer.php have use Notifiable; imported
ref link https://laravel.com/docs/8.x/notifications#using-the-notifiable-trait
then only you can call notify() function from Answer model instance

The problem is that $asker is just a string, its just the idvalue of the user.
I recommend that you use laravels route model binding. The passed parameters $querstion and $asker are automatically queried from the database.
https://laravel.com/docs/8.x/routing#route-model-binding
Afterwards you can access the question id normally and you have the notifiable user model.
public function postAnswer(Request $request, Question $question, User $asker) {
$validate_data = $request->validate([
'answer' => 'required',
]);
$answer = Answer::create([
'answer' => $request->answer,
'user_id' => auth()->user()->id,
'question_id' => $question->id,
]);
$asker = User::find($asker);
$asker->notify(new RepliedToThread($question));
return back();
}

Related

i'm having trouble with adding new replies using laravel8

Before question , This is my code
Show.blade.php
#foreach ($comments as $comment)
#if ($comment->post_id == $post->id)
.....
<form action="{{ route('createreply', ['rid' => $comment->id]) }}" method="POST">
#csrf
<input type="text" class="form-control" name="replyContent" id="replyContent" style="color:white" />
<button type=" submit" style=" color :lavender " class="btn btn-secondary">comment</button>
</form>
....
#endif
#endforeach
(( comment is original comment, and i made reply for answer of comment ))
web.php (route)
Route::post('/replycreate', [CommentController::class, 'createReply'])->name('createreply');
my controller (comment)
public function createReply(Request $request, $rid)
{
$reply = new Reply();
$reply->replyContent = $request->replyContent;
$reply->user_name = Auth::user()->name;
$reply->comment_id = $rid;
dd($reply);
$reply->save();
return redirect()->back();
}
I have problem with making re-reply,
and my code returns error and it says
Too few arguments to function App\Http\Controllers\CommentController::createReply(), 1 passed in C:\Users\ALSACE\post-app\vendor\laravel\framework\src\Illuminate\Routing\Controller.php on line 54 and exactly 2 expected
I tought i had used two argument , but this kind of error occurs.
so i tought using dd($reply),
dd() can't even complete.
you can guess $rid is empty .. but in the same Show.blade.php , I had used $comment with no problem so i think i can not be problem.
plz help with newbe Laravel student!!
Your createReply method expect 2 arguments, BUT you don't have variable in your route.
You must change the route to:
Route::post('/replycreate/{rid}', [CommentController::class, 'createReply'])->name('createreply');
You forgot to add the id to the route itself. If you're going to require it in the function parameters, then it needs to be added on the route URL.
Route::post('/replycreate/{rid}', [CommentController::class, 'createReply'])->name('createreply');

Laravel 8 Unique form validation ignore

My form edit
<form action="{{ route('admin.akun.update', $akun->id_pegawai) }}" method="POST">
#csrf
#method('patch')
<input type="text" class="form-control" #if (old('nip')) value="{{old('nip')}}" #else value="{{$akun->nip}}" #endif name="nip">
My Route
Route::patch('admin/akun/{id_pegawai}', 'AkunController#update')->name('admin.akun.update');
My Controller
public function update(Request $req, $id_pegawai)
{
$user = new User;
$pegawai = new Pegawai;
$this->validate($req, [
'nip' => ["required", "unique:users,nip," . $id_pegawai],
]);
}
condition: I edit my data, I have a unique field, if I don't change the unique field it will be successfully edited, and if I replace it with the same data there will be an alert
You need to specify against which column you want to be unique
Rule::unique('users', 'nip')->ignore($id_pegawai, 'id_pegawai'),
Try it like this:
["required", "unique:users,nip,".$id_pegawai]
Documentatin: https://laravel.com/docs/8.x/validation#rule-unique
Syntax: unique:table,column,except,idColumn

Routes and controller methods for a multi step form are not correct, it appears "The page has expired due to inactivity"

I have a multi step form using bootstrap and jQuery. The multi step form is for a user to buy a product. There are 4 steps:
- Step 1 is for the user insert his info (name, email, etc)
- Step 2 the user select the payment method
- Step 3 the user introduces the payment data
- Step 4 present an invoice for the user.
So I want to divide the form in 4 steps, each step with a respective method in the PaymentController. But the routes or controller methods should have some error because Im getting "The page has expired due to inactivity" when "go to step 2" button is clicked. Do you know where is the error?
The flow of the context is:
The user clicks in a product and goes to the product details page. In the product details page the user select the quantities. So there is a select menu inside a form with this action "<form method="post" action="{{route('products.storeProduct', ['id' => $product->id, 'slug' => $product->slug])}}">".
The route for this form is and to present the payment page:
Route::post('/product/{id}/{slug?}/payment', [
'uses' => 'PaymentController#storeProduct',
'as' =>'products.storeProduct'
]);
Route::get('/product/{id}/{slug?}/payment', [
'uses' => 'PaymentController#presentPaymentPage',
'as' =>'products.payment'
]);
In the PaymentController, the storeProduct method stores the product, get some info from db and then redirect the user to the products.payment route to present the payment page page:
class PaymentController extends Controller
{
public function storeProduct(Request $request, $id, $slug = null){
...
return redirect(route('products.payment',['id' => $id, 'slug' => $slug]));
}
public function presentPaymentPage(Request $request, $id, $slug=null){
...
return view('products.payment',
['product' => $product, 'id' => $id, 'slug' => $slug]);
}
}
So now the user is on the payment page. In this page appears the mult is step form, the first step is step 1 in this first step appears a form for the user introduce somer user info like name, email, etc. The action of the form is for the storeUserInfo() method where the information introduced by the user should be stored in session. Code in the payment.blad.ephp for step 1:
<div class="tab-pane fade show active clearfix" id="step1" role="tabpanel" aria-labelledby="home-tab">
<h6>User Info</h6>
<form method="post" action="{{route('products.storeUserInfo', ['id' => $id, 'slug' => $slug])}}">
<div class="form-group font-size-sm">
<label for="name" class="text-gray">Name</label>
<input type="text" required class="form-control" value="{{ (\Auth::check()) ? Auth::user()->name : old('name')}}">
</div>
<!-- other form fields -->
<input type="submit" href="#step2"
class="btn btn-primary btn float-right next-step" value="Go to step 2"/>
</form>
</div>
In the PaymentController I added two methods:
public function storeUserInfo(Request $request, $id, $slug = null){
dd($request->all());
}
public function presentPaymentMethods(Request $request, $id, $slug=null){
}
And in web.php two routes:
Route::post('/product/{id}/{slug?}/payment/storeUserInfo', [
'uses' => 'PaymentController#storeUserInfo',
'as' =>'products.storeUserInfo'
]);
Route::get('/product/{id}/{slug?}/payment/paymentMethods', [
'uses' => 'PaymentController#presentPaymentMethods',
'as' => 'products.presentPaymentMethods'
]);
When user click in "Go to step 2" he is redirected to ""store.test/product/5/a-5/payment/storeUserInfo";" but it appears "The page has expired due to inactivity. Please refresh and try again". Do you know where is the issue?
You may have missed the CSRF protection as I can't see it on your form: https://laravel.com/docs/5.6/csrf

update table with laravel

I can`t update my table. Maybe you can see where is problem.
Edit works fine. It brings value to the fields. If i erase {{ method_field('PUT') }} it saves values normally, but i need to UPDATE
It`s my UPDATE controller
public function update(Request $request, Radar $radar)
{
Radar::update([
'date' => $request->input('date'),
'number' => $request->input('number'),
'distance' => $request->input('distance'),
'time' => $request->input('time'),
]);
return redirect('/radars');
}
Thats how my view looks like:
<form action="{{ url('/radars')}}" method="post" >
{{ method_field('PUT') }}
{{ csrf_field() }}
Routes:
Route::put('radars/{radar}', 'RadarsController#update');
Error:
MethodNotAllowedHttpException
No message
Thank you for help.
You need to specify ID:
{{ url('/radars/') . $radar->id }}
Also, you need to use object and not just a model class. Something like:
public function update(Request $request, Radar $radar)
{
$radar->update($request->all());
return redirect('/radars');
}
Illuminate\Support\Facades\Request
Radar::update(Request::all());
Looking at it, I think it should be like the below:
<form action="{{ url('/radars/' . $radar->id )}}" method="post" >
If you look, you're posting to /radars but your route is radars/{driver}
You need to add where statement to tell which record to update and dont
Radar::where('id',$id)->update([
'date' => $request->input('date'),
'number' => $request->input('number'),
'distance' => $request->input('distance'),
'time' => $request->input('time'),
]);
return redirect('/radars');
If you are using resource route, then in your form, you need to change action from:
url('/radars')
to
route('radars.update', $radar)
and keep the following:
{{ method_field('PUT') }}

i cant pass the parameter id on the URI slim framework

i have an update form to update the product details :
<form action="{{ path_for('product.update', {id: product.id}) }}" method="get">
// another fields
<input type="hidden" name="_METHOD" value="PUT">
<input type="submit" name="submit" class="submit" value="update">
routes :
$app->get('/admin/product/edit/{id}', ['maimana\Controllers\AdminController','editupdateProduct'])->setName('product.edit');
$app->get('/admin/product/update/product/{id}', ['maimana\Controllers\AdminController','updateProduct'])->setName('product.update');
and the controller :
public function updateProduct($id, Request $request, Response $response){
$product = $this->product->where('id',$id)->first()->update([
'title' => $request->getParam('title'),
'category' => $request->getParam('category'),
'slug' => $request->getParam('slug'),
'description' => $request->getParam('description'),
'price' => $request->getParam('price'),
'image' => $request->getParam('image'),
'stock' => $request->getParam('stock')
]);
return $response->withRedirect($this->router->pathFor('admin.product'));
}
everytime i hit the update button, i cant pass the parameter is automatically and it turns PAGE NOT FOUND. but when i add the id manually it works and redirect back to admin.product.
please help me im getting stuck for about 4 days and i need this for my college task
Slim also uses Restful URLs it seems. When you have the _method set to 'put' in the form and sends the request, it will interpret it as a PUT request rather than a GET. Since this is your college task, I think I've helped you with 99% of the problem here.

Categories