Async Pipe not working

Hi Mr. Jason & All

Any idea on how to fix this issue?
The products list is not getting loaded from firebase.

Hello Ahmed, could you paste your product-form.component.ts and product-form.component.html files in code blocks like this:

product-form.component.ts

```
Contents of TS file
```

product-form.component.html

```
Contents of HTML file 
```

product-form.component.ts

import { Component, OnInit } from '@angular/core';
import { CategoryService } from 'src/app/category.service';
import { ProductService } from 'src/app/product.service';

@Component({
  selector: 'app-product-form',
  templateUrl: './product-form.component.html',
  styleUrls: ['./product-form.component.css']
})
export class ProductFormComponent implements OnInit {
  categories$: any;

  constructor(categoryService: CategoryService, private productService: ProductService) { 
    this.categories$ = categoryService.getCategories();
  }   // no need to add the private access modifier as we are not going to reference this anywhere outsde the constructor

save(product: HTMLInputElement){  // I added HTMLInputElement from my own
  console.log(product); // I didn't get to test this because the list is not generated from firebase
  this.productService.create(product);
}

  ngOnInit(): void {
  }

}

product-form.component.html

<form #f="ngForm" (ngSubmit)="save(f.value)">
    <div class="form-group">
        <label for="title">Title</label>
        <input #title="ngModel" ngModel name="title" id="title" type="text" class="form-control" required>
        <div class="alert alert-danger" *ngIf="title.touched && title.invalid">Title is required</div>
    </div>
    <div class="form-group">
        <label for="price">Price</label>
        <div class="input-group-prepend">
            <span class="input-group-text">$</span>
            <input #price="ngModel" ngModel name="price" id="price" type="number" class="form-control" required>
        </div>
        <div class="alert alert-danger" *ngIf="price.touched && price.invalid">Price is required</div>
    </div>
    <div class="form-group">
        <label for="category">Category</label>
        <select #category="ngModel" ngModel name="category" id="category" class="form-control" required>
            <div class="alert alert-danger" *ngIf="category.touched && category.invalid">Category is required</div>
            <option value=""></option>
            <option *ngFor="let c of categories$ | async" [value]="c.$Key">{{c.name}}</option>
        </select>
    </div>
    <div class="form-group">
        <label for="imageUrl">Image</label>
        <input #imageUrl="ngModel" ngModel name="imageUrl" id="imageUrl" type="text" class="form-control">
        <div class="alert alert-danger" *ngIf="imageUrl.touched && imageUrl.invalid">Image URL is required</div>
    </div>
    <button class="btn btn-primary">Save</button>
</form> 

You have typed this as an any which is not very useful to begin with since that basically means we have no typing help at all. You should type this as the appropriate observable you expect it to hold.

I cannot really get too many more details without the CategoryService implementation. Can you also share the contents of your category.service.ts file (which might need to be type-annotated anyway in order to improve the annotation for the categories$ variable)?

category.service.ts

```
contents of category.service.ts
```

I will change it

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

@Injectable({
  providedIn: 'root'
})
export class CategoryService {

  constructor(private db: AngularFireDatabase) { }

  getCategories(){
    return this.db.list('/categories', ref => ref.orderByChild('name')).valueChanges();
  }
}

I was able to solve it by applying this valueChanges() in category.service.ts

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

@Injectable({
  providedIn: 'root'
})
export class CategoryService {

  constructor(private db: AngularFireDatabase) { }

  getCategories(){
    return this.db.list('/categories', ref => ref.orderByChild('name')).valueChanges();
  }
}

1 Like