ValueChanges & SnapshotChanges, don't get the full lists anymore with Firebase AngularFire2
Asked Answered
L

1

19

We've been having some serious problems with the recent changes to how AngularFire treats objects/lists and referencing the objects throughout our app.

The primary thing is how the old AngularFireObject & AngularFireList worked compared to the new ones. Our app was/is highly dependent on the $key value as we denormalized extensively (as recommended).

Now the docs use a map example to get the $key value but that isn't working the same, and even the valueChanges() doesn't seem to work the same.

I'm not totally sure what we should do now with the changes.

Consider:

Old Way

/* /items/
    a/{name: 'Dennis', city: 'Dallas'}
    b/{name: 'Katie', city: 'Austin'}
    c/{name: 'Will', city: 'Chicago'}
*/
let myAfList = this.af.list('path/to/items');
let itemsFirst, itemsSecond, itemsThird;

myAfList.subscribe(items => itemsFirst = items);

setTimeout(_ => myAfList.subscribe(items => itemsSecond = items), 1000);
setTimeout(_ => myAfList.subscribe(items => itemsThird = items), 2000);

/* Results for all three item arrays
    itemsFirst: [
        {name: 'Dennis', city: 'Dallas', $key: 'a'},
        {name: 'Katie', city: 'Austin', $key: 'b'}
        {name: 'Will', city: 'Chicago', $key: 'c'}
    ];
*/

All three subscriptions correctly get the full array of items and are setup to listen to future changes

New way with value changes:

let myAfList = this.af.list('path/to/items').valueChanges();
let itemsFirst, itemsSecond, itemsThird;

myAfList.subscribe(items => itemsFirst = items);

setTimeout(_ => myAfList.subscribe(items => itemsSecond = items), 1000);
setTimeout(_ => myAfList.subscribe(items => itemsThird = items), 2000);

/* Results for ONLY itemsFirst
    itemsFirst: [
        {name: 'Dennis', city: 'Dallas'},
        {name: 'Katie', city: 'Austin'}
        {name: 'Will', city: 'Chicago'}
    ];
*/

ItemsFirst as the first subscription correctly gets the items. The other two items get nothing, but all three are subscribed for future changes. None have the key value.

With map for $key

let myAfList = this.af.list('path/to/items').snapshotChanges()
            .map(actions => {
                return actions.map(action => {
                    const $key = action.payload.key;
                    const data = { $key, ...action.payload.val() };
                    return data;
                });
            });
let itemsFirst, itemsSecond, itemsThird;

myAfList.subscribe(items => itemsFirst = items);

setTimeout(_ => myAfList.subscribe(items => itemsSecond = items), 1000);
setTimeout(_ => myAfList.subscribe(items => itemsThird = items), 2000);

/* Results for ONLY itemsFirst
    itemsFirst: [
        {name: 'Dennis', city: 'Dallas', $key: a},
        {name: 'Katie', city: 'Austin', $key: b}
        {name: 'Will', city: 'Chicago', $key: c}
    ];
*/

$key is now on the list, but again it is only on the first item list...

So the quick observation is the objects now are really simple wrappers around core firebase references, and valueChanges() needs to be moved to the sub side like:

let myAfList = this.af.list('path/to/items');
myAfList.valueChanges().subscribe(items => itemsFirst = items);

This works! yay! But what about for the key? well there I have to write out the map function over and over. Or create my own function but it's not on the object proto so I have to add it to every file I use it in...

What am I missing? What is the correct way to get $key, have the subscriptions always get the full values?

Is there a better way to do this?

Leaseback answered 4/11, 2017 at 20:7 Comment(2)
so what eventually you did ? i'm stuck here now as well ..Grosmark
I do think that the mayor issue here is, you don't have any async mechanics between timeouts and the first subscribe.Swoosh
R
1

You may want to explore this possibilty:

// Generate a reference to a new location and add some data using push()
var newPostRef = postsRef.push();

// Get the unique key generated by push()
var postId = newPostRef.key;

source

Referential answered 28/3, 2018 at 2:17 Comment(1)
what about update vs push, how can we simply get the key ?Grosmark

© 2022 - 2024 — McMap. All rights reserved.