0

I'm using Firebase with an Ionic3 / Angular4 application.

The data in Firebase Realtime Database looks like this:

database structure

With the TS code below, I'm retrieving observable data from Firebase...

getDishesCategories(uid: string) {

    // 1. Fetch an observable AngularFire database snapshot

    const afDishCategoriesList$ = this.database.list<DishCategory>(`/users/${uid}/dishcategories/`).snapshotChanges()

    // 2. Map the AF list to an observable list of dish category objects

    const dishCategoriesList$ = afDishCategoriesList$.pipe(map(changes => {
      return changes.map(c => ({
      ...c.payload.val()
      }))
    }))

    // 3. return the observable list of dish objects

    return dishCategoriesList$
}

This is giving me the following:

[{
    createdDate: "2018-12-14T15:59:25.345Z",
    dishes: { ozvawkfci1dadyuibgdy4: {name: "Dish 1", selected: true} },
    id: "default01",
    name: "All Dishes",
    selected: true,
    toggleDisabled: true
}]

The problem is that the 'dishes' data is still being received as JSON, with the Firebase key, and values as an object.

I'm trying to map the 'dishes' object of objects into a standard array, so I can call methods like .length() on it, and use indexes rather than keys.

This is what I'm trying for (dishes also mapped to an array):

[{
    createdDate: "2018-12-14T15:59:25.345Z",
    dishes: [ {name: "Dish 1", selected: true} ],
    id: "default01",
    name: "All Dishes",
    selected: true,
    toggleDisabled: true
}]

I don't need the Firebase key here, just a bog standard zero indexed array, with each dish stored as an object at each index. Just can't visualise how to do this as I'm new to .map(), and I've been staring at it for hours now!

Could anyone help?

Thanks!

Mark Reiner
  • 72
  • 2
  • 11
  • I think it would be easier if you clearly define (with JSON style syntax, not screenshots), the structure of the objects you have, and the structure of the objects you want instead. You probably just need to perform some basic translation from one thing to the other thing. – Doug Stevenson Dec 14 '18 at 20:23
  • Oh hey Doug! I’ve been watching your videos - really helpful, thanks so much for those :). Ok I’ll add that detail in tomorrow, I’m taking a screen break for the night! Cheers – Mark Reiner Dec 14 '18 at 20:27
  • OK couldn't help myself! I've edited the original post Doug, does that make it any clearer? Thanks in advance ;) – Mark Reiner Dec 14 '18 at 21:17

1 Answers1

2

This is just a simple data transform in JavaScript. Iterate the properties of the object in dishes and build an array of just the values of those properties. Then overwrite the original property with that new array. For each object o in the array, something like this:

o.dishes = Object.keys(o.dishes).map(key => o.dishes[key])

If you're targeting newer versions of JavaScript, you could do this even easier with o.dishes = Object.values(o.dishes).

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Ah, of course! I’ll try it in the morning. Thanks for the help it’s very much appreciated :) – Mark Reiner Dec 14 '18 at 22:20
  • Hi Doug, `o.dishes = Object.keys(o.dishes).map(key => o.dishes[key])` is working perfectly when I'm subscribing to the `dishCategoriesList$` data and running a forEach() loop on the categories. Ideally, I'd like to perform this transformation while I'm mapping in step 2 of the `getDishesCategories` method above - so when I subscribe to the data from anywhere in the app, it's already transformed correctly. I can't get it working. I appreciate this is basic stuff but iterating object properties and using map are really new to me. Thanks! – Mark Reiner Dec 15 '18 at 11:03
  • Wouldn't you just put it inside the lambda you pass to pipe()? – Doug Stevenson Dec 15 '18 at 18:16
  • Yep - got it! Thanks :) – Mark Reiner Dec 17 '18 at 13:06