1

Problem:
I want to try to have multiple games running at the root of my Firebase, they all have Firebase generated id's,
when I'm trying to fetch them using the <firebase-collection> I'm always getting an array of the Objects, and 2-way binding is very hard with Polymer.
Is there a way to get the Firebase data as an Object?

I tried to add the data-as-object attribute, but it didn't worked, I also got an array.
I even tried to use the <firebase-document> element by simply change form
<-collection> to <-document>, but then updating the game data didn't push to firebase.
I don't know if this is possible ...

Or is there a way for good two-way binding?
I can't use the index of the array item, like this: this.set('gameData.' + i), because then I'm getting the error Uncaught Error: unexpected key 2, when I try to modify the values under the Object in the array

Full code on Github

My code:
Data provider:

<firebase-collection location="https://***.firebaseio.com" 
                     data="{{data}}" data-as-object log>
</firebase-collection>
<!-- script -->
Polymer({
    is: 'tmp-game-data',
    properties: {
        data: {
            notify: true
        }
        }
});

Game Element:

<!-- map with several players(Array), -->
<!-- an player(Object) has some properties -->
<!-- on-map-ready, when the map is fully configured --> 
<tmp-map players="{{game.players}}" 
         on-map-ready="_mapReadyCallback">
</tmp-map>
<!-- menu user for creating and -->
<!-- joining games with selected settings -->
<tmp-menu on-start-global-game="startGlobalGame" 
          on-join-game="joinGame">
</tmp-menu>
<tmp-game-data data="{{gamesData}}"></tmp-game-data>
<!-- script -->
var blocks = []; //Map blocks, global access

Polymer({
    is: 'tmp-game',

    properties: {
        gamesData: {
            notify: true
        },
        game: {
            notify: true
        },
        gameId: {
            type: String
        }
    },

    startGlobalGame: function(e) {
        var gameId = getRandomString(6);
        this.set('gameId', gameId);

        var player = {id: /*playerId*/};
        var players = [player];

        this.push('gamesData', {
            gameId: gameId,
            maxPlayers: e.detail.maxPlayers,
            players: players
        });

        this.selectGame();

        //generate map
    },

    joinGame: function(e) {
        var gameId = e.detail.gameId;
        for (var i = 0; i < this.gamesData.length; i++) {
            if(this.gamesData[i].gameId === gameId) {
                var map = this.get('gamesData.' + i + '.map');
                //generate map with the map of the game
            }
        }
        this.selectGame();
    },

    selectGame: function() {
        for (var i = 0; i < this.gamesData.length; i++) {
            if(this.gamesData[i].gameId === this.gameId) {
                this.set('game', this.gamesData[i]);
                this.linkPaths('game', 'gamesData.' + i);
            }
        }
    },

    _mapReadyCallback: function(e) {
        for (var i = 0; i < this.gamesData.length; i++) {
            if(this.gamesData[i].gameId === this.gameId) {
                //get the map as a json
                var map = JSON.stringify(blocks);
                this.set('gamesData.' + i + '.map', map);
            }
        }
    }
});
1
  • I removed <dom-module>, <template> and <script> to simplify the code Commented Dec 10, 2015 at 21:12

1 Answer 1

1

I don't think that there is a way to manipulate the data as Object instead of Array...

In your snippet, you do not specify the Array type for data and gamesData

You will have to use Polymer API to manipulate the Array you get through data-binding, like this.push, this.splice, etc... like you did already.

You should also be able to this.set('gamesData.' + i + '.map', map); like described here

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

6 Comments

I thought of the <firebase-collection> attribute data-as-object, but unluckily it isn't working ... Ohh yeah I've added it, but does it matter, when I don't define the type? The problem, when you're working with firebase, you can't use the splice, because Firebase then creates a new Object with changed properties and leaves the element you wanted to delete as it is on his servers ... And last I'll get an error (added above) on this.set('gamesData.' + i + '.map', map); I don't know exactly what it means, because I works apparently the way it is supposed!
there is no such attribute! :) I am building a set of element that extends Firebase, it might interest you, and I will build also a demo out of it, I'll keep you updated. In the meantime, check out here: github.com/MeTaNoV/firebase-element-extended
But why can I find it here? Polymer Elements
dataAsObject is an acessor function defined in the behavior but only used by firebase-document
it should not even be public, just a small bug, I'll raise a small issue on that point!
|

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.