javascriptbackbone.jsbackbone.js-collections

Backbone - Updating models in collection with data polled from another API


I have a Backbone collection that I'm populating from an API endpoint. This return data such as:

[
    {
        "gameId": 1234,
        "gameName": "Fun Game 1"
    },
    {
        "gameId": 1235,
        "gameName": "Fun Game 2"
    },
    {
        "gameId": 1236,
        "gameName": "Fun Game 3"
    },
    etc,
    etc,
    etc
]

The collection is very simple and is initialised in the router so it's accessible to the entire app:

var GamesCollection = Backbone.Collection.extend({
        model: GameModel,
        url: '/path/to/games/list',

        parse:function(response){
            return response;
        }
    });

I have another endpoint that returns a collection of data related to the original data. This data looks like:

[
    {
        "gameId": 1234,
        "numberOfPlayers": "1,000"
    },
    {
        "gameId": 1235,
        "numberOfPlayers": "Fun Game 2"
    },
    {
        "gameId": 9999,
        "numberOfPlayers": "Some other game that's not in the original list"
    }
]

Note that the number of players response may or may not contain data for every game in the original response and may or may not contain data for games that do not exist in the original games response.

I need to be poll the number of players endpoint every X minutes and update the models in the GamesCollection with the data from the response so I can show this in the view.

What is the best way to handle this?


Solution

  • Query your numberOfPlayers endpoint and then set the fetched data on your collection. You can customize how set works with add and remove options.

    For example,

    var GamesCollection = Backbone.Collection.extend({
        model: GameModel,
        url: '/path/to/games/list',
    
        parse: function(response){
            return response;
        },
    
        pollNumberOfPlayers: function() {
            var self = this;
            return Backbone.ajax('/numberOfPlayers/endpoint').then(function(resp) {
                self.set(resp, {add: false, remove: false, merge: true});
            });
        },
    
        startPolling: function() {
            var self = this, 
                timer = 10000; //10 seconds
    
            self.pollNumberOfPlayers().then(function() {
                setTimeout(function() {
                    self.startPolling();
                }, timer);
            });
        }
    });
    

    Note that I assumed your GameModel objects have gameId as their idAttribute.