So I'm using Angularjs with TypeScript to make a simple to-do list as a webpage just for fun/practice. This is my controller which queries the database and stores the objects:
module app.ToDo {
class ToDoCtrl {
toDoItems: app.domain.ToDoItems[];
static $inject = ["dataAccessService"];
constructor(private dataAccessService: app.common.DataAccessService)
{
this.toDoItems = [];
var toDoResource = dataAccessService.getToDoResource();
toDoResource.query((data: app.domain.ToDoItems[]) => {
this.toDoItems = data;
});
}
}
angular.module("toDoManagement").controller("ToDoCtrl", ToDoCtrl);
}
Here is my ToDoItems class:
module app.domain {
export class ToDoItems {
constructor(public id: number, public title: string, public description: string,
public due: Date, public completed: boolean) { }
}
}
Those are all of the fields in my database. This is my view:
<table>
<thead>
<tr>
<td>Title</td>
<td>Description</td>
<td>Due Date</td>
<td>Completed</td>
</tr>
</thead>
<tbody ng-repeat="item in vm.toDoItems">
<tr>
<td>{{item.title}}</td>
<td>{{item.description}}</td>
<td>{{item.due}}</td>
<td>{{item.completed}}</td>
</tr>
</tbody>
</table>
My problem is the Due column shows up empty for each row. Is this some sort of formatting error from MySQL to JavaScript? The Due field in my database is of type DATE not DATETIME in case that's relevant.
FIXED: The problem was the variable that because of the way I named the variable in the database, the value for Due was being assigned to a variable that didn't exist in the class and was instead making its own variable named due_Date that I didn't know about. I just had to change the binding from {{item.due}} to {{item.due_Date}}.
This is just a shot in the dark but does the date filter in angular help?
{{ item.todo | date : 'medium' }}
I think that's it just off the top of my head
Related
I have an array(formResponses) of objects. My object structure is as shown below. In the below picture I have userResponses object, where I have keys and value loaded dynamically. I want to display userResponses object in my HTML. How can I do this?
All the keys and values in userResponses object are loaded differently each time.
I know I can display if I do it like this:
<p>{{userResponses.firstName}}</p>
<p>{{userResponses.lastName}}</p>
But, I don't know what values are loaded everytime. Is there a way to display any value which is in the object.
<table>
<thead>
<th>Name/Attributes</th>
<th>arrtibute1</th>
<th>attribute2</th>
</thead>
<tbody>
<tr *ngFor="let item of formResponses">
<td>{{item.userName}}</td>
<td>{{item.userResponses.firstName}}</td>
<td>{{item.userResponses.lastName}}</td>
</tr>
</tbody>
</table>
Create a pipe to loop json keys.
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({ name: 'keys' })
export class KeysPipe implements PipeTransform {
transform(value): any {
if(!value) return null;
return Object.keys(value);
}
}
<td *ngFor="let key of item.userResponses | keys">{{item.userResponses[key]}}</td>
I want to navigate to an URL based on the key of an object in my database, but when i acces the p.$key value is always undefined.
service:
getAll(){
return this.db.list('/products').valueChanges();
}
component:
products$;
constructor(private productService: ProductService) {
this.products$ = this.productService.getAll();
}
html:
<table class="table">
<thead>
<tr>
<th>Title</th>
<th>Price</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let p of products$ | async">
<td>{{p.title}}</td>
<td>{{p.price}}</td>
<td>
<a [routerLink]="['/admin/products/', p.$key]" >Edit</a>
</td>
</tr>
</tbody>
</table>
I am getting the right values for p.title and p.price, but p.$key is always undefined. I also tried p.key , same thing.
The valueChanges() stream doesn't include the key of the nodes. According to the AngularFire documentation on [valueChanges](When would you not use it? - When you need a more complex data structure than an array or you need the key of each snapshot for data manipulation methods. This method assumes you either are saving the key for the snapshot data or using a "readonly" approach.):
When would you not use it? - When you need a more complex data structure than an array or you need the key of each snapshot for data manipulation methods. This method assumes you either are saving the key for the snapshot data or using a "readonly" approach.
I think you may want to use the snapshotChanges stream instead, which gives you the entire DataSnapshot for each object from which you can get the key and the val().
Service:
Pipe is not necessary. I used it so you can console.log your object to view.
getAll(){
return this.db.list('/products').snapshotChanges()
.pipe(
map(object => {
console.log(object);
return object;
})
);
}
Component
Same as yours
html
<span *ngFor="let item of items$ | async">
<!-- print out the key values -->
{{item.key}}
</span>
In my project I getting the data from JSONPlaceholder - Users
I'm new in Angular, so if you find something stupid in the way I get the data please warn me.
dataFromServer;
constructor(private http: HttpClient){
this.dummyPromise.then(
response => {
console.log("response from dummy promise:", response);
this.dataFromServer = response;
},
error => {
console.log("Error happened with dummy promise:", error)
}
)
}
dummyPromise = new Promise((resolve, reject) => {
this.http.get('https://jsonplaceholder.typicode.com/users').subscribe(data => {
console.log(data);
this.dataFromServer = data;
});
//resolve(returnData);
});
Problem is, in my HTML file, I write the data into a table like this:
<tr *ngIf="dataFromServer">
<td>{{dataFromServer[0].id}}</td>
<td>{{dataFromServer[0].name}}</td>
<td>{{dataFromServer[0].username}}</td>
<td>{{dataFromServer[0].email}}</td>
</tr>
<tr *ngIf="dataFromServer">
<td>{{dataFromServer[1].id}}</td>
<td>{{dataFromServer[1].name}}</td>
<td>{{dataFromServer[1].username}}</td>
<td>{{dataFromServer[1].email}}</td>
</tr>
... for all the 10 people. I want to do it dynamically, as many lines as many people's data I get.
I think that you should try to use *ngFor instead of *ngIf. I will give you an example.
<tr *ngFor="let data of dataFromServer">
<td>{{data.id}}</td>
<td>{{data.name}}</td>
<td>{{data.username}}</td>
<td>{{data.email}}</td>
</tr>
So, it will repeat for every object in your dataFromServer
use ngFor to iterate on an array of data:
<table *ngIf="dataFromServer">
<tr *ngFor="let item of dataFromServer">
<td>{{item.id}}</td>
...
</tr>
</table>
the ngIf condition on the table will prevent console errors/rendering issues if dataFromServer is null/undefined before receiving from your API
You can replace your html code as bellow
<tr *ngFor="let row of dataFromServer">
<td>{{row.id}}</td>
<td>{{row.name}}</td>
<td>{{row.username}}</td>
<td>{{row.email}}</td>
</tr>
You can use *ngFor to do it. It's pratically a for in the html. As an example we assume that we have a component like this :
private users: User[] = [];
ngOnInit(){
this.service.getUser()
.subscribe(userList => {
this.users = userList;
});
}
The User class :
export class User {
public id: number;
public name: string;
}
You can use the *ngFor in your html like this way :
<span *ngFor="let user of users">
UserID: {{user.id}} - User Name: {{user.name}}
</span>
So basically, related to your code, just put in an object of User the json data you get from the http call, then modify the html like this way :
<tr *ngFor="let user of users">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
.....
</tr>
Hi I want to iterate the data of firebase and need to display it in table.
Below is my firebase structure.I want to display the bill to, email id and po number in the tables.i can see the data in console.log, but its not populating in tables.
EDI855
Bill To
-L9ac7clRzSVT-EfGxYv:
"123456789"
-L9acDp2k34qDpubJFr6:
"123456780"
Email Id
-L9ac7cxYSALI3Ogj-nt:
"test#gmail.com"
-L9acDp87NO83OQutasK:
"test1#gmail.com"
Po Number
-L9ac7cvtNNzg7hYa355:
"123456789"
-L9acDp4PPOSo9VL9ysB:
"VV002"
Below is my html table:
div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>No</th>
<th>Bill To</th>
<th>Requested by</th>
<th>Po Number</th>
</tr>
</thead>
<tbody>
<tr>>
<td *ngFor="let x of items">{{x.$value}}</td>
</tr>
</tbody>
</table>
Below is my firebase code:
constructor(public af: AngularFire) {
af.database.list('/EDI855').subscribe(x =>{
this.items=x;
console.log(this.items)
}
Try implementing your query in the init event instead
export class MyComponent implements OnInit {
items;
constructor(public af: AngularFire) {
}
ngOnInit() {
this.af.database.list('/EDI855').subscribe(x =>{
this.items=x;
}
}
Or even better, to get the most out of the real-time database, you should consider using the async pipe. When you do that, your app will react to any changes on your data and immediately refresh the UI.
<td *ngFor="let x of items | async">{{x.$value}}</td>
Just that in this case, remember that you're changing the type of items (it is no longer the list of items, but an observable of items), than therefore, no need to subscribe to it. The async pipe will do the work.
constructor(public af: AngularFire) {
this.items = af.database.list('/EDI855');
}
I have a scenario to bind a html table using angular js. In my table i need to show an a tag based on another column value(Payment Status). If its fully paid no need to show the a tag, else need to show it for very next element. I am a new one in angular.
<table>
<thead>
<tr>
<th>Month</th>
<th>Installement</th>
<th>PaymentAmount</th>
<th>PaymentDate</th>
<th>Payment Status</th>
<th>Pay</th>
</tr>
</thead>
<tbody>
<tr dir-paginate="row in rowCollection|orderBy:type:reverse|filter:searchKeyword|itemsPerPage:maxsize">
<td>{{row.Month}}</td>
<td>{{row.MonthlyInstallement}}</td>
<td>{{row.PaymentAmount}}</td>
<td>{{row.PaymentDate}}</td>
<td>{{row.PaymentStatus}}</td>
<td ng-if="row.PaymentStatus == 'UNPAID'">
Pay Online
</td>
<td ng-if="row.PaymentStatus == 'FULLY_PAID'">
</td>
</tr>
</tbody>
</table>
function bindFinanceDetails() {
var finUrl = baseurl + 'api/FinancialStatement/GetCarFinanceInfo';
var req = {
method: 'post',
data: {
LoginID: LoginID,
ContractNumber: 11170200669,
CustomerId: 2355898046
},
url: finUrl,
headers: {
RequestedPlatform: "Web",
RequestedLanguage: cookiePreferredLanguage,
Logintoken: $cookieStore.get('LoginToken'),
LoginId: LoginID
}
};
$http(req).then(function(response) {
var getData = response.data.FinanceList;
$scope.rowCollection = getData;
}, function(error) {
toastr.error($filter('translate')('Error Occured'));
});
}
A quite hacky solution will be something like the following (just showing you the needed change in the unpaid td element):
<td ng-if="row.PaymentStatus === 'UNPAID'" ng-show="$index === data.payOnlineIndex"
ng-init="data.payOnlineIndex = (!data.payOnlineIndex || (data.payOnlineIndex > $index)) ? $index : data.payOnlineIndex">
Pay Online
</td>
This way ng-init will run for all unpaid elements, setting the smallest index to the payOnlineIndex variable. ng-show will make sure to only show that one element that has the smallest index.
I encapsulate payOnlineIndex with a data object to keep a stable reference to it. This also requires the following addition to the controller code:
$scope.data = { payOnlineIndex: null };
See a working jsFiddle example here: https://jsfiddle.net/t3vktv0r/
Another option is running your filter and orderBy in the controller, searching for the first occurrence of an "unpaid" row, and marking that element for the "pay online" feature with some flag you can test with ng-if in your view.