Ramsha Khalid
Ramsha Khalid

Reputation: 126

Add an element in Observable - Ionic 4

I am a beginner in ionic and following tutorials of my lecturer. I have a ionic 4 shopping application where user can add an item to their wishlist. I am adding just the item id to the wishlist collection in the firebase firestore. Now, when I am retrieving the wishlist and want to show items inside wishlist, I get the item ids from wishlist collection and then use those item ids to get items from items collection. I am stuck at the point where adding the items to another observable or array so I can display those items on the wishlist page. I tried to look at others solutions and they say I have to subscribe or something but I found it difficult to understand so I am posting my question. Below is my code

Interface for items

export interface Item { 
  id?: string, 
  name: string, 
  image: string, 
  price: number
}

Declaration of wishlist , items, itemsCollection , wishlistcollection and wishlistItems

  private items: Observable<Item[]>;
  private itemCollection: AngularFirestoreCollection<Item>;

  private wishlist: Observable<any>;
  private wishlistCollection: AngularFirestoreCollection<any>;
  private wishlistItems : Observable <Item[]>; 

Constructor

constructor(private afs: AngularFirestore) {
  //save the collection from firebase firestore to itemCollection
  this.itemCollection = this.afs.collection<Item>('items');

  //save the collection from firebase firestore to wishlistCollection
  this.wishlistCollection = this.afs.collection('wishlist').doc(this.userID).collection('items');

  //listen to changes in item collection and save to items
  this.items = this.itemCollection.snapshotChanges().pipe(
      map(actions => {
        return actions.map(a => {
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return { id, ...data };
        });
      })
    ); 



  //listen to changes in wishlist collection and save to wishlist
  this.wishlist = this.wishlistCollection.snapshotChanges().pipe(
      map(actions => {
        return actions.map(a => {
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return { id, ...data };
        });
      })
    );
}

Get item code for retrieving the item from items collection

getItem(id: string): Observable<Item> {
    return this.itemCollection.doc<Item>(id).valueChanges().pipe(
      take(1),
      map(item => {
        item.id = id;
        return item
      })
    );
  }

Now this is the final method that retrieves the items based on itemIDs from wishlist and save to wishListItems

getWishlistItems():Observable<any>{

    // get each id from wishlist
    this.wishlist.forEach(item =>{
      //retrieve the item from the items collection
      //but I don't understand how to add it to the wishlistItems since I can't push it to wishlistItems
      this.getItem(item.id);
    })
    return this.wishlistItems;
  }
Console.log(this.getItem(item.id));

gives this

{image: "mac.jpg", name: "MAC Cosmetics set", price: 35, id: "3w1HEZ8X11jldlcWkDDx"}
image: "mac.jpg"
name: "MAC Cosmetics set"
price: 35
id: "3w1HEZ8X11jldlcWkDDx"

How can I add the items to wishlistItems observable?

Upvotes: 0

Views: 273

Answers (1)

Peter Haddad
Peter Haddad

Reputation: 80924

The method getItem() returns an observable which is used in asynchronous code to be able to emit data. Then you can use the subscribe method to subscribe to that observable and receive the data:

this.getItem(item.id).subscribe(items => {
    console.log(items);
    this.
 });

Example in your code:

getWishlistItems(){
    this.wishlist.forEach(item =>{ 
    this.getItem(item.id).subscribe(items => {
       console.log(items);
       this.wishlistItems = items;
      });
    });
  }

This was the actual code that worked in ngInit() of wishlist page

this.crud.wishlist.subscribe(item =>{
      item.forEach(val =>{
        this.crud.getItem(val.id).subscribe(items => {
          this.wishlist.push(items);
        });
      });
    });

Therefore change the type of this.wishlistItems to any and the type of the method getWishListItems(). I'm not sure why you want to return but usually when you subscribe to anobservable to get the values then you just display those values in the template.

Upvotes: 1

Related Questions