Skip to content

Instantly share code, notes, and snippets.

@daniel-234
Last active March 8, 2022 18:23
Show Gist options
  • Save daniel-234/d6ed0cf947a6f42fac073bf01a35af47 to your computer and use it in GitHub Desktop.
Save daniel-234/d6ed0cf947a6f42fac073bf01a35af47 to your computer and use it in GitHub Desktop.
BackboneJS - Fetch data from an API and parse the response populating models inside a collection
// Create a Backbone Model with default attributes.
var Food = Backbone.Model.extend({
/* Set the idAttribute inside the Model and make
* sure the ids of the Models that populate the same
* Collection are different from each other.
* See [Stackoverflow](http://stackoverflow.com/questions/18007118/
* backbone-collection-length-always-set-to-one-with-nested-views).
*/
idAttribute: '_id',
defaults: {
brandName: '',
itemName: '',
itemCalories: '',
itemWeight: ''
}
});
// Create a Backbone Collection.
var FoodList = Backbone.Collection.extend({
// Model reference
model: app.Food,
// URL to be used in the fetch operation.
url: 'https://api.nutritionix.com/v1_1/search',
/* The `parse` function is called by Backbone whenever a
* collections's models are returned by the server in `fetch`.
* The default implementation simply passes through the raw
* JSON response.
* If this response is not what you were expecting to populate
* your models, you will need to override it.
*/
parse: function(response) {
// Uncomment if you need to see the raw response.
// console.log(response);
// Save this scope inside a variable.
var self = this;
/* Iterate through the `hits` array of Objects using the `UnderscoreJS`
* `each` function, create a Model for each array item, set its
* attributes taking the values from any object `fields` property and
* push it into the collection.
*/
_.each(response.hits, function(item, index) {
// console.log(item.fields);
// console.log(item.fields.item_name);
var member = new self.model();
/* Set the idAttribute explicitly to make sure every Model has
* its unique one [Stackoverflow](http://stackoverflow.com/questions/
* 18007118/backbone-collection-length-always-set-to-one-with-nested-views).
*/
member.set('_id', index);
// Set the defaul attributes.
member.set('brandName', item.fields.brand_name);
member.set('itemName', item.fields.item_name);
member.set('itemCalories', item.fields.nf_calories);
member.set('itemWeight', item.fields.nf_serving_weight_grams);
self.push(member);
});
// Check to see that the collection has been populated by models.
console.log('length of this collection: ' + this.length);
// Log the collection to the console to see if it gets populated correctly.
// console.log(this);
return this.models;
}
});
// Create a View Collection.
var FoodListView = Backbone.View.extend({
// Reference to a `foods` id inside an HTML file where the View might be rendered.
// Change it to the `id` you defined in your file.
el: '#foods',
initialize: function() {
// Bind the relevant events to the collection.
this.listenTo(this.collection, 'reset change', this.render);
// Define a new collection.
this.collection = new FoodList();
// Cache the reference to this scope.
var self = this;
// Fetch request. Request requirements must match the ones requested
// by the server. Check the API documentation for more informations
// (https://developer.nutritionix.com/docs/v1_1).
this.collection.fetch({
url: this.collection.url,
type: 'post',
contentType: 'application/json',
data: JSON.stringify({
// Change `*****` and `#####` with your own credentials.
'appId': '*****',
'appKey': '#####',
'query': 'Starbucks OR frapp*',
'fields': [
'item_name',
'brand_name',
'nf_calories',
'nf_serving_weight_grams']
}),
reset: true,
// As `fetch` is asynchronous, wait for the operation to be completed.
success: function() {
// Just log the collection and see if the models have
// been correctly populated.
console.log(self.collection);
}
// Add an `error` handling.
});
}
// Now that your collection has been populated, you can render it
// as you'd like.
});
About this gist
With this gist I wanted to freeze some concepts about BackboneJS that could
save some time in the future either to me if I needed to use this functionality
again, or to somebody else.
This implementation addresses the need to retrieve some data from an API and
to populate a BackboneJS collection accordingly, storing the retrieved items
as Models inside the Collection.
If you want to see this functionality built into an application, have a look
at my repository called `frontend-health-tracker-project`. This functionality
is built inside it and it took me some time to put all the pieces together, so
I thought it worth it to save the basic steps and references.
The two fundamental resources to start with when using BackboneJS are the
official BackboneJS documentation and the book `Backbone fundamentals` written
by Addy Osmani.
Another great resource is a blog post written by Miguel Mota whose title is
`Getting started with Backbone.js`.
Other than the previous ones, you can search to find really great answers on
Stackoverflow to help you build you knowledge in your `fail and discover`
learning process.
The API used it is the `Nutritionix API v.1.1`. If you want to use their service,
you should register with them (they have a free account for developers) and
generate your own Id and Key, to replace the `*****` and `#####` I used in this
app.
You can also apply the same concepts to any other API you would like to use.
To see and study the object returned from the API I used a very useful program,
called `Postman` (https://www.getpostman.com/). With this program or others that
you might like it's easier to see if the response returned by the server is what
you were expecting.
@Greed2kk
Copy link

very good and very well!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment