Posts not retrieving the created_at for comments - laravel

I'm trying to retrieve the created_at time for the comments, currently i can add a comment and it will show a time for it, but on refresh the time disappears.
time appears on submit
disappears on refresh, so it needs to be retrieved in the getPosts map method, but im unsure how to include that in.
Can someone point me the right direction, i know it has to do something with this
https://laravel.com/docs/5.5/collections
This is what i currently have.
PostController
public function getPosts( )
{
$posts = Post::with('user')
->with(['likes' => function ($query) {
$query->whereNull('deleted_at');
$query->where('user_id', auth()->user()->id);
}])
->with(['comments' => function($query) {
$query->with('user');
}])
->get();
$data = $posts->map(function(Post $post, Comment $comment )
{
$user = auth()->user();
if($user->can('delete', $post)) {
$post['deletable'] = true;
}
if($user->can('update', $post)) {
$post['update'] = true;
}
$post['likedByMe'] = $post->likes->count() == 0 ? false : true;
$post['likesCount'] = Like::where('post_id', $post->id)->get()->count();
$post['createdAt'] = $post->created_at->diffForHumans();
$post['createdAt'] = $post->updated_at->diffForHumans();
// not getting the time for comments
$comment['comment_createdAt'] = $comment->created_at->diffForHumans();
return array($post, $comment);
});
return response()->json($data);
}
Comment Controller
public function create(Request $request, $post)
{
$data = request()->validate([
'comment_body' => 'required|max:1000'
]);
$data['user_id'] = auth()->user()->id;
$data['name'] = auth()->user()->name;
$data['post_id'] = $post;
$post = Comment::create($data);
// sets a time on a comment instantly im using angular :)
$data['comment_createdAt'] = $post->created_at->diffForHumans();
$response = new Response(json_encode($data));
$response->headers->set('Content-Type', 'application/json');
if(!$response){
return 'something went wrong';
}
return response()->json($data);
}
html
<div ng-show="comments" id="comments" class="col-md-offset-2 animated fadeIn panel-default" ng-repeat="comment in post.comments">
<div style="font-size:10px;" id="eli-style-heading" class="panel-heading">
<a class="link_profile" href="/profile/<% comment.user.name | lowercase %>"><% comment.user.name %></a>
</div>
<figure class="my-comment">
<p> <% comment.comment_body%>
</p>
<p><% comment.comment_createdAt %> </p>
<hr>
</figure>
</div>

To answer your question: As I assume a post has many comments you can not just assign the created date of the post to one comment:
$post['comment_createdAt'] = $post->created_at->diffForHumans();
Instead you should have to loop over all comments and store the date in an array.
But this approach is a bit cumbersome because a Comment object already keeps the created_at value. I would just retrieve the date and format it in the frontend:
<p><% comment.created_at | diffForHumans %> </p>
diffForHumans is a JS implementation which you have to write by yourself.
Update:
Accessors
Model Comment:
class Comment
{
public function getCreatedAtAttribute($value)
{
return Carbon::createFromFormat($this->dateFormat, $value)
->diffForHumans();
}
}
<p><% comment.created_at %> </p>
But this will convert your created_at date all the time it get retrieved. A variation and better approach would be to use a custom Accessor:
class Comment
{
public function getCreatedAtHumanDiffedAttribute()
{
return Carbon::createFromFormat($this->dateFormat, $this->created_at)
->diffForHumans();
}
}
<p><% comment.created_at_human_diffed %> </p>
More about them here:
API Resources
Use API Resources. Your usecase is excactly what they are made for.
Honestly, your code has issues. Some remarks:

Related

How to store dynamically input name and value both in Controller

This is my blade file where the input type is a radio and I have made name dynamically by giving question id so that I can store in question_id. So How can I store them in Controller.
#foreach($question->answers as $index=> $answer)
<span>
<input type="radio" name="{{$question->id}}" value="{{$answer->id}}" id="answer{{$question->id}}"
class="clickanswer" data-id="{{$answer->id}}">
{{$index+1}}) {!! $answer->answer_body !!}
</span>
#endforeach
Now this is my Controller
public function quizTest(Request $request){
if($request->isMethod('post')){
$data=$request->all();
foreach($data as $question_id => $answer_id){
dd($data);
$result=new Result;
$result->user_id=$data['user_id'];
$result->question_id=$question_id;
$result->answer_id=$answer_id;
$result->save();
}
}
}
Now when I do dd($data); and I want to store data like 1 2 3 4 5 in question_id and 2,6,9,13,18 in answer_id
Change your controller code to this to store it in answer and question format
public function quizTest(Request $request){
if($request->isMethod('post')){
$data=$request->all();
$user_id = $data['user_id'];
unset($data['_token']);
unset($data['user_id']);
foreach($data as $question_id => $answer_id){
$result = new Result;
$result->user_id = $user_id;
$result->question_id = $question_id;
$result->answer_id = $answer_id;
$result->save();
}
}
}

Why does the old() method not work in Laravel Blade?

My environment is Laravel 6.0 with PHP 7.3. I want to show the old search value in the text field. However, the old() method is not working. After searching, the old value of the search disappeared. Why isn't the old value displayed? I researched that in most cases, you can use redirect()->withInput() but I don't want to use redirect(). I would prefer to use the view(). method
Controller
class ClientController extends Controller
{
public function index()
{
$clients = Client::orderBy('id', 'asc')->paginate(Client::PAGINATE_NUMBER);
return view('auth.client.index', compact('clients'));
}
public function search()
{
$clientID = $request->input('clientID');
$status = $request->input('status');
$nameKana = $request->input('nameKana');
$registerStartDate = $request->input('registerStartDate');
$registerEndDate = $request->input('registerEndDate');
$query = Client::query();
if (isset($clientID)) {
$query->where('id', $clientID);
}
if ($status != "default") {
$query->where('status', (int) $status);
}
if (isset($nameKana)) {
$query->where('nameKana', 'LIKE', '%'.$nameKana.'%');
}
if (isset($registerStartDate)) {
$query->whereDate('registerDate', '>=', $registerStartDate);
}
if (isset($registerEndDate)) {
$query->whereDate('registerDate', '<=', $registerEndDate);
}
$clients = $query->paginate(Client::PAGINATE_NUMBER);
return view('auth.client.index', compact('clients'));
}
}
Routes
Route::get('/', 'ClientController#index')->name('client.index');
Route::get('/search', 'ClientController#search')->name('client.search');
You just need to pass the variables back to the view:
In Controller:
public function search(Request $request){
$clientID = $request->input('clientID');
$status = $request->input('status');
$nameKana = $request->input('nameKana');
$registerStartDate = $request->input('registerStartDate');
$registerEndDate = $request->input('registerEndDate');
...
return view('auth.client.index', compact('clients', 'clientID', 'status', 'nameKana', 'registerStartDate', 'registerEndDate'));
}
Then, in your index, just do an isset() check on the variables:
In index.blade.php:
<input name="clientID" value="{{ isset($clientID) ? $clientID : '' }}"/>
<input name="status" value="{{ isset($status) ? $status : '' }}"/>
<input name="nameKana" value="{{ isset($nameKana) ? $nameKana : '' }}"/>
...
Since you're returning the same view in both functions, but only passing the variables on one of them, you need to use isset() to ensure the variables exist before trying to use them as the value() attribute on your inputs.
Also, make sure you have Request $request in your method, public function search(Request $request){ ... } (see above) so that $request->input() is accessible.
Change the way you load your view and pass in the array as argument.
// Example:
// Create a newarray with new and old data
$dataSet = array (
'clients' => $query->paginate(Client::PAGINATE_NUMBER),
// OLD DATA
'clientID' => $clientID,
'status' => $status,
'nameKana' => $nameKana,
'registerStartDate' => $registerStartDate,
'registerEndDate' => $registerEndDate
);
// sent dataset
return view('auth.client.index', $dataSet);
Then you can access them in your view as variables $registerStartDate but better to check if it exists first using the isset() method.
example <input type='text' value='#if(isset($registerStartDate)) {{registerStartDate}} #endif />

Laravel 5 (custom) method for calculating age(in days) does not exist

there's a lot of similar questions but I did not find the solution for my problem, so here's the issue:
I have a simple function that should be used for calculating age (in days), listed in the SubmissionController:
public function agingDate($sub) {
$to = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $sub);
$now = Carbon::now();
$diff_in_days->age = $to->diffInDays($now);
return $diff_in_days;
}
Also, in the same controller:
public function index() {
$submission = Submission::orderBy('location_address_state', 'asc')
->get();
return view('/subs/index', [
'submission' => $submission
]);
}
And finally, in my view, I'm trying to call this function:
#if($submission)
#foreach($submission as $sub)
<p>{{ $sub->created_at->agingDate() }}</p>
#endforeach
#endif
The message I'm receiving is "Method agingDate does not exist. (View: /subs/index"). Why can't I access this function - it's in the same controller?
In order to keep the separation of concerns intact, I would suggest that you move your agingDate() method into your submission model.
So, in your Submission model, you could refactor it in the following way:
public function agingDate() {
$to = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $this->created_at);
$now = Carbon::now();
return $to->diffInDays($now);
}
In your blade file, you should then be able to call:
#if($submission)
#foreach($submission as $sub)
<p>{{ $sub->agingDate() }}</p>
#endforeach
#endif
The approach you are currently using doesn't work, since you are trying to call the aging method on a plain property of your Submission instance.

Trying to get property 'post_titile' of non-object

This is My Controller.
public function show(Posts $posts)
{
$page = Posts::find($posts->id);
//dd($page);
return view('web_views.index',['page' => $page]);
}
This is my view page
<h4>{{$page->post_titile}}</h4>
It's better to use Route-Model Binding I think.
Your route (if you are using resource route, it's already done):
Route::get('posts/{post}', 'PostController#show); // domain.tld/posts/1
Your method should look like this:
public function show(Post $post)
{
return view('web_views.index',compact('post'));
}
In your view:
<h4>{{ $post->post_titile }}</h4>
May be $posts->id you are passing, has no result in database so you need to check it by using if-statement
public function show(Posts $posts)
{
$page = Posts::find($posts->id);
if($page == null){
$page = ['post_title' => 'Not Available'];
}
return view('web_views.index',['page' => $page]);
}
I believe this error is because of not finding data for an ID into database. So if as per above script will pass the fetched data to view otherwise it will push an item into $page array.

Laravel 5.5 - Save multiple data continiously from blade

I want to make a PHP method using laravel. I want to do the comparison of criteria and criteria. Here is the controller code :
public function create()
{
$kriteria1 = Model\Kriteria::pluck('nama_kriteria', 'id');
$kriteria2 = Model\Kriteria::pluck('nama_kriteria', 'id');
return view('kriteria_kriterias.create')->with('kriteria1', $kriteria1)->with('kriteria2', $kriteria2)->with('data', $data);
}
and this is the blade code :
It will make the form appear as total of criteria#
The problem is, I can't save it all to database. How do I get it to do this?
Updated method in the controller to the following:
public function create()
{
$kriteria1 = Model\Kriteria::pluck('nama_kriteria', 'id');
$kriteria2 = Model\Kriteria::pluck('nama_kriteria', 'id');
$data = [
'kriteria1' => $kriteria1,
'kriteria2' => $kriteria2
];
return view('kriteria_kriterias.create')->with($data);
}
How to output in the blade file:
{{ $kriteria1 }}
{{ $kriteria2 }}
Or you update the controller to pass the complete results:
public function create($id1, $id2)
{
$kriteria1 = Model\Kriteria::find($id1);
$kriteria2 = Model\Kriteria::find($id2);
$data = [
'kriteria1' => $kriteria1,
'kriteria2' => $kriteria2
];
return view('kriteria_kriterias.create')->with($data);
}
And the in the blade you can accss the data in various ways, one way is a foreach loop using blade in the blade template:
#foreach($kriteria1 as $k1)
{{ $k1 }}
#endforeach
#foreach($kriteria2 as $k2)
{{ $k2 }}
#endforeach'
To accept multiple values dynamicaly in the controller you can try something like this:
public function create($ids)
{
$results = collect([]);
foreach($ids as $id) {
$kriteria = Model\Kriteria::findOrFail($id);
if($kriteria) {
$results->put('kriteria' . $id, $kriteria);
}
}
return view('kriteria_kriterias.create')->with($results);
}
Then use the same looping method mentioned above to display them in the blade or a for loop that gets the count and displays accordingly.
maybe you forgot to add the opening tag ;)
{!! Form::open(array('url' => 'foo/bar')) !!}
//put your code in here (line 1-34)
{!! Form::close() !!}

Resources