Pulling Single Quote From DB and displaying on page using Laravel - laravel-5.7

I have some quotes in a database and am trying to use Laravel to display it on a page. I have the quotes being pulled from the controller then passed to the view but I am getting an error:
Undefined variable: quotes (View: C:\laragon\www\resources\views\inc\quote.blade.php) (View: C:\laragon\www\\resources\views\inc\quote.blade.php) (View: C:\laragon\www\\resources\views\inc\quote.blade.php
QuotesController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
class QuotesController extends Controller
{
public function index()
{
$quotes = DB::table('quotes')->get();
return view('inc.quote', ['quotes' => $quotes]);
}
}
quote.blade.php
<div id="MarketingQuote" class="container-fluid padding bg-light">
<div class="row">
<div class="col-lg-6">
<h2>Marketing Quote of the day</h2>
#foreach($quotes->all() as $quote)
<li>{{$quote}}</li>
#endforeach
<br>
</div>
<div class="col-lg-6">
<img src="img/computer.jpg" class="image-fluid" alt="">
</div>
</div>
</div>
Migration Table for Quotes
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateQuotesTable extends Migration
{
public function up()
{
Schema::create('quotes', function (Blueprint $table) {
$table->bigIncrements('id');
$table->text('quote');
$table->string('author');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('quotes');
}
}
Why do I get this error? And how do I get only one quote to display at a time and only change upon each page refresh?
Thank you.

I advise you to input the variable $quotes in the controller, And I remember the passed variable array key which can use and not have to use all function.
The below code from laravel manual:
Route::get('greeting', function () {
return view('welcome', ['name' => 'Samantha']);
});
Hello, {{ $name }}.
change
#foreach($quotes->all() as $quote)
<li>{{$quote}}</li>
#endforeach
into
#foreach($quotes as $quote)
<li>{{$quote}}</li>
#endforeach

Related

Missing required parameters for [Route: {$route->getName()}] [URI: {$route->uri()}]."

in new to laravel and Im trying to set up an edit blade using resource controller . ( using laravel 5.7) but it is throwing an error like this
Missing required parameters for [Route: home.hotels.update] [URI: home/hotels/{hotel}]. (View: C:\xamp\....\.....\edit.blade.php)
Please note:
when i hover over edit button it is correctly pointing to the id's and
when i tries to echo a fieldname inside my "edit function"in controller it returns the correct page but "blank" . can some one tell me wher this error comming from and if possible how to fix this
code in my index blade ( part relating to the edit)
#foreach($hotels as $c)
<tr>
<td>{{$c->hotelid}}</td>
<td>{{$c->hotelname}}</td>
<td>{{$c->city}}</td>
<td>{{$c->location}}</td>
<td>{{$c->singleroom}}</td>
<td>{{$c->doubleroom}}</td>
<td>{{$c->deluxroom}}</td>
<td>{{$c->deluxdouble}}</td>
<td>{{$c->superiorsuit}}</td>
<td><a href="{{route('home.hotels.edit',$c->id)}}"class="btn btn-info" >Update </a>
my edit blade
im passing the entries like this
<form method="post" action="{{route('home.hotels.update',$hotels->id)}}">
#csrf
{{ method_field('PUT') }}
<div class="form-group">
<div class="row">
<label class="col-md-6">Hotel ID</label>
<div class="col-md-6"><input type="text" name="hotelid" class="form-control" value="{{$hotels->hotelid}}"> </div>
</div>
......... rest of the input fields follows........
controller functions
public function index()
{
$arr['hotels']=hotels::all();
return view('admin.hotels.index')->with($arr);
}
my update function also has the same code as store ------
public function store(Request $request, hotels $hotels)
{
$hotels->hotelid=$request->hotelid;
$hotels->hotelname=$request->hotelname;
...........other fields..................
$hotels->save();
return redirect('home/hotels');
}
public function edit(hotels $hotels )
{
$arr['hotels'] = $hotels;
return view('admin.hotels.edit')->with($arr);
}
and my routes
Route::get('/home', 'HomeController#index')->name('home');
Route::resource('home/users', 'Admin\UsersController',['as'=>'home']);
Route::resource('home/hotels', 'Admin\HotelsController',['as'=>'home']);

Laravel Facades in VueJS Template?

I just created a symbolic link using this command php artisan storage:link to be able to access my files from the web. I've known this from Laravel's official docs: https://laravel.com/docs/5.3/filesystem#configuration.
And so I'm using <img src="{{ Storage::url($user->avatar) }}"> in my blade template to get the path of my image.
My question is, how can I achieve similar approach using VueJS Template?
I tried <img src="{{ Storage::url($user->avatar) }}"> in my .vue file but got an error when running gulp watch. The error throws an invalid expression. Simple means I can't use Laravel's Facades inside a .vue file?
What would be the best approach in getting the correct path of my image then? Use $avatar = Storage::url($user->avatar); and inject it to an array before getting it in .vue file?
For reference here's my:
VueJS File
<template>
<div class="row">
<div class="col-md-4" v-for="person in people">
<div class="panel panel-default">
<div class="panel-heading text-center">
{{ person.name }}
</div>
<div class="panel-body">
<img :src="person.avatar" class="img-responsive">
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
this.$http.get('/people/')
.then((res) => {
console.log(res)
this.people = res.body.people
})
},
data() {
return {
people: '',
}
}
}
</script>
Route
Route::group(['prefix' => 'people', 'middleware' => ['auth']], function () {
Route::get('/', [
'uses' => 'PeopleController#index',
'as' => 'people',
]);
});
Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class PeopleController extends Controller
{
public function index () {
$people = User::all();
return response()->json(['people' => $people]);
}
}
Why not set the storage path in your User model.
Create an avatar_url attribute in your model.
use Illuminate\Support\Facades\Storage;
class User extends Model {
protected $appends = ['avatar_url'];
....
public function getAvatarUrlAttribute() {
return Storage::url($this->avatar);
}
...
}
Then in your VueJS file...
<img :src="person.avatar_url" class="img-responsive">

How to pass async variable in template (action) function?

I need to pass async variable to the function.
Something like this:
<div class="team" (click)="addToFavorite((match | async)?.id)">
And of course I have an error.
Parser Error: Cannot have a pipe in an action expression.
Maybe there is a way to transform async variable in JavaScript?
Here is how I solved it :
<div *ngIf="(match | async) as match" class="team" (click)="addToFavorite(match.id)">
It's short, simple and it works.
<ng-container *ngIf="(match | async) as match">
<div class="team" (click)="addToFavorite(match.id)">
</div>
</ng-container>
Update January 20th 2021
To be more clear I would name match observable source as match$.
And we can now use the new #ngrx/component package and use the new ngrxLet structural directive :
<ng-container *ngrxLet="match$ as match">
<div class="team" (click)="addToFavorite(match.id)">
</div>
</ng-container>
The async pipe is no more necessary.
More info on ngrx.io, on this link.
Another option for simple variables and without any observables is writing value of the variable into hidden input:
<div *ngIf="(match | async)?.id">
<input #myControl [value]="(match | async).id" type="hidden" />
<div class="team" (click)="addToFavorite(myControl.value)">
</div>
You can't do it in template.
But you can:
<div class="team" (click)="addToFavorite()">
and in your .component.ts:
public addToFavorite() {
this
.match // should retain last value (e.g. use BehaviorSubject)
.first() // completes after passing one value only
.subscribe(
(matchValue) => {
// your logic here
});
}
Note: We are subscribing (and immediately unsubscribing), similarly async pipe subscribes to Observable.
What about:
<div class="team" (click)="addToFavorite(match)">
and then in your code:
addToFavorite(obs: Observable<any>) {
obs.take(1).subscribe(value => {
addToFavoriteById(value.id);
});
}
Seems you need to use a helper method:
<div class="team" (click)="onClick(match)">
class MyComponent {
onClick(event) {
event.then(val => this.addToFavorite(val?.id);
}
addToFavorite(val) {
}
}

Form submit error, Failed to convert value of type 'java.lang.String' to required type error in browser, In spring MVC

So, I'm trying to create comments on a post using spring mvc, spring boot, spring data, jpa, and thymeleaf, and so far I can get to the specific page I want, using the controller and pathvariables, and I can load up the page just how I want, but when I go to submit the comment I get the error
There was an unexpected error (type=Bad Request, status=400).
Failed to convert value of type 'java.lang.String' to required type 'com.example.domain.Comment'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type java.lang.Long for value 'comment 1'; nested exception is java.lang.NumberFormatException: For input string: "comment1"
This error is only in my browser, nothing comes up in the console in my IDE. Also I can access the page just fine, so there I don't think there's an issue in my get method in my controller, but I'm not really sure where the problem is, so I'll show you guys some of my code.
Here's my controller.
private PostRepository postRepo;
#RequestMapping(value="viewCourse/post/{postId}", method=RequestMethod.GET)
public String postViewGet (#PathVariable Long postId, ModelMap model)
{
Post post = postRepo.findOne(postId);
model.put("post", post);
Comment comment = new Comment();
model.put("comment", comment);
return "post";
}
#RequestMapping(value="viewCourse/post/{postId}", method=RequestMethod.POST)
public String postViewPost (#ModelAttribute Comment comment, #PathVariable Long postId, ModelMap model)
{
Post post = postRepo.findOne(postId);
comment.setPost(post);
post.getComments().add(comment);
postRepo.save(post);
return "redirect:/viewCourse/{postId}";
}
#Autowired
public void setPostRepo(PostRepository postRepo) {
this.postRepo = postRepo;
}
Here's my thymeleaf html page
<div class="PostContent">
<h2 th:text = "${post.title}"></h2>
<p th:text = "${post.content}"></p>
</div>
<br/>
<div class="CommentPost">
<form th:action="${post.id}" method="post" th:object="${comment}" id="comment">
<div class="form-group">
<textarea rows="2" th:field="${comment.comment}" class="form-control" placeholder="comment" id="comment"></textarea>
</div>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<input type="submit" value="Comment" class="btn btn-success"/>
</form>
</div>
<br/>
<div class="Comments">
<div th:each = "comment : ${comments}" th:object="${comment}">
<span th:text="${comment.comment}"></span>
</div>
<div th:if = "${#lists.isEmpty(comments)}">
There are no comments to display
</div>
</div>
</div>
Also on this page the message comes up "There are no comments to display", just like I tell it to in the code, but it still says "There are no comments to display" even if I manually insert a comment into the database.
Here's my comment object, although I'm pretty sure that's fine.
#Entity
public class Comment {
public Long id;
public String comment;
public Post post;
public User user;
#Id
#GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
#ManyToOne
public Post getPost() {
return post;
}
public void setPost(Post post) {
this.post = post;
}
#ManyToOne
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
And my postRepo, although this should be fine, just thought I'd include it
public interface PostRepository extends JpaRepository <Post, Long>{
}
If anyone can see my issue, and let me know, that would be awesome, thanks.
When you use th:object don't have to reference to object, you access directly atributes of object. Try with this code:
<div class="PostContent">
<h2 th:text = "${post.title}"></h2>
<p th:text = "${post.content}"></p>
</div>
<br/>
<div class="CommentPost">
<form th:action="${post.id}" method="post" th:object="${comment}" id="comment">
<div class="form-group">
<textarea rows="2" th:field="*{comment}" class="form-control" placeholder="comment" id="comment"></textarea>
</div>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<input type="submit" value="Comment" class="btn btn-success"/>
</form>
</div>
<br/>
I don't see in the controller where you put the comments in the model. I suppose that comments there are inside the post so modify the refereces of comments to post.comments
<div th:each = "comment : ${post.comments}" th:object="${comment}">
<span th:text="*{comment}"></span>
</div>
<div th:if = "${#lists.isEmpty(post.comments)}">
There are no comments to display
</div>
</div>
</div>
The problem is that the name of Class - Comment - and the field - comment - are the same, regarding to insensitive way, causing problem due to Java Reflection use to read the field and its class.
The solution was to rename the field, like "comment" to "commentary", and to avoid to change again in database, if there is some, just put the annotation #Column(name="comment") above the field.
Perhaps, reference from main template on thymeleaf template in question look like:
th:href="#{/post/{${post.getId()}}",
but it should look like:
th:href="#{/post/{postId}(postId=${post.getId()})}"
In my occasion, it helped me

How to access implicit objects in my templates

I want to know what is the current url of my template. I have read here that the "request" is an implicit object present in all templates which returns the url of my template.
So I have tried this:
Controllers:
public class Application extends Controller {
public static Result index() {
return redirect("/home");
}
public static Result home() {
return ok(homePage.render());
}
public static Result aboutUs() {
return ok(aboutUs.render());
}
}
HTML:
leftbar.scala.html file:
<aside id="left-panel">
<nav>
<ul class="animated fadeInLeft">
<li class="#if(request.uri.contains("/aboutus")){active}">(some code here)</li>
</ul>
</nav>
</aside>
homePage.scala.html file:
#scripts = { (some scripts here) }
#views.html.main("Beta Project", scripts) {
#views.html.leftbar()
<div id="main" role="main">
<div id="content">
<span><i class="fa fa-bell"></i>SOMETHING</span>
</div>
</div>
}
Where I import the leftbar.scala.html file I get this error:
not found: value request
What should I do to solve this error? Thanks in advance
A bit more code from your template would be useful, but you can probably fix it by adding
(implicit request: Request[AnyContent])
at the end of the first line on your template.

Resources