1 00:00:00,000 --> 00:00:02,000 [?music?] 2 00:00:02,000 --> 00:00:06,000 [Introduction to Backbone and Models] 3 00:00:06,000 --> 00:00:11,000 [Jim Hoskins] In this Master Class, we're going to continue building our HTML5 4 00:00:11,000 --> 00:00:13,000 mobile note-taking application. 5 00:00:13,000 --> 00:00:15,000 This is the second Master Class in our series. 6 00:00:15,000 --> 00:00:19,000 In the first Master Class, we outlined our project requirements. 7 00:00:19,000 --> 00:00:22,000 http://membership.thinkvitamin.com/library/html5-mobile-web-applications 8 00:00:22,000 --> 00:00:25,000 We determined that it needed to be optimized for mobile, use localStorage for the database, 9 00:00:25,000 --> 00:00:26,000 and be location-aware. 10 00:00:26,000 --> 00:00:30,000 We determined that we would use jQuery Mobile for handling the user interface 11 00:00:30,000 --> 00:00:34,000 and we would use Backbone.js to manage the data. 12 00:00:34,000 --> 00:00:37,000 We set up our project and created a basic homepage 13 00:00:37,000 --> 00:00:42,000 and note form for our application using the built-in functionality of jQuery Mobile. 14 00:00:42,000 --> 00:00:45,000 In this Master Class, we will write the JavaScript that will handle 15 00:00:45,000 --> 00:00:51,000 saving our notes in the database and updating our user interface whenever a note changes. 16 00:00:51,000 --> 00:00:55,000 [?music?] 17 00:00:55,000 --> 00:01:00,000 [HTML5 Mobile Development with Jim Hoskins] 18 00:01:00,000 --> 00:01:02,000 [?music?] 19 00:01:02,000 --> 00:01:06,000 So now we've used jQuery Mobile to prototype the look and feel of our application. 20 00:01:06,000 --> 00:01:10,000 We've created a homepage and a New Note form, 21 00:01:10,000 --> 00:01:14,000 but now we actually want to get down to the business of capturing the Note form, 22 00:01:14,000 --> 00:01:18,000 saving it to a database, and ultimately redisplaying it to the user 23 00:01:18,000 --> 00:01:20,000 in these different lists here. 24 00:01:20,000 --> 00:01:24,000 So now, we actually have to start building the logic of our application, 25 00:01:24,000 --> 00:01:29,000 and we're going to be doing that in our code in this application.js file. 26 00:01:29,000 --> 00:01:32,000 Now, there's a lot of different ways we could organize our code, 27 00:01:32,000 --> 00:01:36,000 and right now, we're going to stick with having it all in our application.js file. 28 00:01:36,000 --> 00:01:40,000 But later on, we can break it out in order to organize our code 29 00:01:40,000 --> 00:01:43,000 since there's actually quite a bit of it. 30 00:01:43,000 --> 00:01:46,000 Now, just so you remember, if we look in our index.html, 31 00:01:46,000 --> 00:01:50,000 our application.js is loaded as the last thing in our application, 32 00:01:50,000 --> 00:01:54,000 which means we have access to backbone, the backbone localStorage, 33 00:01:54,000 --> 00:01:58,000 setup, underscore.js, as well as jQuery. 34 00:01:58,000 --> 00:02:00,000 There's not a whole lot in jQuery Mobile we need right now, 35 00:02:00,000 --> 00:02:05,000 but we want to make sure our application is loaded last so all of our prerequisites 36 00:02:05,000 --> 00:02:10,000 and utility libraries are available to us. 37 00:02:10,000 --> 00:02:13,000 Now, there are a lot of different ways we could organize this, 38 00:02:13,000 --> 00:02:15,000 but what I'm going to do is I'm going to write all of our code 39 00:02:15,000 --> 00:02:18,000 in a self-executing private function, 40 00:02:18,000 --> 00:02:22,000 and I'm going to return the application object from that. 41 00:02:22,000 --> 00:02:25,000 That means we can create various local variables 42 00:02:25,000 --> 00:02:29,000 within the scope of our application code that won't leak out 43 00:02:29,000 --> 00:02:31,000 and interfere with any other code. 44 00:02:31,000 --> 00:02:36,000 So ultimately, I want a NotesApp variable 45 00:02:36,000 --> 00:02:38,000 that is available at the global scope, 46 00:02:38,000 --> 00:02:42,000 and everything is going to be on that object. 47 00:02:42,000 --> 00:02:48,000 So I'm going assign that to a function that's going to execute, 48 00:02:48,000 --> 00:02:52,000 so what we return from this anonymous function will be assigned to the NotesApp, 49 00:02:52,000 --> 00:02:55,000 and that's going to be our application object. 50 00:02:55,000 --> 00:02:58,000 So what I'm going to do is inside of the scope of this function 51 00:02:58,000 --> 00:03:02,000 where all of our code will be, I'm first going to create an App object. 52 00:03:02,000 --> 00:03:06,000 This will be sort of an organizing object that ultimately is returned, 53 00:03:06,000 --> 00:03:12,000 but will also serve as a way to organize the models, views, collections, 54 00:03:12,000 --> 00:03:18,000 and other pieces of information that need to be accessed by all of the application logic. 55 00:03:18,000 --> 00:03:22,000 And let me fix that typo--and we'll do it that way-- 56 00:03:22,000 --> 00:03:26,000 and there are going to be various objects within this. 57 00:03:26,000 --> 00:03:30,000 We need to make sure at the end of our code to return App; 58 00:03:30,000 --> 00:03:37,000 that way the NotesApp will take on the ultimate value of our App object in here. 59 00:03:37,000 --> 00:03:42,000 Now, one thing that we want to use is to be able to have our localStorage data store, 60 00:03:42,000 --> 00:03:46,000 and if we open up the Backbone localStorage file, 61 00:03:46,000 --> 00:03:49,000 we can see that code that is used. 62 00:03:49,000 --> 00:03:51,000 We don't really need to worry about it. 63 00:03:51,000 --> 00:03:56,000 But the way we're going to use it is we're going to instantiate one of these Store objects 64 00:03:56,000 --> 00:04:00,000 with a specific name to hold this type of object. 65 00:04:00,000 --> 00:04:04,000 For instance, we can create a store to hold all of our Note objects 66 00:04:04,000 --> 00:04:08,000 and if we had other things like locations or users, 67 00:04:08,000 --> 00:04:12,000 it would create separate store objects to maintain those separate collections. 68 00:04:12,000 --> 00:04:15,000 Now, we don't need to worry about the particular code in here. 69 00:04:15,000 --> 00:04:19,000 We will have to probably modify it a little bit later, but right now, all we need to do 70 00:04:19,000 --> 00:04:24,000 is instantiate a Store object, and then we'll be able to use that in our code 71 00:04:24,000 --> 00:04:31,000 as the localStorage in which to store all of our data. 72 00:04:31,000 --> 00:04:34,000 So I want to organize our Stores in our App object, 73 00:04:34,000 --> 00:04:39,000 so I'm going to create a property of our App object called stores: 74 00:04:39,000 --> 00:04:42,000 and I'm just going to make this an empty object so we can assign to it later. 75 00:04:42,000 --> 00:04:47,000 Now, the first thing I want to do in our app is to initialize our store for Notes 76 00:04:47,000 --> 00:04:50,000 and that's because we want to make sure our localStorage is set up 77 00:04:50,000 --> 00:04:55,000 and ready to use any time within this application. 78 00:04:55,000 --> 00:04:57,000 So what I'm going to do is simply paste in this code here 79 00:04:57,000 --> 00:05:02,000 and I'm saying App.stores, and I'm creating a new Store called ("notes")' 80 00:05:02,000 --> 00:05:05,000 and I'm just going to instantiate a new Store object for ("notes"); 81 00:05:05,000 --> 00:05:11,000 We'll be using this later and specifying when we want to use this particular store 82 00:05:11,000 --> 00:05:13,000 as we define our code later, 83 00:05:13,000 --> 00:05:18,000 but now we know we have this available to us in App.stores.notes. 84 00:05:18,000 --> 00:05:21,000 So you may be familiar with the model view controller paradigm, 85 00:05:21,000 --> 00:05:25,000 and that is different parts of our application or different parts of our code 86 00:05:25,000 --> 00:05:28,000 manage different parts of our actual application 87 00:05:28,000 --> 00:05:31,000 and the model is probably the most core concept. 88 00:05:31,000 --> 00:05:34,000 A model represents a particular object in our application. 89 00:05:34,000 --> 00:05:37,000 Now, there's really only one sort of object in our application 90 00:05:37,000 --> 00:05:39,000 and that would be a Note; 91 00:05:39,000 --> 00:05:42,000 so a Note is something that we could have multiple of. 92 00:05:42,000 --> 00:05:45,000 We're going to be creating them, modifying them, viewing them, 93 00:05:45,000 --> 00:05:49,000 and we want to be able to manage all that through a specific API 94 00:05:49,000 --> 00:05:52,000 so we want to be able to instantiate a note object 95 00:05:52,000 --> 00:05:57,000 and have that be able to be saved from session to session, 96 00:05:57,000 --> 00:06:01,000 so a Backbone model is ideal for managing that type of interaction. 97 00:06:01,000 --> 00:06:03,000 You can actually look at the Backbone API 98 00:06:03,000 --> 00:06:05,000 documentcloud.github.com/backbone/ 99 00:06:05,000 --> 00:06:07,000 to find out all of the things the model can do. 100 00:06:07,000 --> 00:06:10,000 So models allow us to instantiate a note, for instance, 101 00:06:10,000 --> 00:06:14,000 and it can have properties and it can be saved. 102 00:06:14,000 --> 00:06:18,000 For instance, we can tell it we want it to save to the localStorage data store, 103 00:06:18,000 --> 00:06:21,000 and when we call a save method on a model, 104 00:06:21,000 --> 00:06:26,000 it'll automatically save into that particular data store. 105 00:06:26,000 --> 00:06:29,000 Another cool feature is the way attributes are handled. 106 00:06:29,000 --> 00:06:34,000 Instead of using normal attributes like saying note.title = some value, 107 00:06:34,000 --> 00:06:37,000 instead, we use the get and set methods on our model 108 00:06:37,000 --> 00:06:40,000 to actually get and set those properties. 109 00:06:40,000 --> 00:06:43,000 Now, while this makes it a little more difficult to code, 110 00:06:43,000 --> 00:06:48,000 it has the added benefit of a model being able to tell whenever a property changes. 111 00:06:48,000 --> 00:06:53,000 And whenever a property does change, it will actually send out an event notification 112 00:06:53,000 --> 00:06:59,000 to anybody listening, and this is great because if we change a property of one of our Notes, 113 00:06:59,000 --> 00:07:03,000 various things need to be updated, like the page that represents that note 114 00:07:03,000 --> 00:07:07,000 needs to have its title updated, or a list view where we list all the Notes, 115 00:07:07,000 --> 00:07:09,000 needs to have its title updated. 116 00:07:09,000 --> 00:07:13,000 So being able to listen to changes is an extremely valuable feature 117 00:07:13,000 --> 00:07:17,000 that's made available in the Backbone model. 118 00:07:17,000 --> 00:07:23,000 So let's define a model called Note. 119 00:07:23,000 --> 00:07:31,000 So to do this, let's create var Note. We use a capital "N" to notify that it's a class. 120 00:07:31,000 --> 00:07:34,000 What we're going to do is we're going to extend Backbone.Model, 121 00:07:34,000 --> 00:07:41,000 and to do that, we do = Backbone.Model 122 00:07:41,000 --> 00:07:44,000 and the Backbone.Model class has an extend method on it 123 00:07:44,000 --> 00:07:48,000 which will allow us to extend the Backbone.Model class 124 00:07:48,000 --> 00:07:51,000 and add our own attributes and methods to it. 125 00:07:51,000 --> 00:07:56,000 So the first thing we want to do is tell the note model how we want it to save itself. 126 00:07:56,000 --> 00:08:00,000 In typical Backbone applications, this might be specifying a URL 127 00:08:00,000 --> 00:08:05,000 that you can post and read from in order to update and retrieve information. 128 00:08:05,000 --> 00:08:08,000 However, we're not using an external server. 129 00:08:08,000 --> 00:08:12,000 Instead, we're using localStorage, so we're going to tell it for all of our Notes, 130 00:08:12,000 --> 00:08:18,000 we want to use the app.store.notes datastore in order to persist the information. 131 00:08:18,000 --> 00:08:22,000 And to do that, all we need to do is add the localStorage attribute 132 00:08:22,000 --> 00:08:27,000 to our backbone model and give it the actual instance of our data store; 133 00:08:27,000 --> 00:08:30,000 in our case, this App.stores.notes. 134 00:08:30,000 --> 00:08:35,000 Now you can see why we needed to instantiate our App.store.notes 135 00:08:35,000 --> 00:08:39,000 before we defined our model because this code will be executed right away 136 00:08:39,000 --> 00:08:42,000 and we need to make sure that this instance is available. 137 00:08:42,000 --> 00:08:48,000 So that's why we initialized our store before we did anything else. 138 00:08:48,000 --> 00:08:53,000 So another thing that we can define in our extend object here is methods. 139 00:08:53,000 --> 00:08:59,000 Now, there's a special method called initialize, which is called sort of like a constructor, 140 00:08:59,000 --> 00:09:03,000 and this will be called any time we instantiate a new note object. 141 00:09:03,000 --> 00:09:05,000 Now, it's optional for us to create this. 142 00:09:05,000 --> 00:09:08,000 The intializer is great for things like initializing default values 143 00:09:08,000 --> 00:09:10,000 or running any other logic 144 00:09:10,000 --> 00:09:13,000 that needs to be run when we initialize a new note. 145 00:09:13,000 --> 00:09:18,000 So what we're going to do is create an initialize method 146 00:09:18,000 --> 00:09:22,000 and we do that by defining initialize as the function(){ 147 00:09:22,000 --> 00:09:30,000 and the initialize function will actually receive any arguments passed to the note constructor. 148 00:09:30,000 --> 00:09:34,000 Right now, we don't want to really capture any of those, 149 00:09:34,000 --> 00:09:37,000 but we could if we needed to. 150 00:09:37,000 --> 00:09:40,000 Now, when I set up my initializer, really want I want to do 151 00:09:40,000 --> 00:09:43,000 is see if the title or body attributes have not been set, 152 00:09:43,000 --> 00:09:48,000 and if they've not been set, I want to go ahead and set default values. 153 00:09:48,000 --> 00:09:52,000 Now, we can set defaults in another way by defining a defaults attribute 154 00:09:52,000 --> 00:09:57,000 in this, but the defaults that I want are a little more dynamic 155 00:09:57,000 --> 00:10:02,000 so I'm going to set them in the initializer if they're not set by the user. 156 00:10:02,000 --> 00:10:06,000 The first thing I want to check is if there's no title, so I'm going to use an if statement 157 00:10:06,000 --> 00:10:11,000 and what I want to check is to see if there is no title set. 158 00:10:11,000 --> 00:10:14,000 Now, in order to get attributes from a note, 159 00:10:14,000 --> 00:10:16,000 I'm going to use the get method 160 00:10:16,000 --> 00:10:19,000 and pass it the name of the attribute I want to get. 161 00:10:19,000 --> 00:10:23,000 So what I can do is do (this.get( 162 00:10:23,000 --> 00:10:28,000 and pass "title")) and that's how I would always retrieve the title attribute from my note. 163 00:10:28,000 --> 00:10:32,000 Now, I want to check if it's non-existent, so I'm going to check as a negative 164 00:10:32,000 --> 00:10:38,000 so that if this title does not exist, then I want to set the value, 165 00:10:38,000 --> 00:10:42,000 and the way I set values or set attributes is the set method. 166 00:10:42,000 --> 00:10:45,000 I use it like this: this.set. 167 00:10:45,000 --> 00:10:48,000 Now, one thing that's easy to get tripped up on 168 00:10:48,000 --> 00:10:50,000 is you may expect set to take two arguments-- 169 00:10:50,000 --> 00:10:54,000 the first being the name of the attribute and the second being the value-- 170 00:10:54,000 --> 00:10:57,000 but the way set actually works is it takes a JavaScript object 171 00:10:57,000 --> 00:11:00,000 with keys and values, so even if you're setting one thing, 172 00:11:00,000 --> 00:11:04,000 you need to use the object notation in order to do it. 173 00:11:04,000 --> 00:11:07,000 It's very confusing if you've missed that part of the documentation. 174 00:11:07,000 --> 00:11:11,000 So in order to set the title, I'm going to create a JavaScript object. 175 00:11:11,000 --> 00:11:14,000 Its key is going to be {title: 176 00:11:14,000 --> 00:11:17,000 and its value is what we want our default value to be, 177 00:11:17,000 --> 00:11:20,000 so in our case, I'm going to create a string, 178 00:11:20,000 --> 00:11:23,000 so we'll say "Note @ " 179 00:11:23,000 --> 00:11:30,000 and let's add a date stamp to it + Date, so I'm just going to call Date() }) here 180 00:11:30,000 --> 00:11:38,000 and this will create a string of Note @ and then some sort of time stamp. 181 00:11:38,000 --> 00:11:41,000 Now, I also want to set a default value for our body 182 00:11:41,000 --> 00:11:44,000 so we can see that there is no content in it, 183 00:11:44,000 --> 00:11:47,000 and I'm going to do this much the same way. 184 00:11:47,000 --> 00:11:48,000 In fact, I'll just paste this piece of code here 185 00:11:48,000 --> 00:11:52,000 and we can see that I check if there's no body attribute, 186 00:11:52,000 --> 00:11:56,000 I'm just going to set the body to the string "No Content"}). 187 00:11:56,000 --> 00:12:00,000 So now we've seen how to get and retreive variables 188 00:12:00,000 --> 00:12:03,000 and how to set default values. 189 00:12:03,000 --> 00:12:06,000 This is all we need to define for our note right now. 190 00:12:06,000 --> 00:12:09,000 Later on, we're going to be adding some other methods; 191 00:12:09,000 --> 00:12:14,000 for instance, getting the geolocation information and some other nice utility functions, 192 00:12:14,000 --> 00:12:16,000 but right now, that's really all we need from our note. 193 00:12:16,000 --> 00:12:20,000 It's basically just and object that stores a value. 194 00:12:20,000 --> 00:12:24,000 Now, it's going to be a few steps before we actually create our note 195 00:12:24,000 --> 00:12:28,000 and see how it works, so what I'm going to do is I'm going to use the JavaScript console 196 00:12:28,000 --> 00:12:31,000 in Chrome to sort of play around with this note API. 197 00:12:31,000 --> 00:12:37,000 Right now, this note is sort of scoped locally so we can't actually access it 198 00:12:37,000 --> 00:12:43,000 from our console, so what I'm going to do here is temporarily say: 199 00:12:43,000 --> 00:12:48,000 window.Note = Note; 200 00:12:48,000 --> 00:12:53,000 and this will make the global variable Note equal to our model. 201 00:12:53,000 --> 00:12:56,000 So if we go back and refresh, we see we don't have any errors 202 00:12:56,000 --> 00:13:01,000 and I'm just going to switch over to our console to get a much better view. 203 00:13:01,000 --> 00:13:05,000 And so, we can see our Note is just a model, 204 00:13:05,000 --> 00:13:12,000 so what we can do is say note = new Note 205 00:13:12,000 --> 00:13:14,000 and we get our object back. 206 00:13:14,000 --> 00:13:21,000 And what we can see is we can use note.get and pass it "title" 207 00:13:21,000 --> 00:13:24,000 and we can see that our initializer actually worked. 208 00:13:24,000 --> 00:13:29,000 We got note@ Mon Mar 14 and so on. 209 00:13:29,000 --> 00:13:36,000 We could do note.get ("body"); 210 00:13:36,000 --> 00:13:38,000 and we can see "No Content." 211 00:13:38,000 --> 00:13:48,000 We could do note.set (title: "My Title")} 212 00:13:48,000 --> 00:13:52,000 and then we can get the title again and see that it works. 213 00:13:52,000 --> 00:13:55,000 I'm going to clear out the console here so we can see it again, 214 00:13:55,000 --> 00:13:58,000 and now while our note object is storing values fine, 215 00:13:58,000 --> 00:14:00,000 let's see how it works on persisting. 216 00:14:00,000 --> 00:14:03,000 Now, what we need to do is simply call save on it 217 00:14:03,000 --> 00:14:06,000 and what it should do is it should use its localStorage attribute, 218 00:14:06,000 --> 00:14:10,000 which is the data store, and save itself in to that data store. 219 00:14:10,000 --> 00:14:14,000 So we could do note.save-- 220 00:14:14,000 --> 00:14:19,000 So it looks like there's a problem with the code that we initially downloaded for our app. 221 00:14:19,000 --> 00:14:22,000 Problems like this can happen in real development situations, 222 00:14:22,000 --> 00:14:26,000 and we could have tried to edit out every little problem that we encounter while developing, 223 00:14:26,000 --> 00:14:31,000 but I think it's important to see the real problems and how they're solved. 224 00:14:31,000 --> 00:14:35,000 Now, there was a change in how Backbone saves its data. 225 00:14:35,000 --> 00:14:37,000 The localStorage adapter had already been updated 226 00:14:37,000 --> 00:14:40,000 to reflect the change in how Backbone works. 227 00:14:40,000 --> 00:14:43,000 However, the stable version of Backbone had not been released, 228 00:14:43,000 --> 00:14:47,000 so our Backbone localStorage adapter is incompatible 229 00:14:47,000 --> 00:14:49,000 with the version of Backbone we're using. 230 00:14:49,000 --> 00:14:53,000 Now, this is easy to work around: we just need to get a slightly older version 231 00:14:53,000 --> 00:14:55,000 of the localStorage adapter. 232 00:14:55,000 --> 00:14:59,000 By the time this video was released, the Backbone localStorage and Backbone 233 00:14:59,000 --> 00:15:01,000 may be in sync. 234 00:15:01,000 --> 00:15:03,000 However, at the time that we filmed this, they're not. 235 00:15:03,000 --> 00:15:07,000 The compatibie localStorage adapter file is included with the project code 236 00:15:07,000 --> 00:15:09,000 available with this video. 237 00:15:09,000 --> 00:15:14,000 So let's replace the incompatible code with the compatible localStorage code. 238 00:15:14,000 --> 00:15:18,000 So what I'm going to do is I'm going to make sure that the original version 239 00:15:18,000 --> 00:15:23,000 of our Backbone localStorage that I'm about replace it with is in our code, 240 00:15:23,000 --> 00:15:26,000 so what I'm going to do is I have a version that I got 241 00:15:26,000 --> 00:15:31,000 and I'm going to paste it into our Backbone localStorage file. 242 00:15:31,000 --> 00:15:35,000 So switching over to our code, 243 00:15:35,000 --> 00:15:38,000 the Backbone.localStorage file, 244 00:15:38,000 --> 00:15:44,000 there are some changes here; you can see it has options.success. 245 00:15:44,000 --> 00:15:46,000 Now, that's not going to work with our version of Backbone 246 00:15:46,000 --> 00:15:50,000 so what I'm going to do is I'm going to replace this with our version, 247 00:15:50,000 --> 00:15:53,000 and I'm going to make sure that the code has the correct version here 248 00:15:53,000 --> 00:15:57,000 and you can tell it's the correct version because it says success with response (resp); 249 00:15:57,000 --> 00:16:00,000 instead of options.success. 250 00:16:00,000 --> 00:16:05,000 So I'm going to save this out and I'm also going to take our minified version of it 251 00:16:05,000 --> 00:16:07,000 and right now, I'm just going to remove the selected file. 252 00:16:07,000 --> 00:16:10,000 That means I'm going to delete it from our project 253 00:16:10,000 --> 00:16:14,000 and that's because it's the compressed version of the wrong version 254 00:16:14,000 --> 00:16:16,000 of our Backbone localStorage. 255 00:16:16,000 --> 00:16:19,000 Now, we can compress it later and create our own minified version, 256 00:16:19,000 --> 00:16:23,000 but this should work for now, so now we should have a working version 257 00:16:23,000 --> 00:16:29,000 of our Backbone localStorage adapter, and let's go ahead and refresh. 258 00:16:29,000 --> 00:16:33,000 Okay, so it looks like we have an unexpected token illegal 259 00:16:33,000 --> 00:16:36,000 on Backbone.localstorage.js on line 20. 260 00:16:36,000 --> 00:16:41,000 So--I wasn't getting this in my original one--let me just remove this code 261 00:16:41,000 --> 00:16:44,000 and see if we can track down this error. 262 00:16:44,000 --> 00:16:47,000 It's somewhere in those three lines of code, 263 00:16:47,000 --> 00:16:50,000 so we take a look and we see this.name = name; 264 00:16:50,000 --> 00:16:52,000 I don't see any problem there. 265 00:16:52,000 --> 00:16:57,000 We see var Store = localStorage.getItem(this.name); 266 00:16:57,000 --> 00:17:04,000 And then, this.data = (store && JSON.parse(store)) 267 00:17:04,000 --> 00:17:06,000 or an empty variable {};. 268 00:17:06,000 --> 00:17:11,000 It looks like the problem might be on this line, so let me remove that and refresh it. 269 00:17:11,000 --> 00:17:14,000 So what is wrong with this line? 270 00:17:14,000 --> 00:17:17,000 Okay, so I've looked at the code and it looks like we're erroring out 271 00:17:17,000 --> 00:17:22,000 on this particular part right here--this JSON.parse and this (store). 272 00:17:22,000 --> 00:17:26,000 And so what we can see is happening in here is it's getting the localStorage 273 00:17:26,000 --> 00:17:34,000 and coded data for the (store), in our case, notes. 274 00:17:34,000 --> 00:17:40,000 What happens if we call JSON.parse is we get syntax, unexpected token, illegal, 275 00:17:40,000 --> 00:17:43,000 and that doesn't mean our code has an unexpected token. 276 00:17:43,000 --> 00:17:47,000 That means the actual JSON.parse retreived bad code. 277 00:17:47,000 --> 00:17:50,000 Now, the reason I think this might be happening 278 00:17:50,000 --> 00:17:53,000 is that we might have loaded the wrong code, 279 00:17:53,000 --> 00:17:58,000 and so whatever is stored in our storage under Notes is probably wrong, 280 00:17:58,000 --> 00:18:02,000 which is cool; we can actually look into this using the Chrome Developers Tools. 281 00:18:02,000 --> 00:18:07,000 I'm going to open up the Resources tab and actually close out our console here, 282 00:18:07,000 --> 00:18:10,000 and we can look directly into our localStorage. 283 00:18:10,000 --> 00:18:14,000 So our localStorage for localHost has notes 284 00:18:14,000 --> 00:18:18,000 and looks like it also has notes for particular pieces 285 00:18:18,000 --> 00:18:21,000 saved using their own id. 286 00:18:21,000 --> 00:18:26,000 This might actually be wrong because the way I've seen my code when I was developing it, 287 00:18:26,000 --> 00:18:32,000 all of the data was actually stored inside of the Notes key 288 00:18:32,000 --> 00:18:34,000 as an encoded JSON string. 289 00:18:34,000 --> 00:18:37,000 So it looks like the two different versions I tried were incompatible, 290 00:18:37,000 --> 00:18:43,000 so I saved with the old version and I'm trying to retrieve with the new version, which is wrong. 291 00:18:43,000 --> 00:18:46,000 So what I'm going to do is actually clear this out 292 00:18:46,000 --> 00:18:51,000 so we can start from scratch and hopefully, now that I'm using a single version, 293 00:18:51,000 --> 00:18:55,000 I'm not going to get errors when I'm transferring from one version of our localStorage code 294 00:18:55,000 --> 00:18:56,000 to the other. 295 00:18:56,000 --> 00:19:01,000 So I've now cleaned those out by using this simple delete button here. 296 00:19:01,000 --> 00:19:04,000 Another way we could do it is from our console, 297 00:19:04,000 --> 00:19:11,000 we could just call localStorage--which is our browser object for localStorage--.clear, 298 00:19:11,000 --> 00:19:17,000 and this will clear out any localStorage data for this domain. 299 00:19:17,000 --> 00:19:19,000 So we should be good. 300 00:19:19,000 --> 00:19:21,000 Now, if we refresh, 301 00:19:21,000 --> 00:19:24,000 I'm just going to create a New Note. 302 00:19:24,000 --> 00:19:33,000 Let's go ahead set the title of my note. 303 00:19:33,000 --> 00:19:38,000 Again, we can do note.get_title to see if that worked. 304 00:19:38,000 --> 00:19:40,000 Awesome. 305 00:19:40,000 --> 00:19:44,000 So finally, let's do note.save, 306 00:19:44,000 --> 00:19:48,000 and it looks like it returns our note. 307 00:19:48,000 --> 00:19:52,000 If we go back to our localStorage here and refresh it, 308 00:19:52,000 --> 00:19:56,000 we can see that our localStorage now has a key of notes 309 00:19:56,000 --> 00:19:59,000 and an object here, which is serializing our note object 310 00:19:59,000 --> 00:20:01,000 and giving it a unique id. 311 00:20:01,000 --> 00:20:06,000 These unique ids are generated randomly and will uniquely identify each note 312 00:20:06,000 --> 00:20:08,000 in our database. 313 00:20:08,000 --> 00:20:15,000 So the key is our note id and the value is a JSON-encoded representation of our note. 314 00:20:15,000 --> 00:20:20,000 So even if we refresh the page, we can see that our data is still stored in the database 315 00:20:20,000 --> 00:20:22,000 and we should be able to get our notes out. 316 00:20:22,000 --> 00:20:25,000 We'll look at how we can actually retrieve our notes 317 00:20:25,000 --> 00:20:27,000 when we take a look at collections next.