I'm trying to build a simple Backbone app from this post Unable to fetch data from Twitter RESTful API using Backbone.js Collection . What I wanna do is adding a text box and a button. Every time a user press a button, my app will request to twitter and will search in twitter based on the textbox content (it will search the word 'NYC' as default).
My code is as follows.
My tweets collection
var Tweets = Backbone.Collection.extend({
model: Tweet,
url: 'http://search.twitter.com/search.json?q=NYC&callback=?',
parse: function(response) {
console.log('parsing ...')
return response.results;
}
});
My view.
var PageView = Backbone.View.extend({
el: $('body'),
events: {
'click button#add': 'addItem'
},
initialize: function() {
_.bindAll(this, 'render', 'addItem');
this.tweets = new Tweets();
this.counter = 0;
this.render();
},
render: function() {
$(this.el).append("<input id= 'search'type='text' placeholder='Write a word'></input>");
$(this.el).append("<button id='add'>Search twitts</button>");
$(this.el).append("<ul id='tweets'></ul>");
return this;
},
addItem: function(item) {
var subject = $('#search').val() || 'NYC';
this.tweets.url = 'http://search.twitter.com/search.json?q=' + subject + '&callback=?';
// never called ...
this.tweets.bind('reset', function(collection) {
console.log(collection.length);
alert(collection.length);
});
$.each(this.tweets.fetch().models, function(index, tweet) {
item = new Tweet();
item.set({
order: this.counter,
info: tweet.attributes.text// modify item defaults
});
$('ul', this.el).append("<li>" + item.get('order') + " " + item.get('info') + "</li>");
});
}
});
var pageView = new PageView();
The thing is:
First click (empty textbox) : twitter request is captured by parse within Tweets collection. Nothing is appended to my ul element.
Second click (with some word): twitter request is made with that word. However, 'NYC' tweets from the previous call are printed.
Third click (with some other word): 'Some word' from second click are printed.
....
I realize that everytime I try to print my tweets I get the previous reply because Twitter hasn't replied me yet. I suppose that I could get my tweets in the parse callback and printed them, but it seems quite nasty.
On the other hand I've tried to get my tweets binding them to the reset event, but it doesn't work either.
Any ideas??.
Thanks in advance!!
Here's your example code done in a more idimatic Backbone pattern.
Basically:
reset
event that does something with the newly populated collectionclick
event that calls collection.fetch()
to get new data from the 'server'. reset
event is triggered, calling the event handler bound to the reset
event.Code:
var Tweet = Backbone.Model.extend();
var Tweets = Backbone.Collection.extend({
model: Tweet,
url: 'http://search.twitter.com/search.json?q=NYC&callback=?',
parse: function(response) {
console.log('parsing ...')
return response.results;
}
});
var PageView = Backbone.View.extend({
el: $('body'),
events: {
'click button#add': 'doSearch'
},
initialize: function() {
_.bindAll(this, 'render', 'addItem');
this.tweets = new Tweets();
_this = this;
// Bind an event handler for the reset event.
this.tweets.bind('reset', function(collection) {
// Clear any old tweet renderings
_this.$('#tweets').empty();
// For each tweet in the collection, we call addItem and
// and pass the tweet.
collection.each(function(tweet) {
_this.addItem(tweet);
});
});
this.counter = 0;
this.render();
},
// This function is the event handler for the button click.
// It tells the Tweets collection to fetch()
doSearch: function() {
var subject = $('#search').val() || 'NYC';
this.tweets.url = 'http://search.twitter.com/search.json?q=' + subject + '&callback=?';
this.tweets.fetch();
},
render: function() {
$(this.el).append("<input id= 'search'type='text' placeholder='Write a word'></input>");
$(this.el).append("<button id='add'>Search twitts</button>");
$(this.el).append("<ul id='tweets'></ul>");
return this;
},
addItem: function(item) {
console.log(item);
$('ul', this.el).append("<li><b>" + item.get('from_user_name') + "</b>: " + item.get('text') + "</li>");
}
});
var pageView = new PageView();
Live example to play with: http://jsfiddle.net/38L35/16/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With