jchri853
jchri853

Reputation: 354

Get array element in observable at particular index [Typescript]

I am running an ionic3 app with Angular4 and angularfire2-Firestore.

How does one go about getting a single object from an Observable. I am looking to return in typescript.

console.log(this.opportunity.title)  //   "Title1"

In the code below I am using the getOpportunityByIndex() method with index as the parameter. I am getting the following output and I'm not sure what to do next.

Observable {_isScalar: false, source: Observable, operator: MapOperator}
    operator:MapOperator {thisArg: undefined, project: ƒ}
    source:Observable {_isScalar: false, source: Observable, operator: MapOperator}
    _isScalar:false
    __proto__:Object

Code

export interface Opportunity { title: string;  }
export interface OpportunityId extends Opportunity { id: string; }

opportunities: Observable<OpportunityId[]>;

  constructor( public firebaseProvider: FirebaseProvider)   {
    this.opportunities = this.firebaseProvider.getOpportunities();
  }

  getOpportunityByIndex(index: number) {            
     this.opportunity = this.opportunities.map(arr => arr[index]);
     console.log(this.opportunity.title);
    }
}

FirebaseProviderService

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

export interface Opportunity { title: string;  }
export interface OpportunityId extends Opportunity { id?: string; }

@Injectable()
  export class FirebaseProvider {    
  private opportunitiesCollection: AngularFirestoreCollection<OpportunityId>;
  opportunity: Opportunity

  constructor(afs: AngularFirestore) {
    this.opportunitiesCollection = afs.collection<Opportunity>('opportunities');
    this.opportunities = this.opportunitiesCollection.snapshotChanges().map(actions => {
      return actions.map(a => {
        const data = a.payload.doc.data() as Opportunity;
        const id = a.payload.doc.id;
        return { id, ...data };
      });
    });
  }

   getOpportunities() {
    return this.opportunities;
  }
}

Upvotes: 2

Views: 14735

Answers (1)

Hugo Noro
Hugo Noro

Reputation: 3243

From what I understand of your example this.opportunities is returning an observable with the array of opportunities. Having this you just need to subscribe to the stream and then you can pick the specific index passed by parameter. This is what you need to do:

getOpportunityByIndex(index: number) {            
 this.opportunities
 .subscribe( opportunities => {
     this.opportunity = opportunities[index];
     console.log(this.opportunity.title);
  });

}

Edit

If you want to make it a bit more flexible you can make the list of opportunities a regular array

opportunities: OpportunityId[]

and then in the constructor you do

constructor( public firebaseProvider:FirebaseProvider)   {
    this.firebaseProvider.getOpportunities()
    .subscribe( opportunities => {
        this.opportunities = opportunities;
    });

}

Then you can simply do whenever you want to call it

getOpportunityByIndex(index: number) {            
   this.opportunity = this.opportunities[index];
   console.log(this.opportunity.title);
}

Upvotes: 2

Related Questions