Last active
March 8, 2022 18:23
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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. | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
very good and very well!