Make an array from object to iterate over it by *ngFor - javascript

I got response from my api it simple one record from my database.
getFilledForm() {
const reservation = this.hotels[0].reservation;
this.accidentFormService.getAccidentForm(reservation).subscribe(
res => {
this.form = res;
console.log('this.form: '+JSON.stringify(this.form));
this.test = Object.keys(this.form).map(key => ({ type: key, value: this.form[key] }));
console.log('this.test: ' +this.test);
},
error => {
console.log(error);
}
)
}
this.form is a object and output looks like:
this.form: {"id":1,reservation":1234,"hotel_name":"BB Hotels"}
I tried to make an array but my array of objects looks like ( this.test )
this.test: [object Object],[object Object],[object Object]
after stringify
this.test: [{"type":"id","value":1},{"type":"reservation","value":null},{"type":"hotel_name","value":"BB Hotels"}]
I want output like: "id":1 no "type":"id","value":1
How sould it be ? I want to make a table from output using *ngFor
-Edit
Added HTML
<table *ngIf="checkForm" class="table table-sm align-items-center table-hover table-flush responsive">
<thead class="thead-light">
<tr>
<th scope="col" class="lPart">ID</th>
<th scope="col" class="lPart">Hotel Name</th>
</tr>
</thead>
<tbody>
<tr
*ngFor="let form of form | paginate: { itemsPerPage: 10, currentPage: p }; let i = index">
<td id="lPart">{{ form.id }}</td>
<td id="lPart">{{ form.hotel_name }}</td>
</tr>
</tbody>
</table>

Related

DataTables unable to display the field of related object in LWC

I have a data table which displays 'Name' field and 'Address' field (Address related to another object). The 'Name' field is displayed properly but if I iterate over the list in html for pcon.Address__r.Name it gives error. If only pcon.Address__r is given , it shows [object object] in table. Can anybody resolve this issue?
HTML:
<table class="slds-table slds-table--bordered">
<thead>
<tr>
<th style="background-color: #151963;color: white;">Name</th>
<th style="background-color: #151963;color: white;">Address</th>
</tr>
</thead>
<tbody>
<template for:each={pconfig} for:item="pcon" for:index="i">
<tr class={pcon.row} data-id={pcon.Id} data-index={i} key={pcon.Id} onclick{getquotes} >
<td>{pcon.Name}</td>
<td>{pcon.Address__r.Name}</td>
</tr>
</template>
</tbody>
</table>
</lightning-layout-item>
JS:
#wire(Vendor_getProduct,{ basketId: 'fef0E0000dwedjh' })
getProducts({error,data})
{
if(data)
{
//console.log( 'Fetched Data ' + JSON.stringify( data ) );
this.pconfig = JSON.parse( JSON.stringify( data) );
console.log('products are:',data);
}
else if(error){
this.error=data;
console.log('error is undefined');
}
}
class:
public class c {
#AuraEnabled(cacheable=true)
public static List<Product_Configuration__c> getProduct (Id basketId) {
return [select id,
name,
Address__r.name,
from Product_Configuration__c
where Product_Basket__c =:basketId];
}

json.parse not working with template engine handlebars

I have a search box which I wish to use to populate my table so i want to access the data sent to the view template in the script tag
ERROR IN SCRIPT
1 Uncaught SyntaxError: "[object Object]" is not valid JSON
at JSON.parse (<anonymous>)
at 1:164:25
<div class="FieldElement2" style="margin-top: 3%;">
<div class="input-field ">
<input id="search_masterTable" type="text" class="validate">
</div>
<table class="highlight centered responsive-table" style="width: min-content;" >
<thead>
<tr>
<th></th>
<th>Ledg.No.</th>
<th>File No.</th>
<th>Name</th>
<th>Phone</th>
</tr>
</thead>
<tbody id="searchResultsBody">
{{#each accounts_array}}
<tr>
<td><button class="viewButton">View Chart</button></td>
<td class="Ledg_No" scope="row">{{ledger_num}}</td>
<td class="File_Num" scope="row">{{file_num}}</td>
<td class="Name">{{client_name}}</td>
<td class="gPhoneNumber3">{{phone_number6}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<script>
document.getElementById('search_masterTable').addEventListener('input',()=>{
const search_value = document.getElementById('search_masterTable').value.toUpperCase().split(' ')
// NOT WOKING
const data = JSON.parse("{{accounts_array}}")
const result_array = data.filter(function(r){
return search_value.every(function(word){
console.log(word)
return column_name_array.some(function(colIndex){
console.log(r[colIndex])
if(r[colIndex] == null){
return false
}else{
return r[colIndex].toString().toUpperCase().indexOf(word) !== -1
}
});
});
})
function to_populate_masterTable(){
}
</script>
insted of sending the search value back to the server i want to perfom the search opearation in the frontend and send display the result for every search input
BACK END
router.get('/masterTable/:id', ensureAuth, async (req, res) => {
const title = 'Master Table'
var account = parseInt(req.params.id)
db.query(`SELECT * FROM mt_`+account+``, async (err,accounts_array) => {
res.render('masterTable', {
accounts_array,
title
})
})
})
THIS IS WHAT THE account_array LOOKS LIKE
[
RowDataPacket { // <= this is the error
id: 1,
ledger_num: 'VM364',
file_num: 'VM364',
client_name: 'MUTHU KUMAR',
phone_number1: '9791716460',
status: 'UNSETTLED'
},
RowDataPacket {
id: 1,
.,
.,
.,
},
RowDataPacket {},
RowDataPacket {}
]
error that i got
Uncaught SyntaxError: Unexpected token '{' (at 1:169:21)
This might work by first stringifying the variable and using the tag syntax to pass the stringified JSON to the template:
const data = JSON.parse(<%= JSON.stringify(accounts_array) %>);

Auto play a sound when receive a new row data in Vue.js

I am developing a Vue app to fetch orders from Woocommerce REST API. So i am having a HTML Table to fill the JSON Data. So when each order receive to Woocommerce, I will get it in my dashboard using "setInterval" for 60 seconds through refreshing data. Also the flags are set to notify new order in the HTML table using colors.
Apart from this I need to play a sound in the Vue app whenever the Woocommerce receives an order. How can I archive this as a stable function?
My JS code
var app = new Vue({
el: '#app',
data: {
orders: []
},
mounted: function() {
// Call the API the first time
this.refreshData()
// Then call the API every minute
this.setIntervalId = setInterval(this.refreshData, 60000)
},
beforeDestroy: function() {
// Stop refreshing data after the component is destroyed!
clearInterval(this.setIntervalId)
},
methods: {
refreshData () {
axios.get('https://mysite/wp-json/wc/v3/orders?per_page=20&consumer_key=key1&consumer_secret=key2')
.then(response => {
const previouslyFlaggedIds = this.orders.filter(x => x.is_printed).map(x => x.id);
this.orders = response.data.map(x => ({...x, is_printed: previouslyFlaggedIds.find(y => y === x.id) != null}));
console.log(response);
})
.catch(error => {
console.log(eror);
});
},
printBill(order) {
//change flag
order.is_printed = true;
}
}
})
HTML
<div class ="container mt-5" id="app">
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">Order id</th>
<th scope="col">Name</th>
<th scope="col">Order Date</th>
<th scope="col">Phone</th>
<th scope="col">Address</th>
<th scope="col">Items</th>
<th scope="col">Total</th>
<th scope="col">Print</th>
</tr>
</thead>
<tbody>
<tr
v-for="(order, index) in orders"
:key="order.id"
:class="{highlight: !order.is_printed}"
>
<td>{{ order.id }}</td>
<td>{{ order.billing.first_name + " " +order.billing.last_name }}</td>
<td>{{ order.date_created }}</td>
<td>{{ order.billing.phone}}</td>
<td>{{ order.billing.address_1 + ", " + order.billing.address_2 + ", " + order.billing.city + order.billing.postcode }}</td>
<td>{{ order.line_items[0].name}} </td>
<td>{{ order.total}}</td>
<td><button class="btn btn-primary" #click="printBill(order)">Print</button>
</tr>
</tbody>
</table>
You can use audio tag for this.
<audio
ref="audio"
src="/media/cc0-audio/t-rex-roar.mp3">
</audio>
Then after you receive the new orders just play the audio
this.$refs.audio.play()
JSFiddle example

why my code make an infinite loop when I call the api?

I'm trying to call my api to get the name of a tp but in the view I only see a [object promise] and in the browser console it looks like it's doing an infinite loop
html:
<table [dtOptions]="dtOptions" class="row-border hover" datatable>
<thead>
<tr>
<th>Date</th>
<th>Intitulé</th>
<th>Résultat</th>
<th>Coefficiant</th>
</tr>
</thead>
<tbody *ngIf="grades?.length != 0">
<tr *ngFor="let grade of grades">
<td>{{ formatDate(grade.Date) | date : 'MM/dd/yyyy hh:mm'}}</td>
<td>{{ getTpName(grade.tp_id) }}</td>
<td><b>{{ grade.Grade | number:'2.1-2' }}/20</b></td>
<td>{{ grade.coeff | number:'1.1'}}</td>
</tr>
</tbody>
<tbody *ngIf="grades?.length == 0">
<tr>
<td class="no-data-available" colspan="4">Aucune note enregistées</td>
</tr>
<tbody>
</table>
TS:
async getTpName(tp_id: any) {
return await this.apiService.getTpName(tp_id);
}
apiservice>getTpName
getTpName(tp_id) {
let url = `${this._tpUrl}/readName/${tp_id}`;
return new Promise((resolve, reject) => {
this.http.get(url, {headers: this.headers}).subscribe(
res => resolve(res),
error => reject(error)
)
});
}
Do you know why it happen and how to correct this ?
EDIT:
It will be good to move the api call from html to component controller.
ngOnInit() {
grades.forEach(grade => {
this.getTpName(grade.tp_id)
.pipe(take(1))
.subscribe(tpName => {
grade.tpName = tpName;
});
});
}
< td > {{ grade.tpName | json }}</td >

dataTables new row won't add to table

When I add new data it won't add to table
Code
HTML
<thead>
<tr>
<th class="text-center">ID</th>
<th class="text-center">Number</th>
<th class="text-center">Body</th>
<th class="text-center">Heading</th>
<th class="text-center">Book</th>
<th class="text-center">Chapter</th>
<th class="text-center">Actions</th>
</tr>
</thead>
<tbody>
<template v-for="verse in getVerses">
<tr v-bind:key="verse.id">
<td width="30" class="text-center">{{ verse.id }}</td>
<td class="text-center">{{ verse.number }}</td>
<td>{{ verse.body }}</td>
<td>{{ verse.heading }}</td>
<td class="text-center">{{ verse.book.name }}</td>
<td class="text-center">{{ verse.chapter.name }}</td>
<td class="text-center">
<button class="btn btn-sm btn-danger" type="button" #click="deleteVerse(verse.id)">Delete</button>
</td>
</tr>
</template>
</tbody>
</table>
Script
export default {
name: "adminVerses",
data() {
return {
isLoading: true,
type: '',
books: [],
errors: [],
pageTitle: 'Manage Verses',
getChapters: [],
getVerses: [],
isLoadingChapters: true,
isLoadingVerses: true,
verse: {
number: 1,
heading: '',
body: '',
book_id: '',
chapter_id: '',
}
}
},
methods: {
submit: function(e) {
axios.post('/api/saveVerse', this.verse)
.then(res => {
this.isLoading = false;
$('#exampleModal').modal('toggle');
this.getVerses.push( res.data.verse );
this.verse = {
number: parseInt(this.verse.number) + 1,
heading: '',
body: '',
book_id: this.verse.book_id,
chapter_id: this.verse.chapter_id,
};
})
.catch(error => {
// handle authentication and validation errors here
this.errors = error.response.data.errors
this.isLoading = false
})
},
}
}
Any idea?
Update
by adding
if ($.fn.dataTable.isDataTable('#verses')) {
$('#verses').DataTable().clear().destroy(); //This will destroy datatable
};
this.getVerses.push( res.data.verse );
now i can get my newly added data into my table but i also will lose ability of paging and search, etc.
ideas?
You are using this to refer to an object, so you are limited to Axios scope. Instead you can use a variable to store a reference to main object, in your case adminVerses and then use $data to set or fetch the data attributes.
Example :
let vm = this;
axios({
...
}).then((res) => {
vm.$data.getVerses.push( res.data.verse );
});
open your vue devtools and check if getVerses gets the right data
The push on the array isn't responsive, so the vue doesn't know it needs to update the view. The array setter is responsive, so:
this.getVerses = this.getVerses.concat(res.data.verse)
will do the trick.

Categories