0

I am unable to render data in my template since property: product={} is returning empty object.

ProductComponent.ts--->

{
    category$;

    product={};

    id;

    constructor(

       private router:Router,

       private route:ActivatedRoute,

       private categoryService:CategoryService, 

       private productService:ProductService)

       { 

         this.category$= categoryService.getCategories();

         this.id=this.route.snapshot.paramMap.get('id');

         if(this.id)        
             this.productService.getProduct(this.id).take(1)
             .subscribe(p=>this.product=p);    

         console.log(this.product)
       }

this.product is showing null. Although when I log "p" inside subscription, is returning empty object. But just not outside the subscription. I am not able to get product data on template also because of this empty object.

TEMPLATE--->

 <label for="title">Title</label>
     <input #title="ngModel" [(ngModel)]="product.title" name="title" 
    id="title" type="text" class="form-control" required>
    <div class="alert alert-danger" *ngIf="title.touched && title.invalid">
      Title is required
    </div>

HELP!!

Below is my ProductService

import { AngularFireDatabase } from 'angularfire2/database';
import { Injectable } from '@angular/core';

@Injectable()
export class ProductService {

  constructor(private db: AngularFireDatabase) { }

  create(product){
    return this.db.list('/products').push(product);
  }

  update(productId, product)
  {
    return this.db.object('/products/' + productId).update(product);
  }
  deleteProduct(productId){
    this.db.object('/products/' + productId).remove();
  }
  getAll(){
    return this.db.list('/products');
  }
  getProduct(id){
    return this.db.list('/products/' + id);
  }


}
Chaitanya
  • 21
  • 2
  • You have to debug the method you implemented in your service `getProduct(this.id)`. share the code of that method. or the full code of your service – HDJEMAI Oct 21 '17 at 03:32
  • What happens if you use curly brackets?: `if() { // code here }` Could you share a snippet from `ProductService` including the `getProduct()` method? – stealththeninja Oct 21 '17 at 03:39

1 Answers1

0

Try like this :

print the console inside the subscribe method

if(this.id) {
    this.productService.getProduct(this.id).take(1)
        .subscribe(p => {
            this.product = p
            console.log('this.product', this.product);
        });
}
Chandru
  • 10,864
  • 6
  • 38
  • 53
  • this.product is set to product object inside subscription as you suggested.But when this.product is used outside, it is empty. Also, the order of statements executed: Angular is running in the development mode. Call enableProdMode() to enable the production mode. product-form.component.ts:30 {} product-form.component.ts:28 this.product (4) [{…}, {…}, {…}, {…}] – Chaitanya Oct 21 '17 at 05:16
  • use setTimeout outside the subscribe method : like setTimeout(() => { console.log('this.product', this.productt); }, 1000) – Chandru Oct 21 '17 at 05:18
  • Check this answer https://stackoverflow.com/questions/46860230/unable-to-subscribed-data-into-a-variable ? hope it will be helpful – Chandru Oct 21 '17 at 05:21
  • SetTimeOut() works!! But template is not rendering product.title, which means product object is null. – Chaitanya Oct 21 '17 at 05:25
  • use template like
    {{product | json}}
    or
    {{product?.title}}
    – Chandru Oct 21 '17 at 05:27
  • {{product | json}} works!! but can you explain me why the subscription is not working with the property? I had success subscribing to Observables with similar scenarios, but just not this. – Chaitanya Oct 21 '17 at 05:40
  • @Chaitanya do NOT use `setTimeout`, you cannot know how long it takes to execute the request, it could take much longer. Understanding this async behavior, check this: https://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular2 and this: https://stackoverflow.com/questions/41242793/angular2-error-typeerror-cannot-read-property-of-undefined For the second, it takes some time to set the values for your variable, so when the view is rendered, at that moment `product` is undefined. Safe navigation operator will help that. – AT82 Oct 21 '17 at 06:38
  • @AJT_82. Safe navigation works only for interpolation. I have a two way binding with product.title. Would you suggest a work around? – Chaitanya Oct 22 '17 at 00:32
  • @Chaitanya Yes, then you would want this: https://stackoverflow.com/a/39755385/6294072, but seems strange, since you have initialized product `product = {}` it shouldn't be null. Hmm, but anyway the one-way-binding and `ngModelChange` should work :) – AT82 Oct 22 '17 at 07:19