Need to print name instead of id in vue.js frontend and Laravel backend - laravel

Here is my CategoryController.php code...
public function name($id) {
$f = Category::findOrFail($id);
$nm = $f->name;
return $nm;
}
Here is my router.
Route::get('/category/{id}', [CategoryController::class, 'name']);
In vue.js I defined this in method,
async getCategoryName($id){
await this.callApi('get','/category/' + $id)
.then(response => {
this.name = response.data.name
return this.name;
});
}
In the table, I need to get category name instead of category id. from URL I get category name but It shows that [object promise]
<table class="_table">
<!-- TABLE TITLE -->
<tr>
<th>ID</th>
<th>Category Name</th>
<th>Name</th>
<th>Created At</th>
<th>Action</th>
</tr>
<!-- TABLE TITLE -->
<!-- ITEMS -->
<tr v-for="(tag, i) in tags" :key="i" if="tags.length">
<td>{{tag.id}}</td>
<td>{{getCategoryName(tag.categoryId)}}</td>
<td class="_table_name">{{tag.name}}</td>
<td>{{tag.created_at}}</td>
<td>
<Button type="info" size="small" #click="showEditModal(tag, i)">Edit</Button>
<Button type="error" size="small" #click="showDeletingModal(tag, i)" :loading="tag.isDeleting">Delete</Button>
</td>
</tr>
</table>
Please help me...

This is the normal behaviour of vue.js, why don't you add the category name in your controller instead of loading it server side, your approach is not good performance wise.
In your controller where you get the view you will have something like: $tags = Tag::all()
You can simply load in each categroy: $tags = Tag::with('category')->get()
In your vue app you can then simply access the name like: tag.category.name

Related

Laravel get one record from the database

Im trying to make a list with game developers, and when you click on one of them you can see the games they have made. I only dont know how to get further....
This is what i have now:
Index.blade.php:
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">Naam</th>
<th scope="col">Opgericht in:</th>
</tr>
</thead>
<tbody>
#foreach($gamedevs as $gamedev)
<tr>
<td>{{ $gamedev['id'] }} </td>
<td>{{ $gamedev['naam'] }}</td>
<td>{{ $gamedev['opgericht'] }}</td>
</tr>
#endforeach
</tbody>
I already tried some methods like these:
href="{{route('games.show', ['id'=>$gamedev->id])}}
and
href="/games/{{$gamedev['id']}}
listcontroller.php
public function index()
{
$gamedevs = Gamedevs::all();
return view("index", [ 'gamedevs' => $gamedevs]);
}
public function show(Gamedevs $gamedevs)
{
$gamedevs = Gamedevs::where($gamedevs)->first();
return view('pages.games.show')->with('Gamedevs',$gamedevs);
}
Never did this before.. so hope im on the right way :)
Laravel controller methods like show will use service container to resolve all the parameters you define there. Since you define a model, laravel will automatically find the one corresponding with explicit model binding.
So you wont have to write another query to show your Gamedev:
public function show(Gamedevs $gamedevs)
{
return view('pages.games.show')->with('Gamedevs',$gamedevs);
}
Sample route in web.php
Route::get('/games/{dev_id}','listController#show');
Sample Method in your listController.php
public function show($gamedevs)
{
#let's say your $gamedevs is your devs id so target their id's
$devs = Gamedevs::where('id',$gamedevs)->first();
return view('pages.games.show')->with([
'Gamedevs'=>$devs
]);
}
In your view
href="/games/{{$Gamedevs->id}}

Angular 8 Pagination with Data from Database --

I am having a little trouble with this one.
Using the approach discussed in this -- https://jasonwatmore.com/post/2019/06/18/angular-8-simple-pagination-example
Use-case difference is, my data all comes from database. So I have had to use a model class and all. But, due to some problem, I am getting the same data [1st row from db] in all the rows. Let me post the code I used --
ANGULAR
method inside my component to get data from service class
newsTopics: NewsTopic[];
pageOfItems: Array<NewsTopic>;
getAllNewsTopics() {
this.userService.getAllTopics()
.subscribe((data: NewsTopic[]) => {
this.newsTopics = (data as NewsTopic[]).map((x, i) => ({ Id: (i + 1), TopicId: data[0].TopicId, TopicName: data[0].TopicName, TopicInfo: data[0].TopicInfo, IssueStartDate: data[0].IssueStartDate, IssueCloseDate: data[0].IssueCloseDate, NewsCategory_Id: 0 }));
})
}
my model class
export class NewsTopic
{
Id: number;
TopicId: string;
TopicName: string;
TopicInfo: string;
IssueStartDate: Date;
IssueCloseDate: Date;
NewsCategory_Id: number;
}
the method in service class itself
getAllTopics(){
var reqHeader = new HttpHeaders({ 'No-Auth': 'True' });
return this.http.get<NewsTopic[]>(this.rootUrl + '/api/NewsTopic/GetAllNewsTopics', { headers: reqHeader });
}
my html for showing the data and the pagination control
<div class="card-body">
<table class="table table-striped" id="newstopics_tbl">
<thead>
<tr style="background:linear-gradient(50deg, #d9fcfc, #dafbde)">
<th>Topic ID</th>
<th>Topic Name</th>
<th>Topic Info</th>
<th>Start Date</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let nt of pageOfItems">
<td><b>{{nt.TopicId}}</b></td>
<td>{{nt.TopicName}}</td>
<td>{{nt.TopicInfo}}</td>
<td>{{nt.IssueStartDate}}</td>
</tr>
</tbody>
</table>
</div>
<div class="card-footer pb-0 pt-3" style="background:linear-gradient(50deg, #d9fcfc, #dafbde); margin-top:15px">
<jw-pagination [items]="newsTopics" (changePage)="onChangePage($event)"></jw-pagination>
</div>
My guess is, the problem lies in the getAllNewsTopics() method, where I am trying to fill and map the array of objects and assign to the variable. Something wrong there. If you see the original example from the link, they used a .fill(0) also. In my case I tried doing .fill(data[0]) however result is the same, ie. only first record, repeated multiple times.
What is the trick I am missing? Can someone just point me out.
Much needed, Thanks,
EDITS --
These are the changes->
getAllNewsTopics() {
var reqHeader = new HttpHeaders({ 'No-Auth': 'True' });
return this.http.get<NewsTopic[]>(this.rootUrl + '/api/NewsTopic/GetAllNewsTopics', { headers: reqHeader })
.subscribe((data: NewsTopic[]) => {
this.newsTopics = data;
});
}
and
<div class="card-body">
<table class="table table-striped" id="newstopics_tbl">
<thead>
<tr style="background:linear-gradient(50deg, #d9fcfc, #dafbde)">
<th>Topic ID</th>
<th>Topic Name</th>
<th>Topic Info</th>
<th>Start Date</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let nt of pageOfItems" style="cursor:pointer" (click)="NewsArticleAdd(nt)">
<td (click)=""><b>{{nt.TopicId}}</b></td>
<td style="color:mediumvioletred;" (click)="">{{nt.TopicName}}</td>
<td (click)="">{{nt.TopicInfo}}</td>
<td (click)="">{{nt.IssueStartDate}}</td>
</tr>
</tbody>
</table>
</div>
<div class="card-footer pb-0 pt-3" style="background:linear-gradient(50deg, #d9fcfc, #dafbde); margin-top:15px">
<jw-pagination [items]="newsTopics" (changePage)="onChangePage($event)"></jw-pagination>
</div>
That does the trick. Works as expected,

Passing multiple variables in Controllers

I am trying to add an update table on a show blade for a Laravel project.
The idea being if someone is paid owed subs, they can be check off on the roll.
I can pass the roll.id into the Controller, however this is a member view so I need to grab the roll.member_id of the roll.id record and pass this into the redirect to show the updated member page
Here is the html table
<table class="table">
<thead class = 'text-primary'>
<th class="text-center">Date</th>
<th></th>
</thead>
<tbody>
#foreach ($member->outstanding as $o)
<tr>
<td class="text-center">{{$o->roll_id}}</td>
<td class="text-center"><i class="material-icons">done</i></td>
</tr>
#endforeach
</tbody>
</table>
This is the RollController#updateRoll
public function updateRoll($id){
$o = Roll::find($id);
if ($o != null)
{
$o->status = "C";
$o->save();
return redirect(action('MembersController#show'))->with ('success', 'Member Present');
}
return redirect(action('MembersController#index'));
}
So I would like to add the Member_id into the
return redirect(action('MembersController#show'))->with ('success', 'Member Present');
So I am taken back to the member show blade.
Have you tried passing the ID to the action, same as in your blade view?
For example:
return redirect(action('MembersController#show', $o->member_id))
->with ('success', 'Member Present');

Spring Boot And Thymeleaf remain on the same page on post request is made

I've created an web app that searches for online car ads and populates the page with a few tables after a post request.It looks like this:
After Search:
Every table element has a save button which should save those values to the database but my problem is that the page gets refreshed after submitting a post request. How can I do this without refreshing the page?
Table:
<form th:action="#{/saveAd}" method="POST">
<table class="table table-sm table-hover">
<thead class="thead-dark">
<tr>
<th>Imagine</th>
<th>Titlu Anunt</th>
<!-- <th style="width: 16.66%">Link</th> -->
<th>Pret</th>
<th>Oras</th>
</tr>
</thead>
<tbody id="myTable">
<th:block th:each="element : ${lista}">
<trth:onclick="'javascript:rowClicked(\'' + ${element.url} + '\');'">
<td><img th:src="#{${element.img}}" class="size" /></td>
<td th:text="${element.title}"></td>
<td th:text="${element.pret}"></td>
<td th:text="${element.oras}"></td>
<td><input class="btn btn-danger" type="submit"value="Save"></td>
</tr>
</th:block>
</tbody>
Controller:
#RequestMapping(path = "/saveAd", method = RequestMethod.POST)
public String saveAd(#ModelAttribute("adValue") AdValue adValue) {
System.out.println(adValue.getImg());
System.out.println(adValue.getLink());
System.out.println(adValue.getOras());
System.out.println(adValue.getPret());
System.out.println(adValue.getTitle());
return "home";
}
And also, how could I bind the list to a model object after pressing the save button?
I guess you may like this project. It is similar with what you need :
https://github.com/adinafometescu/tutorials/tree/master/spring-elasticsearch
You can use .bootstrapTable(). It a very method to update dynamically your table.
<table id="car-table" class="table table-striped">
<thead>
<tr>
<th data-field="id">Id</th>
<th data-field="title">Title</th>
<th data-field="price">Price</th>
<th data-field="city">City</th>
<th data-width="10" data-formatter="saveButtonFormatter"/>
</tr>
</thead>
</table>
The beauty is that it will map the data-field to a java object.
js stuff:
function saveButtonFormatter(value, row, index){
var adId = row.id;
return "<button class=\"btn btn-danger \" data-title=\"Save\"
data-toggle=\"modal\" onclick=\"saveAd(\'"+adId+"\')\"
</button>"
}
The function saveAd(adId) will call the rest endpoint and will update the bootstrap table on success.
I see that in your thymeleaf you don't have inputs. I suggest to not post your entire object if you don't need user input, just the id.
// anotate the controller class with #RestController
#Autowired
AdService adService;
#PostMapping(path = "/ad/{id}")
public ResponseEntity<?> saveAd(#PathVariable("id") String id) {
adService.saveAd(id);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
P.S : don't write code in Romanian :D

spring mvc mapping - send value between controllers

I have got webapp in spring 3 mvc. The case is that I have index page with url, when user click on them should be display another page with details of choosed information. Now the details page is shown but without any information (on index page is creating model with correct variable but not in details controller - in debug mode).
index controller method:
#RequestMapping(value="/{site}", method = RequestMethod.GET)
public String showDetails(#RequestParam(value = "site", required = true) String site, Model model){
Catalog product = catalogEndpoint.getByTitle(site);
model.addAttribute("product", product);
return "details";
}
index html:
<form action="#" th:object="${product}" method="post" th:action="#{/details}">
<table border="0" width="600" th:each="sb, poz : ${product}" >
<tr >
<td rowspan="3" width="20"><span th:text="${poz.count}"></span></td>
<td>
<a th:href="#{/details/(site=${sb.tytul})}" th:value="${site}"><span th:text="${sb.tytul}"></span></a>
</td>
</tr>
<tr >
<td><span th:text="${sb.adres}"></span></td>
</tr>
<tr>
<td>category:<b><span th:text="${sb.category.name}"></span></b></td>
</tr>
</table>
</form>
details controller method:
#RequestMapping(value = "details/{site}", method = RequestMethod.GET)
public String showHomePage(#PathVariable(value = "site") String site, Model model){
model.addAttribute("product");
return "details";
}
details html:
<form th:object="${product}" method="get" th:action="#{/details}">
<table border="1" width="600" >
<tr >
<td ><span th:text="${tytul}"></span></td>
<td>
<span th:text="${opis}"></span>
</td>
<td><span th:text="${adres}"></span></td>
</tr>
</table>
</form>
I don't have any ideas how to map the details site (I tried a lot of solution but nothing). Thanks for help.
With thymeleaf, using th:object, you need to reference the fields of that object with *{}
<form th:object="${product}" method="get" th:action="#{/details}">
<table border="1" width="600" >
<tr >
<td ><span th:text="*{tytul}"></span></td>
<td>
<span th:text="*{opis}"></span>
</td>
<td><span th:text="*{adres}"></span></td>
</tr>
</table>
</form>
assuming tytul, opis, and adres are fields of product. Unless it's a type, don't forget
Catalog product = catalogEndpoint.getByTitle(site);
model.addAttribute("product", product);
in your details controller method, otherwise you won't have a Catalog model attribute.
inside your details controller where are you setting product object in your model ?
model.addAttribute("product");
is just settingstring object "product", fetch the product object and set it in details controller like you have done in showDetails method
Change
model.addAttribute("product");
To
Catalog product = catalogEndpoint.getByTitle(site);
model.addAttribute("product", product);
in "showPage" method.

Resources