3
votes

I'm trying to get some information from the database through the get() function, but when I try to run it gets the error of the title, stating

at HomeTabPage.push ../src/app/home-tab/home-tab.page.ts.HomeTabPage.ngOnInit (home-tab.page.ts: 18)

No *ngFor I already tried to use the Elvis parameter, but it did not work. I already passed my main function out of ngOnInit and declared another function to reference, but it did not work.


home-tab.page.html


<ion-list >
    <ion-item *ngFor="let advert of advertList">
        <ion-thumbnail slot="start">
           <ion-img src="advert?.image"></ion-img>
         </ion-thumbnail>
         <ion-label>
           <h2 >{{advert?.name}}</h2>
           <h3 >{{advert?.price}}</h3>
           <p >{{advert?.description}}</p>
        </ion-label>
     </ion-item>
  </ion-list>

home-tab.page.ts


export class HomeTabPage implements OnInit {
  public advertList: Array<any>;

  constructor(private navCtrl: NavController, public adService: AdvertisingService) {}

  ngOnInit(){
    this.adService.getAdAllList().get().then(advertListSnapshot => {
      this.advertList = [];
      advertListSnapshot.forEach(snap =>{
        this.advertList.push({
          id: snap.id,
          name: snap.data().name,
          price: snap.data().price,
          description: snap.data().description,
          image: snap.data().picture
        });
      });
    });
  }
}

service.ts


export class AdvertisingService {
  public adAllListRef: firebase.firestore.CollectionReference;
  constructor() {
    firebase.auth().onAuthStateChanged(user => {
      if (user) {
        this.adAllListRef = firebase.firestore().collection(`/adverts/adAll/adList`);
      }
    });
  }

  //cRud -> Read
  getAdAllList(): firebase.firestore.CollectionReference {
    return this.adAllListRef;
  }
}

ERROR

HomeTabPage_Host.ngfactory.js? [sm]:1 ERROR TypeError: Cannot read property 'get' of undefined
    at HomeTabPage.push../src/app/home-tab/home-tab.page.ts.HomeTabPage.ngOnInit (home-tab.page.ts:18)
    at checkAndUpdateDirectiveInline (core.js:22099)
    at checkAndUpdateNodeInline (core.js:23363)
    at checkAndUpdateNode (core.js:23325)
    at debugCheckAndUpdateNode (core.js:23959)
    at debugCheckDirectivesFn (core.js:23919)
    at Object.eval [as updateDirectives] (HomeTabPage_Host.ngfactory.js? [sm]:1)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:23911)
    at checkAndUpdateView (core.js:23307)
    at callViewAction (core.js:23548)

ERROR

1
post your service codeSajeetharan
The problem isn't with your template, it is with your typescript code. Look at this line this.adService.getAdAllList().get().then(.. it looks like the `getAdAllList() is returning null and therefore calling get on an undefined value throws the error.Kalenda
I posted the service code. It makes sense what you said. With this code I put service.ts, the path I'm trying to request is wrong? Should I pass any parameters?Caio Costa
Your problem is that you are trying to access it before its ready. I haven't worked with Firebase for a few weeks and have promptly forgotten everything but I can see you are missing the core concept that you are dealing with async streams of data. My recommendation, and I mean this in a nice way - Firebase is hard, would be to find a good Firebase tutorial and get back to basics, or you won't really understand what the fix is doing even if its provided.rtpHarry

1 Answers

2
votes

Ok, there is one scenario which has not been handled by your code. What if user is undefined in firebase.auth().onAuthStateChanged ? Your this.adAllListRef will not be initialized, and so you'll get the same error in that case as well.

I might not be able to give a working code, but I can suggest you the approach to handle this:

Since this page works only when user is valid, so try to use AuthGuard which could be something like:

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router, Route } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {


  constructor(private _router: Router,private _advSvc: AdvertisingService) {
  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> 
  {
    return new Promise((resolve) => {
      firebase.auth().onAuthStateChanged(user => {
         if (user) {
            resolve(true);
         }else{
           this._router.navigate(['/login']);
           resolve(false);
         }
      });
   }
}

in AdvertisingService, you dont need to check for user because it is only being called because AuthGuard has validated the user.

export class AdvertisingService {
  constructor() {
  }

  getAdAllList(): firebase.firestore.CollectionReference {
    return firebase.firestore().collection(`/adverts/adAll/adList`);
  }
}

and define router as:

  const route = [
    { .... },
    {path: '/home',component: HomeTabPage, canActivate: [AuthGuard] },
    {path: '/login',component: LoginPage }
  ]