Angular translate and filtering over table - javascript

I have a simple table with search -
<table>
<thead>
<tr>
<th> Name </th>
<th> Lastname </th>
<th> Job Title </th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="data in ctrl.data | filter : searchQuery">
<td>{{data.name}}</td>
<td>{{data.lastname}}</td>
<td>{{data.jobtitle | translate}}</td>
</tr>
</tbody>
</table>
<input type="text" data-ng-model="searchQuery"/>
Since job title is translated - search works only with original value - so yes with "Developer" but no with any translation of this.
Is there is any possibility to make it work with translations too?

You can create a filter to handle the translation
Filter
app.filter('translateFilter', function($translate) {
return function(input, param) {
if (!param) {
return input;
}
var searchVal = param.toLowerCase();
var result = [];
angular.forEach(input, function(item) {
var translated = $translate.instant(item.jobtitle);
if (translated.toLowerCase().indexOf(searchVal) > -1) {
result.push(item);
}
});
return result;
};
});
And use it like this:
HTML
<tr data-ng-repeat="data in ctrl.data | translateFilter:searchQuery">

Related

*ngFor is showing an error of undefined when trying to loop over an object in angular

I get the below error when trying to loop over an object using *ngFor directive in angular:
Type 'Inventory' is not assignable to type 'NgIterable | null | undefined'.
18 <tr *ngFor="let item of searchedInventory;">
but the searchedInventory has data in it when I console logged it -
{id: 1, foodName: 'idli', foodDescription: 'made from rice', date: '2023-02-07 16:14:37.793398+05:30', price: 30, …}
The component.ts file as below,
searchedInventory!: Inventory;
constructor(private inventoryDataService : InventoryDataService, private route : ActivatedRoute){
}
ngOnInit(): void {
this.foodname = this.route.snapshot.params['foodname'];
this.searchedItems();
// console.log(this.foodname);
}
foodname!: String;
searchedItems(){
this.inventoryDataService.retrieveFoodByName(this.foodname).subscribe(
response => {
// console.log(response);
this.searchedInventory = response;
console.log(this.searchedInventory);
}
)
}
my HTML page is,
<h1>List of foods:</h1>
<div class="container">
<table class="table">
<thead>
<tr>
<th>id</th>
<th>Food Name</th>
<th>Food Description</th>
<th>Price</th>
<th>Date</th>
<th>Hotel Name</th>
<th>Hotel Address</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of searchedInventory;">
<td>{{item.id}}</td>
<td>{{item.foodName}}</td>
<td>{{item.foodDescription}}</td>
<td>{{item.price}}</td>
<td>{{item.date}}</td>
<td>{{item.hotelName}}</td>
<td>{{item.hotelAddress}}</td>
<td><button class="btn btn-success">Select</button></td>
</tr>
</tbody>
</table>
</div>
Editted,
I tried to convert the object into an array,
this.values = Object.values(this.searchedInventory);
console.log(this.values);
}
and the html is,
<tr *ngFor="let item of values">
<td id="values">{{item}}</td>
<td><button class="btn btn-success">Select</button></td>
</tr>
now the the array is not printing in row but as a column.
data is coming as an object don't need to iterate it
<tr>
<td>{{searchedInventory.id}}</td>
<td>{{searchedInventory.foodName}}</td>
<td>{{searchedInventory.foodDescription}}</td>
<td>{{searchedInventory.price}}</td>
<td>{{searchedInventory.date}}</td>
<td>{{searchedInventory.hotelName}}</td>
<td>{{searchedInventory.hotelAddress}}</td>
<td><button class="btn btn-success">Select</button></td>
</tr>
I solved it on my own!!!
Actually the problem was in the backend Springboot,
#GetMapping(path="/admin/inventory/search/{food_name}")
public Inventory getFoodByName(#PathVariable String food_name) {
Inventory foodname = inventoryService.findByFoodName(food_name);
if(foodname == null) {
throw new TodoNotFoundException("foodname - " + food_name);
}
return foodname;
}
to,
#GetMapping(path="/admin/inventory/search/{food_name}")
public List<Inventory> getFoodByName(#PathVariable String food_name) {
Inventory foodname = inventoryService.findByFoodName(food_name);
if(foodname == null) {
throw new TodoNotFoundException("foodname - " + food_name);
}
List items = new ArrayList<>();
items.add(foodname);
return items;
}
so now my backend return a ArrayList, with which I can iterate using *ngFor and it is executing perfectly!!!
sometimes I need to look a deep into everything to figure out the solution. I was thinking the problem was with the *ngFor!

How to prevent column total Count from display on component.html?

I have field total count I need to prevent total Count from display on component.html
I already do it but not working if you can tell me how to do that ?
I display data dynamically on header column and body data with angular 7
I try using filter function below but not working
this._displayreport.GetReportDetailsPaging(this.searchData).subscribe((data: any[]) => {
this.reportdetailslist = data;
this.headerCols = Object.keys(data[0]);
this.contentBody=data.filter(item =>item != data[0].totalCount);
});
}
}
<thead>
<tr>
<th >
<ng-container *ngIf="coln != 'totalCount'">
{{coln}}
</ng-container>
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let rep of contentBody">
<td *ngFor="let coln of headerCols">
<span>
{{rep[coln]}}
</span>
</td>
</tr>
<tbody>
data object represent following data as any[]
companyName: "Innovasic, Inc."
done: "0"
notImpacted: "0"
notificationDate: "2009-11-12"
offilneURL: "https://source.z2data.com/2019/1/13/8/55/47/351/662203977/21527_SPCN.PDF"
onlineURL: "N/A"
pending: "3"
reportDate: "2020-05-07"
revisionID: "272299243"
teamName: "MFG"
totalCount: 79
it solved by change my code above to
this.headerCols = Object.keys(data[0]).filter(x => x !== 'totalCount');

How order list of dates get from object

I have a list sorted by date and I want to reorder it by clicking button. This date is taken from an object, I try this code, but it sorts like a simple number:
// function to order and change button by click
$scope.sortType = "CreationDate";
$scope.sortReverse = false;
$scope.buttonStyle = "icon ion-ios-time-outline";
$scope.buttonPress = false;
$scope.ordina = function() {
if ($scope.sortType == "CreationDate") {
$scope.sortReverse = !$scope.sortReverse;
console.log("riordinate");
}
$scope.buttonPress = !$scope.buttonPress;
if ($scope.buttonPress == true) {
$scope.buttonStyle = "icon ion-ios-time";
} else {
$scope.buttonStyle = "icon ion-ios-time-outline";
}
}
in html:
<ion-item ng-repeat="object in allODA | filter: searchQuery | orderBy : sortType : sortReverse " href="#/app/ODA_Detail/{{object.caseTaskId}}">
any solutions???idea???
I don't know if I understood correctly, but here is an example to sort a table with dates, click on the title of the column to sort it.
https://jsfiddle.net/lisapfisterer/8pvqau4z/
This does not use ionic, you might need to adapt it.
<table class="table table-striped">
<thead>
<td data-ng-click="sortType = name; sortReverse = !sortReverse;">
Date
</td>
<td data-ng-click="sortType = name; sortReverse = !sortReverse;">
Name
</td>
</thead>
<tbody>
<tr ng-repeat="item in allItems | orderBy:sortType:sortReverse">
<td>{{item.date | date:"yyyy-MM-dd"}}</td>
<td>{{item.name}}</td>
</tr>
</tbody>
</table>

Angular - link two API sources in table based on ID FK

I'm really new to Angular and i'm trying to create a list of user transactions that presents the time of the action and the user's name. In my audit API I have an action ID and the User FK which associates with my User API and i'm displaying it as follows:
HTML
<table>
<thead>
<tr>
<th>
Date/Time
</th>
<th>
User
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="audit in audit.data>
<td>{{audit.audit_date_time}}</td>
<td>**{{audit.audit_user_fk}}**</td> **<--I need the name not the ID here**
</tr>
</tbody>
</table>
My Apis are as follows:
AUDIT
[
{
"audit_id": "1",
"audit_date_time": "2016-01-28 12:46:20",
"audit_user_fk": "97"
}
]
USER
[
{
"user_id": "97",
"user_full_name": "Mr.User",
}
]
Controller, which is working fine GETting the data from each API:
app.controller('auditControl', ['$scope','auditService', 'userService', function ($scope, auditService, userService) {
var auditLogs = auditService.query(function () {
$scope.audit.data = auditLogs;
});
var user = userService.query(function () {
$scope.auditUser = user;
});
}]);
So my main issue i'm having is getting the user name in the table instead of the foreign key value. I've stripped out a lot of this just so we can focus on the main problem. Getting the user name from the user API, based on the FK in the Audit API and repeated based on the items in the Audit API.
Any help greatly appreciated and apologies for the noob question!
Create a custom filter.
app.filter("lookupUser", function() {
function lookup (idNum, userList) {
var userName = "UNKNOWN";
angular.forEach(userList, function(user) {
if ( user.user_id == idNum ) {
userName = user.user_full_name;
};
});
return userName;
};
return lookup;
});
Then in your template:
<tr ng-repeat="audit in audit.data>
<td>{{audit.audit_date_time}}</td>
<td>{{audit.audit_user_fk | lookupUser : auditUser }}</td>
</tr>
You could do something like this:
Controller:
app.controller('auditControl', ['$scope','auditService', 'userService', function ($scope, auditService, userService) {
var auditLogs = auditService.query(function () {
$scope.audit.data = auditLogs;
});
var user = userService.query(function () {
$scope.auditUser = user;
});
$scope.getUserName = function (id) {
var result = $scope.users.filter(function( user ) {
return user.user_id == id;
});
if (angular.isDefined(result) && result.length > 0) {
return result[0].user_full_name;
} else {
return "--";
}
}
}]);
HTML
<table>
<thead>
<tr>
<th>
Date/Time
</th>
<th>
User
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="audit in audit.data">
<td>{{audit.audit_date_time}}</td>
<td>**{{getUserName(audit.audit_user_fk)}}**</td> **<--I need the name not the ID here**
</tr>
</tbody>
</table>
I don't know where the users array are, so I called $scope.users.

Meteor returning NaN in the browser

I'm building a simple ordering app in Meteor and have come a cropper trying to get the order total even though I can get it to log in the console as a bona fide number - it is being rendered as NaN. Any help would be greatly appreciated.
Note the totals of individual products are appearing fine.
I have the following files:
meteorder/client/templates/orders/order_build.js:
Template.order.helpers({
'orderitems': function() {
var orderCart = [];
var orderItems = OrderItems.find({});
var total = 0;
orderItems.forEach(function(orderItem) {
var item = _.extend(orderItem, {});
var product = Products.findOne({
_id: orderItem.product
});
orderItem.productname = product.description;
orderItem.price = (Number(product.price) * orderItem.qty);
total += orderItem.price;
orderCart.push(orderItem);
});
orderCart.subtotal = total;
orderCart.tax = orderCart.subtotal * .23;
orderCart.total = orderCart.subtotal + orderCart.tax;
return orderCart;
}
})
meteorder/client/templates/orders/order_build.html:
<template name="order">
<div class="page-header">
<h1>
<small>My Order</small>
</h1>
</div>
<table class="span4 table table-striped table-bordered table-hover">
<thead>
<th>Qty</th>
<th>Product</th>
<th>Price</th>
<th></th>
</thead>
<tbody>
{{#each orderitems}}
<tr>
<td>{{qty}}</td>
<td>{{productname}}</td>
<td>{{currency price}}</td>
<td><span class="label-important label removeci">X</span></td>
</tr>
{{else}}
<tr>
<td colspan="3">No Products in Order</td>
</tr>
{{/each}}
<tr>
<td class="totalcol" colspan="2">SubTotal:</td>
<td colspan="2">{{currency orderCart.subtotal}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Tax 6%:</td>
<td colspan="2">{{currency orderCart.tax}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Total:</td>
<td colspan="2">{{currency orderCart.total}}</td>
</tr>
</tbody>
</table>
</template>
meteorder/client/lib/main.js:
Template.registerHelper('currency', function(num){
return '€' + Number(num).toFixed(2);
});
meteorder/server/server.js:
Meteor.methods({
addToOrder:function(qty,product,session){
check(qty, Number);
check(product, String);
check(session, String);
if(qty > 0){
OrderItems.insert({qty:qty,product:product,sessid:session});
console.log('reaching this fn', typeof qty, typeof product, typeof session);
} else{
console.log('Quantity is Zero');
}
},
removeOrderItem:function(id){
check(id, String);
OrderItems.remove({_id:id});
console.log('successfully deleted');
}
});
Here is a link to the GitHub repo
And the latest version of the deployed App
Thanks in advance!
Edit:
Just adding this in for Matthias:
Template.productItem.events({
'click .addOrder':function(evt,tmpl){
var qty1 = tmpl.find('.prodqty').value;
var qty = parseInt(qty1);
var product = this._id;
var sessid = Meteor.default_connection._lastSessionId; //stops others adding to your cart etc
Meteor.call('addToOrder',qty, product, sessid);
console.log('this is the quantity:', typeof qty, product, sessid);//stops others ad
}
});
to see if it gives a better picture of why the cart is not populating. Thanks
You're trying to use orderCart as both an array of objects and an object. You push a bunch of orderItem objects on to the array but at the end you attempt to set orderCart.subtotal etc...
Change your helper to have a separate summary object:
var summary = {};
summary.subtotal = total;
summary.tax = summary.subtotal * .23;
summary.total = summary.subtotal + summary.tax;
return {items: orderCart, summary: summary}
Then in your html do:
{{#each orderitems.items}}
...
{{/each}}
Finally in your summary line use {{currency orderitems.summary.tax}} etc...
Your values are rendered as NaN because orderCart is undefined.
You could define a separate helper to fix your code:
Template.order.helpers({
orderItems: function () {
return OrderItems.find().map((orderItem) => {
let product = Products.findOne({
_id: orderItem.product
});
if (product) {
orderItem.productname = product.description;
orderItem.price = calcPrice(product, orderItem);
return orderItem;
}
});
},
orderCart: function () {
let orderCart = {subtotal: 0};
OrderItems.find().forEach((orderItem) => {
let product = Products.findOne({
_id: orderItem.product
});
if (product) orderCart.subtotal += calcPrice(product, orderItem);
});
orderCart.tax = orderCart.subtotal * .23;
orderCart.total = orderCart.subtotal + orderCart.tax;
return orderCart;
}
});
function calcPrice(product, orderItem) {
return (Number(product.price) * orderItem.qty);
}
<template name="order">
<div class="page-header">
<h1>
<small>My Order</small>
</h1>
</div>
<table class="span4 table table-striped table-bordered table-hover">
<thead>
<th>Qty</th>
<th>Product</th>
<th>Price</th>
<th></th>
</thead>
<tbody>
{{#each orderItems}}
<tr>
<td>{{qty}}</td>
<td>{{productname}}</td>
<td>{{currency price}}</td>
<td><span class="label-important label removeci">X</span></td>
</tr>
{{else}}
<tr>
<td colspan="3">No Products in Order</td>
</tr>
{{/each}}
{{#with orderCart}}
<tr>
<td class="totalcol" colspan="2">SubTotal:</td>
<td colspan="2">{{currency orderCart.subtotal}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Tax 6%:</td>
<td colspan="2">{{currency orderCart.tax}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Total:</td>
<td colspan="2">{{currency orderCart.total}}</td>
</tr>
{{/with}}
</tbody>
</table>
</template>
Please note: I noticed a lot of missing semicolons. I strongly recommend to fix that, as this may cause several issues on deployment due to Meteor's minifying process.

Categories