How to update polymer component on model change - websocket

I have a simple Polymer component that get's data from an external url, in this example, a json placeholder, in the future this will be consuming from an API.
What I want to do is update the displayed data upon model update, if the exposed data from the API response changes, I need to reflect it to the HTML almost immediately (maybe using web sockets, signal R in my case).
<dom-module id="ajax-test">
<template>
<!-- GETS THE DATA FROM A SOURCE -->
<iron-ajax auto
url="https://jsonplaceholder.typicode.com/users"
handle-as="json"
last-response="{{ajaxResponse}}">
</iron-ajax>
<table class="tg">
<caption><span>USERS</span></caption>
<template is="dom-repeat" items="[[ajaxResponse]]">
<tr>
<th class="tg-yw4l">[[item.name]]</th>
<th class="tg-yw4l">[[item.username]]</th>
<th class="tg-yw4l">[[item.email]]</th>
<th class="tg-yw4l">[[item.address.street]] [[item.address.suite]] </th>
</tr>
</template>
</table>
<!-- SHOW THE FETCHED DATA -->
<br />
<pre>[[json(ajaxResponse)]]</pre>
</template>
<script>
class AjaxTest extends Polymer.Element {
static get is() { return 'ajax-test'; }
static get properties() {
return {
prop1: {
type: String,
value: "bar"
}
}
}
json(obj) {
return JSON.stringify(obj, null, 2);
}
}
customElements.define(AjaxTest.is, AjaxTest);
</script>

Related

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

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

Im confuse with axios in seperate service file

Im now is learn vue.js, and i want to consume API from my backend (using spring).
This is my service.js
import axios from "axios";
class LowonganKerjaService {
retrieveAllLoker() {
return axios.get('http://localhost:8081/api/listLoker');
}
deleteLoker(idLowongan){
return axios.delete('http://localhost:8081/api/${idLowongan}');
}
}
export default new LowonganKerjaService();
this is my component
<template>
<div class="container">
<h3>All Courses</h3>
<div v-if="message" class="alert alert-success">
{{message}}
</div>
<div class="container">
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr v-for="loker in loker" v-bind:key="loker.idLowongan">
<td>{{loker.idLowongan}}</td>
<td>{{loker.deskripsi}}</td>
<td>
<button class="btn btn-warning" v-on:click="deleteLokerClicked(loker.idLowongan)">
Hapus
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
import LowonganKerjaService from '../../service/LowonganKerjaService';
export default {
name : "LokerList",
data() {
return{
loker : []
};
},
methods:{
refreshLoker(){
LowonganKerjaService.retrieveAllLoker()
.then(response => {
this.loker = response.data;
});
},
deleteLokerClicked(idLowongan){
LowonganKerjaService.deleteLoker(idLowongan).then(()=> {
this.message = 'Loker dengan ${idLowongan} berhasil dihapus';
this.refreshLoker();
});
}
},
created(){
this.refreshLoker();
}
};
</script>
<style>
</style>
and i got this error
Failed to compile.
./src/service/LowonganKerjaService.js Module Error (from
./node_modules/eslint-loader/index.js):
D:\Kuliah\TERM
6\Propensi\Implementasi\frontend-sixacti\src\service\LowonganKerjaService.js
10:17 error 'idLowongan' is defined but never used no-unused-vars
✖ 1 problem (1 error, 0 warnings)
Oh and i've got error too when i use ${} in those service.
Why that error state that my 'idLowongan' is never used? is it because i wrong my syntaks or what?
Please somebody help me to give the reason
Thanks
**sorry for my bad language
From the looks of your code it looks like you're using a single quote (') and not a backtick (`) when you're attempting to use JS template literal. You can see an example of that in the MSDN documentation. Since it is a string in your example and not a template literal the variable in the function's argument is never used.
Try changing the code in your service's delete method to be this:
return axios.delete(`http://localhost:8081/api/${idLowongan}`)

Vue Component not works even i register it follow the official manual

just a very new to Vue 2.0, i actually use if for Laravel 5.4, now you can see from below link that i created one component which name is "canvas-chart", what actually i want show is a filterable table, and then to get more Json data from next steps, but now it always show me "Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option." , can not understand that i follow the official documentation to use it why it's not work?
new Vue({
el:'#filterTest',
data:{
keywords:[{"id":"9","name":"missy","phone":"21324234532"},
{"id":"3","name":"Mahama","phone":"345604542"},
{"id":"2","name":"Bernard","phone":"241242542"}]
},
computed: {
filterM: function () {
var self = this
return self.filter(function (word) {
return user.name.indexOf(self.searchQuery) !== -1
})
}
}
});
Vue.component('canvas-chat',{
template:'#canvasChart',
props:['keywordsData']
})
<script type="text/x-template" id="canvasChart">
<table>
<thead>
<tr>
<th v-for="key.id in keywordsData">
<span class="arrow" ></span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="key.name in keywordsData">
<td v-for="key.phone in keywordsData"> {{key.name}}</td>
</tr>
</tbody>
</table>
</script>
<div id="filterTest">
<canvas-chat keywordsData="keywords" ></canvas-chat>
</div>
You have a few issues:
You must register the canvas-chat component first before you use it in the main component (put Vue.component('canvas-chat', ... before new Vue(...)).
Your v-for loops are wrong. They should be like v-for="key in keywordsData", not v-for="key.id in keywordsData".
The v-fors on the tr and td elements don't make sense; you will have to process the keywordsData first (perhaps in a computed property) to get it into the correct format you want, then loop over that.
You must bind the keywordsData prop in the template like this: :keywords-data="keywords".

Grails Ajax table - how to implement?

I've input:
<g:form role="search" class="navbar-form-custom" method="post"
controller="simple" action="addEntry">
<div class="form-group">
<input type="text" placeholder="Put your data HERE"
class="form-control" name="InputData" id="top-search">
</div>
</g:form>
And table:
<table class="table table-striped table-bordered table-hover " id="editable">
<thead>
<tr>
<th>Name</th>
<th>Created</th>
</tr>
</thead>
<tbody>
<g:render template="/shared/entry" var="entry"
collection="${entries}" />
</tbody>
</table>
Controller:
#Secured(['ROLE_USER', 'ROLE_ADMIN'])
class SimpleController {
def springSecurityService
def user
def index() {
user = springSecurityService.principal.username
def entries = Entry.findAllByCreatedBy(user)
[entries: entries]
}
def addEntry(){
def entries = Entry.findAllByCreatedBy(user)
render(entries: entries)
}
}
I just want to dynamically update the table with data from input string.
What is the best way?
Will be grateful for examples/solutions
You can update the table using AJAX with Grail's formRemote tag.
Input form
<g:formRemote
name="entryForm"
url="[controller: 'entry', action: 'add']"
update="entry">
<input type="text" name="name" placeholder="Your name" />
<input type="submit" value="Add" />
</g:formRemote>
HTML table
<table>
<thead>
<tr>
<th>Name</th>
<th>Created</th>
</tr>
</thead>
<tbody id="entry">
<g:render
template="/entry/entry"
var="entry"
collection="${entries}" />
</tbody>
</table>
Entry template
<tr>
<td>${entry.name}</td>
<td>${entry.dateCreated}</td>
</tr>
Controller
import org.springframework.transaction.annotation.Transactional
class EntryController {
def index() {
[entries: Entry.list(readOnly: true)]
}
#Transactional
def add(String name) {
def entry = new Entry(name: name).save()
render(template: '/entry/entry', collection: Entry.list(), var: 'entry')
}
}
How it works
When the add button is pressed the add controller method is called. The controller method creates the domain instance and renders the _entry.gsp template. But instead of refreshing the browser page, the template is rendered to an AJAX response. On the client side, the rendered template is inserted into the DOM inside of the tbody element with id entry, as defined in the formRemote tag by the update attribute.
Note that with this approach all of the entries are re-rendered, not just the new one. Rendering only the new one is a bit trickier.
Resources
Complete source code for my answer
Grails AJAX
Just to give you direction ( you are not showing any of your controller and js code.):
Create an action your controller ( the responsible controller) that will render the template /shared/entry by passing entries collection.
On submit of the form make ajax call to the action defined above, then replace the tbody html by the returned view fragment(template).

jquery error this.source is not a function

Hi I am trying to catch an array of string from a class called AjaxFacade using DWR and I am using jquery to autocomplete a text box snippetof my jsp code is as follows
<%
String path = request.getContextPath();
%>
<script type='text/javascript' src='<%=path%>/dwr/interface/ajaxFacade.js'></script>
<script type='text/javascript' src='<%=path%>/dwr/engine.js'></script>
<script type='text/javascript' src='<%=path%>/dwr/util.js'></script>
<script>
$(function()
{
var countries ;
countries = ajaxFacade.getCountries();
$("#tags").autocomplete({source : countries});
});
</script>
<tr>
<td align="left" valign="top" bgcolor="e3ddc7">
<div align="right"><strong> <font color="red">*</font>Old E-mail Address:</strong></div>
</td>
<td align="left" valign="top" bgcolor="#FFFFFF">
<html:text name="amsUserRequestForm" property="oldEmail" size="20" styleClass="ui-widget" styleId="tags">
</html:text></td>
</tr>
Function in AjaxFacade class is as follows
public String[] getUsers() {
String[] countries = {
"India",
"Iran",
"Iraq",
"Indoneshia",
"Ireland"
};
return countries;
}
No matter what I do it keeps me giving error this.source is not a function. Any help is greatly appreciated
make sure that the countries are filled with data make sync json call if needed.

Resources