1

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!

3
  • 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. Commented Dec 14, 2018 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 Commented Dec 14, 2018 at 20:27
  • OK couldn't help myself! I've edited the original post Doug, does that make it any clearer? Thanks in advance ;) Commented Dec 14, 2018 at 21:17

1 Answer 1

3

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).

Sign up to request clarification or add additional context in comments.

4 Comments

Ah, of course! I’ll try it in the morning. Thanks for the help it’s very much appreciated :)
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!
Wouldn't you just put it inside the lambda you pass to pipe()?
Yep - got it! Thanks :)

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.