Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Giorgos Karyofyllis
Giorgos Karyofyllis
21,276 Points

Angular2 - Firebase database routing

I have created an application that loads a list of Players from a hard-coded array and when one of them is clicked the details of this player is displayed in a new component. I am trying now instead of the hard-coded array to get the data from Firebase database. The data are loaded correctly to the list however when I click on an item I get an error "ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable."

Players Component

@Component({

    selector: 'players',
    template: `
    <h1>{{title}}</h1>
    <ul>
        <li class="text" *ngFor="let player of players | async" (click)="onSelect(player)">
            {{player.name}}
        </li>
    </ul>
    <div *ngIf="selectedPlayer">
        <h1>{{selectedPlayer.name}}</h1> <h2>{{selectedPlayer.age}}</h2>
    </div>
    `,
    styleUrls: ['./players.component.css'],
    providers: [PlayerService]

})

export class PlayersComponent implements OnInit{

    title = 'Players'
    selectedPlayer: Player;
    players: FirebaseListObservable<any[]>;

    constructor(
        private playerService: PlayerService,
        private router: Router,    
        ){}

    getPlayers(){
        // this.playerService.getPlayers().then(players => this.players = players);
        this.players = this.playerService.getPlayers();
    }

    onSelect(player: Player): void {
        this.selectedPlayer = player;
        this.router.navigate(['/detail', this.selectedPlayer.id]);
    }

    ngOnInit(): void {
        this.getPlayers();
    }

    gotoDetail(): void {
        this.router.navigate(['/detail', this.selectedPlayer.id]);
    }

}

Player details component

@Component({

    selector: 'player-details',
    template: `
    <h1>Details</h1>
    <div *ngIf="player">
      <h2>{{player.name}} details!</h2>
    </div>
    `
})

export class PlayerDetailsComponent implements OnInit{

    title = 'Players Details'

    @Input() player: Player;
    constructor(
      private playerService: PlayerService,
      private route: ActivatedRoute,
      private location: Location
    ) {}

    ngOnInit(): void {
      this.route.paramMap
        .switchMap((params: ParamMap) => this.playerService.getPlayer(+params.get('id')))
        .subscribe(player => this.player = player);

    }
}

Player service

@Injectable()
export class PlayerService {

     players: FirebaseListObservable<any[]>;
        constructor(db: AngularFireDatabase) {
            this.players = db.list('/players');
        }
    getPlayers(): FirebaseListObservable<any[]> {
        return this.players;
    } 

    getPlayer(id: number): Observable<Player> {
    return this.getPlayers()
                .switchMap(items => items.find(player => player.id === id));
    }
}

Error Log

core.es5.js:1020 ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
    at Object.subscribeToResult (subscribeToResult.js:73)
    at SwitchMapSubscriber.webpackJsonp.../../../../rxjs/operator/switchMap.js.SwitchMapSubscriber._innerSub (switchMap.js:101)
    at SwitchMapSubscriber.webpackJsonp.../../../../rxjs/operator/switchMap.js.SwitchMapSubscriber._next (switchMap.js:94)
    at SwitchMapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
    at Notification.webpackJsonp.../../../../rxjs/Notification.js.Notification.observe (Notification.js:32)
    at QueueAction.webpackJsonp.../../../../rxjs/operator/observeOn.js.ObserveOnSubscriber.dispatch (observeOn.js:87)
    at QueueAction.webpackJsonp.../../../../rxjs/scheduler/AsyncAction.js.AsyncAction._execute (AsyncAction.js:111)
    at QueueAction.webpackJsonp.../../../../rxjs/scheduler/QueueAction.js.QueueAction.execute (QueueAction.js:33)
    at QueueScheduler.webpackJsonp.../../../../rxjs/scheduler/AsyncScheduler.js.AsyncScheduler.flush (AsyncScheduler.js:36)
    at QueueAction.webpackJsonp.../../../../rxjs/scheduler/QueueAction.js.QueueAction.schedule (QueueAction.js:27)