2

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;
  }
}

1 Answer 1

2

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);
}
Sign up to request clarification or add additional context in comments.

4 Comments

You are correct, this method seems to run great in the constructor, however I cannot return the opportunity.title if I run the method anytime after the app is loaded such as a click event.
I’ve edited my answer to be a bit more flexible and consider your case scenario.
Wonderful! Thanks so much Hugo Noro
Always glad to help :)

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.