0

I have three variables and i was created one array and pushed all these three variables in to this array.

And in my html template i am using a table. I tried with *ngFor but it is not working and also i tried with string interpolation and that too not woriking.

I am getting an error called <--can not read property "title" of undefined-->

In my console i am getting data like this....

array of data
(3)[{...}{...}{...}]
0:{key:"-LtZprPfMtDgzuxmaI5o"}
1:{price:1}
2:{title:"title1"}

array of data
(3)[{...}{...}{...}]
0:{key:"-LtcY8_6dd8fzibK9EYV"}
1:{price:2}
2:{title:"title2"}

array of data
(3)[{...}{...}{...}]
0:{key:"-LtcZF9NHknDZ0OcKzHg"}
1:{price:3}
2:{title:"title3"}

And here my product.component.ts

import { ProductsService } from './../../products.service';
import { Component, OnInit } from '@angular/core';
import { AngularFireDatabase, AngularFireAction, DatabaseSnapshot } from 'angularfire2/database';

@Component({
  selector: 'app-admin-products',
  templateUrl: './admin-products.component.html',
  styleUrls: ['./admin-products.component.css']
})
export class AdminProductsComponent{
  constructor(
    private products:ProductsService,
    private db : AngularFireDatabase
    ) { 
    products.getAll().on('child_added',function(c){
        let data = c.val();
        let key = c.key;
        let price = data.price;
        let title = data.title;
        let array=[];
        array.push({"key":key});
        array.push({"title":title});
        array.push({"price":price});
        console.log('array of data',array);
    })    
  }
}

And my admin-products.component.html

<table class="table">
    <thead>
        <th>Title</th>
        <th>Price</th>
        <th></th>
    </thead>
    <tbody *ngFor="let p of array">
        <td>{{p.title}}</td>
        <td>{{p.price}}</td>
        <td ><a [routerLink]="['/admin/products',p.key]">Edit</a></td>
    </tbody>
</table>
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807

5 Answers5

0

Try like this:

  • Have the loop in tr instead of td
  • Change {{array.title}} to {{p.title}}
  • Make array global

.html

<tbody>
    <tr *ngFor="let p of array">
        <td>{{p.title}}</td>
        <td>{{p.price}}</td>
        <td ><a [routerLink]="['/admin/products',p.key]">Edit</a></td>
    </tr>
</tbody>

.ts

export class AdminProductsComponent{
     array:any[] = [];
     products.getAll().on('child_added',function(c){
            let data = c.val();
            let key = c.key;
            let price = data.price;
            let title = data.title;
            this.array=[];
            this.array.push({"key":key});
            this.array.push({"title":title});
            this.array.push({"price":price});
            console.log('array of data',this.array);
        })  
}
Adrita Sharma
  • 21,581
  • 10
  • 69
  • 79
0

Change this:

    <tbody *ngFor="let p of array">
        <td>{{array.title}}</td>
        <td>{{array.price}}</td>

into this:

    <tbody *ngFor="let p of array">
        <td>{{p.title}}</td>
        <td>{{p.price}}</td>

You have an array of object, therefore you need to use ngFor to iterate inside the array and then use the variable p to access the attribute's values.

Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
0

array is a local variable inside your callback. Make it a member of your component to make it available in the template.

export class AdminProductsComponent{
  array: any[] = [];

  constructor(
    private products:ProductsService,
    private db : AngularFireDatabase
    ) { 
    products.getAll().on('child_added', c => {
        let data = c.val();
        let key = c.key;
        let price = data.price;
        let title = data.title;
        // you probably want one item per product, not three??
        this.array.push({ key, title, price });
    })
  }
}

Template:

<tbody >
  <tr *ngFor="let p of array">
    <td>{{p.title}}</td>
  </tr>
</tbody>
hansmaad
  • 18,417
  • 9
  • 53
  • 94
0

From your html code, I think you need a array of object. for example :

array = [
    {key: 'key1', title: 'title 1', price: 10, },
    {key: 'key2', title: 'title 2', price: 10, },
    {key: 'key3', title: 'title 3', price: 10, }
]

if my assumption is correct then there are several problems here.

  1. array construction is not ok.
  2. your array variable is local. make it a public variable otherwise from html you can't access it.
  3. In html, you are trying to iterate the array and each iteration, the data will be assigned in your local variable 'p' (as you are using *ngFor="let p of array")

so, change your code to this

import { ProductsService } from './../../products.service';
import { Component, OnInit } from '@angular/core';
import { AngularFireDatabase, AngularFireAction, DatabaseSnapshot } from 'angularfire2/database';

@Component({
  selector: 'app-admin-products',
  templateUrl: './admin-products.component.html',
  styleUrls: ['./admin-products.component.css']
})
export class AdminProductsComponent{
  array: any = [];
  constructor(
    private products:ProductsService,
    private db : AngularFireDatabase
    ) { 
    products.getAll().on('child_added',function(c){
        let data = c.val();
        let key = c.key;
        let price = data.price;
        let title = data.title;
        this.array.push({"key":key, "title":title, "price":price });
        console.log('array of data', this.array);
    })    
  }
}

and change your html to this,

<table class="table">
    <thead>
        <th>Title</th>
        <th>Price</th>
        <th></th>
    </thead>
    <tbody *ngFor="let p of array">
        <td>{{p.title}}</td>
        <td>{{p.price}}</td>
        <td ><a [routerLink]="['/admin/products',p.key]">Edit</a></td>
    </tbody>
</table>
Sadid Khan
  • 1,836
  • 20
  • 35
  • Getting an error called can not read property 'array' of null – Srinivas Neelamraju Nov 15 '19 at 10:42
  • use this.array instead – Sadid Khan Nov 15 '19 at 10:55
  • @SrinivasNeelamraju please mark as accepted if it is exactly what you were expected or your issue is solved. Upvote it if it at least helps you to solve the issue. you can do both if it is accepted to you. If it is irrelevant downvote it. Your feedback is very much appreciated. – Sadid Khan Dec 10 '19 at 03:53
0

Define an array property in your component and pass objects into it. Use Arrow function for the on callback so your this context is the component.

import { ProductsService } from './../../products.service';
import { Component, OnInit } from '@angular/core';
import { AngularFireDatabase, AngularFireAction, DatabaseSnapshot } from 'angularfire2/database';

@Component({
  selector: 'app-admin-products',
  templateUrl: './admin-products.component.html',
  styleUrls: ['./admin-products.component.css']
})
export class AdminProductsComponent{
  // Define property here
  public array = [],

  constructor(
    private products:ProductsService,
    private db : AngularFireDatabase
    ) { 
    products.getAll().on('child_added',(c) => {
        let data = c.val();
        let key = c.key;
        let price = data.price;
        let title = data.title;
        this.array.push({key, title, price});
    })    
  }
}
Sadid Khan
  • 1,836
  • 20
  • 35
user3588429
  • 976
  • 6
  • 5