More Backbone Persistence!
25 Sep 2015Model Persistence Exercise
Before we visit the last part of the tutorial, let's practice loading and saving individual models. We can do it from scratch using ajax!
First, make sure you have a copy of three files, found in the [original repo][backbone-repo] but also listed below:
- modelServer.js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended : false}));
app.use(express.static(__dirname));
var texts = [];
// Allow optional test data...
var testValues = ['Zero','One','Two','Three','Four','Five...data...things!']
var useTestValues = process.argv[2];// a number, optional extra argument when starting server
if (useTestValues)
texts = testValues.slice(0,useTestValues);
function showData() {
console.log('Data store is now: ', texts);
}
app.get('/texts/:id', function (req, res) {
var id = req.params.id;
console.log('Sending text #%s...',id);
res.send({value : texts[id]});
});
/*
app.put('/texts/:id', function (req, res) {
var id = req.params.id;
console.log('Receiving text #%s...',id);
texts[id] = req.body.value;
showData();
res.send({});
});
app.post('/texts', function (req, res) {
console.log('Receiving new text...');
var newid = texts.length;
console.log('Assigning id of %s',newid);
texts[newid] = req.body.value;
showData();
res.send({id:newid});
});
app.get('/texts', function (req, res) {
console.log('Sending all texts...');
showData();
var textsAndIDs = texts.map(function (v, i) {
return {id : i, value : v};
});
res.send(textsAndIDs);
});
*/
app.listen(3000);
showData();
- model.html
<!doctype html>
<html>
<head>
<title>Persisent Model Demo</title>
<script type="text/javascript" src="js/jquery-2.1.4.js"></script>
<script type="text/javascript" src="js/underscore.js"></script>
<script type="text/javascript" src="js/backbone.js"></script>
<script type="text/javascript" src="model.js"></script>
</head>
<body>
</body>
</html>
- model.js
var TextModel = Backbone.Model.extend({
defaults : {"value" : ""},
urlRoot: '/texts',
//fetch: function() {},
//save: function() {},
initialize : function () {
this.fetch();
},
replace : function (str) {
this.set("value", str);
this.save();
}
});
/*
var TextCollection = Backbone.Collection.extend({
model : TextModel,
url : "/texts",
initialize: function () {
this.fetch();
}
});
var textCollection = new TextCollection();
*/
Exercise
Notice that the server can be started with or without test data. Starting it with
node modelServer.js
runs the server with no initial data. Starting it withnode modelServer.js N
for some digit N will give the server a few test models to work with.Start the server with
node modelServer.js 6
, direct your browser tolocalhost:3000/model.html
and open the console.Test out models' built-in
fetch()
method. In the browser console, make anew TextModel({})
. You'll get a 404 error. Can you explain why?Next try
new TextModel({id:3})
. What happens now and why?Write your own version of
fetch()
! Uncomment TextModel's fetch method and implement it using$.get(...)
.Now try using the model's built-in save method. On your current model, try
model.replace('test')
. You'll get a 404 error. Why?Uncomment the server's 'put' route and try again.
Write your own version of
save()
! Uncomment TextModel's save method and implement it using a variant of$.ajax(url,{method:'PUT'})
. Ignore any models which don't have an id attribute.Test your save() on a new model:
new TextModel({value:test, id:1})
. Check the server log! Then reload your browser page and trynew Model({id:1})
. Did you model save and load correctly?Now try saving a model which has no id! First uncomment the server's 'post' route. Then modify your save() method to make an ajax POST request for a model with no id.
Finally, uncomment the last server route and the client's TextCollection code. What happens when you reload your browser page?