2

I'm trying to follow this youtube video tutorial and at the 8:22 point of the video, I am running into the following error:

Error: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe'

enter image description here

This his how the information is stored in firebase. enter image description here

The data is set in firebase by a profile.html page.

<ion-content padding>
    <ion-item>
        <ion-label floating>Username</ion-label>
        <ion-input [(ngModel)]="profile.username"></ion-input>
    </ion-item>
    <ion-item>
        <ion-label floating>First Name</ion-label>
        <ion-input [(ngModel)]="profile.firstname"></ion-input>
    </ion-item>
    <ion-item>
        <ion-label floating>Last Name</ion-label>
        <ion-input [(ngModel)]="profile.lastname"></ion-input>
    </ion-item>

    <button ion-button block (click)="createProfile()">Create Profile</button>

</ion-content>

this profile.ts looks like this

import { Profile } from '../../models/profile';
import { AngularFireAuth } from 'angularfire2/auth';
import { AngularFireDatabase } from 'angularfire2/database';
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';

/**
 * Generated class for the ProfilePage page.
 *
 * See https://ionicframework.com/docs/components/#navigation for more info on
 * Ionic pages and navigation.
 */

@IonicPage()
@Component({
  selector: 'page-profile',
  templateUrl: 'profile.html',
})
export class ProfilePage {

    profile = {} as Profile;

  constructor(
    private afAuth: AngularFireAuth,
    private afDatabase: AngularFireDatabase,
    public navCtrl: NavController, 
    public navParams: NavParams) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad ProfilePage');
  }

  createProfile(){
    this.afAuth.authState.take(1).subscribe(auth => {
        this.afDatabase.object(`profile/${auth.uid}`).set(this.profile)
        .then(() => this.navCtrl.setRoot('HomePage'));
    })
  }

}

The models/profile.ts looks like:

export interface Profile {
    username: string;
    firstName: string;
    lastName: string;
}

At this point in the tutorial we are just simply trying to display the username on the homepage.

My home.ts file looks like this:

import { Item } from './../../models/item/item.model';
import { Profile } from './../../models/profile';
import { AngularFireDatabase, FirebaseObjectObservable } from 'angularfire2/database';
import { Component } from '@angular/core';
import { NavController, IonicPage, ToastController } from 'ionic-angular';
import { ShoppingListService } from '../../services/shopping-list/shopping-list.service';
import { Observable } from 'rxjs/Observable';
import { AngularFireAuth } from 'angularfire2/auth';

@IonicPage()

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  profileData: FirebaseObjectObservable<Profile>
    shoppingList$: Observable<Item[]>

  constructor(
    private afAuth: AngularFireAuth,
    private afDatabase: AngularFireDatabase,
    private toast: ToastController,
    public navCtrl: NavController,
    private shopping:ShoppingListService) {
    this.shoppingList$ = this.shopping
        .getShoppingList()
        .snapshotChanges()
        .map(
            changes => {
                return changes.map(c => ({
                    key: c.payload.key, ...c.payload.val()
                }));
            });
  }

  ionViewWillLoad(){
      this.afAuth.authState.subscribe(data => {
        if(data && data.email && data.uid){
          this.toast.create({
            message: `Welcome to the Jungle, ${data.email}`,
            duration: 3000
          }).present();
          this.profileData = this.afDatabase.object(`profile/${data.uid}`)

        } else {
        this.toast.create({
            message: `Could not log you in`,
            duration: 3000
          }).present();
      }
    }
  )}

My home.html page looks like this:

<ion-header>
  <ion-navbar color="primary">
    <ion-title>
      Shopping List
    </ion-title>
    <ion-buttons end>
        <button navPush='AddShoppingItemPage' ion-button>
            <ion-icon name="add"></ion-icon>
        </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <p>Username: {{(profileData | async)?.username}}</p>
  <ion-list>
    <ion-list-header>
      Items
    </ion-list-header>
    <ion-item *ngFor="let item of shoppingList$ | async" detail-push navPush="EditShoppingItemPage" [navParams]="{item: item}">
      {{item.name}}
    </ion-item>
  </ion-list>
</ion-content>

It seems as though either this line in home.ts:

this.profileData = this.afDatabase.object(`profile/${data.uid}`)

or this line:

profileData: AngularFireObject<Profile>

or this line:

import { AngularFireDatabase, FirebaseObjectObservable } from 'angularfire2/database';

is the culprit.

However, I'm not sure how to fix it. I have followed the tutorial exactly as the author has instructed, and it works fine for him. The tutorial is only 5 months old. I know that the technology is changing rapidly and 5 months is a long time, but its advancing so quickly that it makes learning it impossible as all the tutorials are broken immediately after they are published. You spend more time fixing errors that as a beginner you don't understand and can't comprehend.

5
  • How does the actual data look like that you are receiving? Commented Dec 10, 2017 at 9:23
  • On the home page it's not displaying any data from firebase. See the screenshot above. I have since removed the pipe and async from the home.html page following cgatian's advice below, and it will display the home page, but it does not receive any data from firebase. Commented Dec 10, 2017 at 16:13
  • Yeah, I understand it's not showing, that is why I asked for how the data looks like ;) i.e, copy paste the JSON you are receiving. Commented Dec 10, 2017 at 17:52
  • Sorry, I misunderstood your question. I will edit the question above to show that. Commented Dec 11, 2017 at 23:07
  • Seemingly the problem is with the async pipe, i.e related to your shopping list. But also the profile seems to be the problem. You are getting an object with the properties you want (firstname, lastname, username) nested so you need to check that you have the correct property path to your properties, since when you look at it, there is for example no property path like profileData.username, username is nested inside the key ovwO...... Commented Dec 12, 2017 at 4:24

3 Answers 3

2

The profileData property is not an observable so you can't use the async pipe with it.

Update your template with the following:

  <p>Username: {{profileData?.username}}</p>
Sign up to request clarification or add additional context in comments.

1 Comment

That makes the error go away, but it does not accomplish the intended goal of making the username appear on the homepage where it should. Nothing appears. Is profileData property supposed to be an observable?
1

This worked for me {{ (profileData)?.username}}

Comments

0

Hey

When working with the real-time database, version 5 is not using FirebaseListObservable and FirebaseObjectObservable anymore, instead, now it uses AngularFireList for lists and AngularFireObject for objects.

You should use valueChanges() now. If you add .valueChanges() afterwards, directly in the same statement, you are basically getting the Observable (whether it is a list or an object) of that AngularFireObject/List to which you can subscribe then.

So what you need to do should be looking like this :

this.profileData = this.afDatabase.object(`profile/${data.uid}`).valueChanges()

profileData should now be declared as an Observable like this (import { Observable } from 'rxjs';)

profileData : Observable<any>

and now in your view you should be able to see your property like so

{{ (profileData | async)?.firstname }}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.