Mdd
Mdd

Reputation: 4400

Backbone: Collection is empty when view is initialized

I have been trying to find a solution to this problem, and I think my pattern is wrong.

I am not sure how to use collection.fetch() to get data on the initial render.

I am calling the Flickr API to build some images. When clicking the button the next page value should be passed to the collection.url and a new ajax request submitted to re-render the template. However, I can not get the collection to pull in data from Flickr and pass it to the template on the initial render.

Here is a fiddle to my current code: http://jsfiddle.net/48WpV/

Here is my JavaScript:

var urlParameters = {
  page: 1,
  api_key:'a2978e5ce30c337e3b639172d3e1a0d1',
  tags: 'cats',
  method: 'flickr.photos.search',
  per_page: 3,
  format: 'json'
};

var TheModel = Backbone.Model.extend({
  default: {
    photos: '',
    stat: ''   
  }
});

var TheCollection = Backbone.Collection.extend({
  model: TheModel,

  url: 'http://api.flickr.com/services/rest'

});

var TheView = Backbone.View.extend({
  el: '.js-container',

  initialize: function () {
    this.collection = new TheCollection();

    this.fetchData();

    this.listenTo(this.collection, 'change', this.render);

    return this;
  }, 

  render: function () {        
    var temp = _.template( $('#List').html(), {collection: this.collection.toJSON()} );      
    this.$el.html(temp);   

    return this;
  },

  fetchData: function () {
    var self = this;
    this.collection.fetch({
        type: 'GET',
        dataType:'jsonp',
        data: urlParameters,
        jsonp:'jsoncallback',
        success: function (data) {
           console.log('self.collection =',self.collection.toJSON()); 
        },
        error: function () {
            console.log('ERROR!!!');
        }
    });    

    return this;
  },

  events: {
    'click .js-button': 'nextPage'   
  },

  nextPage: function () {
    urlParameters.page = urlParameters.page + 1;
    this.fetchData();

    return this;
  }

});

var theView = new TheView();
theView.render();

Here is my HTML:

<script type="text/template" id="List">
    <button class="js-button">Click for the next page</button>
    <% console.log('templates collection=',collection) %>

    <% _.each(collection, function (element, index) { %>
        <% _.each(element.photos.photo, function(ele, i) { %>

           <img src="http://farm<%- ele.farm %>.staticflickr.com/<%- ele.server %>/<%- ele.id %>_<%- ele.secret %>_m.jpg" />

        <% }); %>

    <% }); %>

</script>


<div class="js-container">

</div>

Upvotes: 0

Views: 845

Answers (1)

Rami Enbashi
Rami Enbashi

Reputation: 3556

I found the following issues in your code:

1) You need to update the url at every fetch.

fetchData: function () {
    var self = this;
    this.collection.fetch({
        url: 'http://api.flickr.com/services/rest/?page=' + pageNumber + '&api_key=a2978e5ce30c337e3b639172d3e1a0d1&tags=kitten&method=flickr.photos.search&per_page=3&format=json&jsoncallback=?',
        type: 'GET',
        success: function (data) {
           self.collection = data; 
        },
        error: function () {
            console.log('ERROR!!!');
        }
    });    

2) you need to remove '1' from your url

url: 'http://api.flickr.com/services/rest/?page=' + pageNumber + '1&api_key=a2978e5ce30c337e3b639172d3e1a0d1&tags=kitten&method=flickr.photos.search&per_page=3&format=json&jsoncallback=?

to be

  url: 'http://api.flickr.com/services/rest/?page=' + pageNumber + '&api_key=a2978e5ce30c337e3b639172d3e1a0d1&tags=kitten&method=flickr.photos.search&per_page=3&format=json&jsoncallback=?'

3) you need to change pageNumber + 1; to pageNumber += 1; to actually increase the value.

4) you don't this line self.collection = data; calling fetch() alone will assign the returned values to the collection.

5) and of course, you need to render after each fetch

here is a working code: http://jsfiddle.net/48WpV/7/

Upvotes: 2

Related Questions