-
SHORTY: So we have a form.
-
We can see it.
-
It's right here.
-
For those of you watching the videos,
-
we did a couple of things the CSS
-
while we weren't recording,
-
which moved this inside a little bit.
-
We added actual padding to the body
-
because it looks better.
-
And then we made a page title class
-
which we can apply to h3s everywhere...
-
That give us a little page title, right?
-
We can use an h3 in our views
-
to let us know what's going on
-
on this page.
-
But outside of that,
-
this is it.
-
This is 100% of what we're about to do.
-
We need to now post.
-
Right, so we type some things.
-
And we hit "post it."
-
And we hang.
-
Right?
-
And why did we hang?
-
Well, we hang 'cause we're going
-
inside of our post controller to...?
-
To create.
-
And so theoretically we want to
-
create a post.
-
But we don't have any way
-
to talk to our database, do we?
-
We haven't done that yet.
-
Now what do we want to use?
-
We want to use mongoose.
-
Mongoose is the new sexy, right?
-
So we want to use our new
-
mongoose skills,
-
which means that we need to create a...
-
schema, right?
-
And we need to use that.
-
So how do we do that?
-
How are we going to do it? Well...
-
STUDENT: We need to require?
-
SHORTY: We're going to require post js
-
in our models folder,
-
which is going to have information
-
about our schema and our post object,
-
and a way to talk to, right,
-
the actual database.
-
So we're going to put our schema in here.
-
And we're going to create the model
-
that will actually connect to the database
-
for us in here.
-
And then we are going to module.exports
-
the model.
-
And then everywhere we want to use
-
posts, we just require it.
-
And if we don't require it,
-
we're not using posts.
-
Does that sound nice?
-
STUDENT: Okay. So is it post.js, or posts.js?
-
SHORTY: Ah! That's a great question.
-
Model names are singular.
-
Controller names are plural.
-
STUDENT: Okay.
-
SHORTY: View folder names are plural.
-
This is a structure that you will get used to
-
in time.
-
It is much like restful routing.
-
There has been decisions made
-
by the universe, without your permission
-
as how we should name things.
-
You are too late to the party
-
to change it.
-
So you should accept it,
-
and go with the flow
-
that way everybody around you is happy.
-
So in here, what do we need to do?
-
We actually need to secretly go back
-
to our server.js, and require some of this stuff,
-
don't we?
-
We're going to need, at the very least,
-
mongoose and the mongoose.Schema,
-
yeah?
-
And in some sense, at the very most.
-
This is the entirety of what we need in here.
-
Inside our -- go away -- here.
-
Of our mongoose.
-
Schema.
-
And now what?
-
Var postSchema =
-
schema... I think we can even do it
-
without new.
-
I think we can just -- anything you pass
-
into the Schema will be the same as
-
having called new Schema.
-
'Cause I think what we're going to do next
-
is var Post = mongoose.model,
-
Post, comma, postSchema, right?
-
And then we'll do module.exports = Post.
-
And now, any time we require models post,
-
it will return to us, the Post object
-
so we can now do things like
-
post.find anywhere,
-
post.delete,
-
post.this,
-
post.whatever.
-
Yes? What?
-
MATT: Can you remove schema and add a [additional?] server [inaudible]...?
-
SHORTY: Yeah, I don't think we need it there anymore.
-
Yeah, as long as none of the routes
-
defined there actually need anything.
-
So Matt's absolutely right.
-
Since we're never going to use mongoose
-
during the course of this server.js file...
-
Oh, shoot.
-
We can get rid of the schema.
-
But we do need mongoose because we still
-
are running mongoose.connect.
-
We don't need schema in there.
-
That's fine.
-
That was a good thought.
-
And I forgot that we had to connect
-
to the database.
-
So yeah...
-
So inside post,
-
what should our posts be made up of?
-
We already said the three things.
-
They're in our form.
-
Author, which it is a what?
-
STUDENT: By line?
-
STUDENT: String.
-
SHORTY: String? By line? What did I call it there?
-
No, that is the author.
-
By line is the author.
-
Title is a string.
-
And content,
-
is a string.
-
Now these are -- this is an
-
unfancy schema, right?
-
I have not specified anything is required.
-
I have not specified anything is
-
unique, or anything like that.
-
It would be kind of weird to have
-
anything in this to be unique.
-
Each author can have one post, right?
-
If you try to post under the
-
same author name twice,
-
you're going to have to start
-
adding the third, the fourth, the fifth.
-
The same title.
-
Everybody's going to like, do something about
-
their trip to New York or whatever, right?
-
And content being unique, while nice
-
for the readers is not necessary, right?
-
Are we good?
-
So far we have our postSchema,
-
and then we have our post model.
-
And then we export the post model.
-
That's it.
-
Now anywhere we require this,
-
we can use it.
-
So where should we probably
-
require it?
-
Inside the post, right?
-
It was the controller.
-
Inside the post controller, right?
-
Theoretically in here,
-
we're going to want to actually
-
access the database.
-
Here's where things get hairy.
-
I think I want to do this.
-
I think.
-
STUDENT: They're models.
-
SHORTY: Oh, yeah, I'm sorry.
-
I'm just --
-
Ah, shoot.
-
I want to import the post model, right?
-
If I don't have this, how am I
-
going to do anything?
-
Watch.
-
What?
-
New Post, req.body dot...?
-
All right, let go back and
-
look at the form again.
-
Everything is inside what name space?
-
STUDENT: Post.
-
SHORTY: Post. So it's gonna --
-
when body-parser does our parsing,
-
what's going to happen?
-
STUDENT: It's going to pull all the data
-
from the code into the post object?
-
SHORTY: Yup. And it's going to put it in an object whose...
-
So inside req.body, we're going to have a
-
top-level attribute called post.
-
And then it's going to have three attributes,
-
which are author, title, and content.
-
So to get to it, I need to .post.
-
So here, req.body.post.
-
Console.log(newPost).
-
This is going to let us know
-
something happened.
-
Now let's go back and look at my schema.
-
I want to make sure I get author, title, content.
-
Author, title, content.
-
That's really important, right?
-
It's going to flail about
-
if it's not matching.
-
STUDENT: Do they have to be in the same order?
-
SHORTY: No, absolutely not.
-
These are just named properties.
-
Objects don't care.
-
They're not arrays.
-
They're in almost like arrays
-
but they're not arrays.
-
Yes?
-
STUDENT: In the object where it says post
-
that's where it would create questionable posts?
-
SHORTY: Yes. Yes.
-
STUDENT: So I was -- I got most of it working last night
-
but if you put a number, or maybe more like a string
-
in something that you define as a number,
-
would it wig out a little?
-
SHORTY: It does wig out.
-
It will throws errors, won't it?
-
STUDENT: Right, yeah. Because I didn't do too much testing on
-
what it was storing or anything.
-
SHORTY: Yeah, so you might want to do is
-
in your form, actually specify that it's
-
a number field.
-
And it will serialize as a number.
-
How are we doing?
-
This is super simple at this point, right?
-
So all I'm doing is I'm importing
-
the ability to access the database
-
and make posts.
-
I'm using the mongoose model as a
-
way to do that.
-
When this form submits,
-
it should fire off into the post
-
controller in here.
-
It should use the post, which I required
-
and make a new one,
-
and then just log it.
-
This is intense.
-
Start everything up.
-
Nothing broke yet.
-
But I haven't hit a thing yet.
-
God, I'm so happy with this form!
-
STUDENT: Aww!
-
STUDENT: Yay!
-
SHORTY: Oh-ho-ho!
-
Is it there?
-
STUDENT: Yes.
-
SHORTY: How happy are you on a scale
-
of 1-5?
-
STUDENT: Ten.
-
SHORTY: Oh, 10?
-
I like 10.
-
That's pretty cool, right?
-
Everything works the way we want it
-
to work.
-
So now, let's not just make the model
-
let's also...
-
STUDENT: Store it?
-
SHORTY: Store it, which is --
-
we save it, right?
-
So newPost = new Post.
-
NewPost.save, which then takes a
-
callback function, which gives us
-
an error and the post itself, right?
-
So when you call methods like
-
save, or delete, or whatever,
-
usually they have a callback function
-
that gets executed after the
-
database is done.
-
And the reason is, because you don't want to
-
keep doing things while you're waiting
-
for the database to finish, right?
-
You're like, hey, database, make a bunch of
-
changes and now I'm going to ask you for some
-
things in the meanwhile.
-
That's really bad.
-
We want to, like, kind of close down
-
access to the database
-
until this finishes.
-
So we're going to save it.
-
It's going to take a callback function.
-
Mongo callback functions are almost exclusively,
-
error something.
-
So we could do something like this.
-
If error, and run some code.
-
Log the error.
-
That seems like useful stuff, right?
-
Else...
-
Okay. So now, if there wasn't an error,
-
and the post saved correctly,
-
what should we do?
-
STUDENT: Console.log?
-
STUDENT: Maybe say success?
-
SHORTY: Maybe say success.
-
What actually is a useful success function here?
-
Let's do something to the response, right?
-
STUDENT: Render it.
-
SHORTY: Res.render. No... remember
-
inside the actions that tickle the database,
-
we actually want to always...?
-
It rhymes with "she direct."
-
STUDENT: Redirect?
-
SHORTY: Rediresct. Res.redirect to somewhere.
-
I don't know where yet.
-
Let's just redirect back to new.
-
Okay?
-
Here, again, this doesn't know
-
anything about the agreement with the
-
router.
-
So we gotta give it a full path.
-
The agreement with the router
-
only gives us shortcuts to these
-
router.get strings.
-
Okay?
-
Everywhere else we have to use
-
full strings.
-
I have no idea.
-
For some reason, I have this weird thing
-
where I use double quotes,
-
whenever it's the second thing.
-
I don't know why.
-
It's really weird.
-
Always --
-
I can't stop myself.
-
So there's a philosophy in quoted strings
-
where you use single quotes when they're
-
only being used internally.
-
And you use double quotes to indicate
-
it's going to go to the user somehow.
-
STUDENT: That's cool.
-
SHORTY: It's a philosophy.
-
It doesn't really matter.
-
As it turns out,
-
it doesn't matter.
-
Not even a little bit.
-
But I like that philosophy.
-
I like that separation.
-
It makes sense to me.
-
STUDENT: Wait, what is it again?
-
SHORTY: Double quotes are when you're
-
talking to the user.
-
So any string which is going to be used
-
to eventually be sent back to the user,
-
put that in double quotes.
-
Anything which is only ever going to be
-
used internally, put single quotes.
-
It's like a nice idea on when you're like, oh, shoot, this stuff's
-
going back, I have to make sure it's okay.
-
whereas this is never seen by the user.
-
And then we get into philosophical discussions...
-
since it's rerouting, is that really
-
seen by the user?
-
Let's ignore that.
-
Right?
-
So let's kill that.
-
Oh, man.
-
I'm so nervous.
-
Start it up.
-
Go back to posts/new.
-
I'm just going to hit post.
-
Boop, we went back to posts/new.
-
Which meant two things.
-
One, the error didn't happen.
-
Which probably means, now, in our database
-
there's a...?
-
STUDENT: Post.
-
SHORTY: Post! Post.save fired off, right?
-
That's great.
-
What?
-
STUDENT: Okay. I think this is more of an
-
advanced question but, like, in real life,
-
when you do a post, there's a lag
-
between your post and to the database
-
and then you go back to the new page, right?
-
Is there only --
-
is it our jobs as developers to set up that lag?
-
SHORTY: Why would you want a lag?
-
STUDENT: Yeah, that's not --
-
SHORTY: Yeah, that's just a matter of
-
it taking a long time to reget, whatever's
-
going to be rendered on the --
-
at this point our database is so small,
-
there's exactly one entry,
-
that we don't have to worry about it.
-
STUDENT: [Inaudible]?
-
SHORTY: No, 'cause I've only saved once.
-
The first time, I didn't save.
-
STUDENT: Oh.
-
SHORTY: I just logged.
-
STUDENT: We don't need to implement a code
-
for the lagging?
-
SHORTY: Absolutely not.
-
All right.
-
So let's make our index page because that's
-
really where we want to go, right?
-
STUDENT: I use create to do that.
-
SHORTY: Create is new plus save simultaneously.
-
Same thing. I personally prefer doing new
-
separate from save.
-
STUDENT: Yeah, well, create I -- [Inaudible].
-
SHORTY: Yes. I think that that's fine.
-
But I actually really like separating the two.
-
I like making the new thing.
-
And then saving the thing separately.
-
That's just the way I've always done it.
-
That's --
-
STUDENT: I thought, I mean, I was just talking
-
if you were in an array, I was just trying to
-
just get it to work.
-
MATT: Yeah. So this, I mean, this is totally
-
a preferential thing.
-
How you've done it from with day one
-
or if you do it Matt's way,
-
the only difference that I notice
-
is that you can't pass in an array to create.
-
So if you have multiple objects,
-
it will go through and create them all.
-
SHORTY: That you want to do new or in create?
-
MATT: Do create if you want to pass in.
-
SHORTY: Ah, so you were trying to create
-
multiple things.
-
MATT: Yeah, but that's the only difference...
-
SHORTY: I see. That makes sense a lot of sense.
-
STUDENT: All right. Makes more sense.
-
SHORTY: So we're kind of at the point
-
where eventually I will release you
-
to the universe.
-
I don't think we have to build out everything.
-
But do you guys see where
-
mongoose goes?
-
Do you see how to compartmentalize
-
our application?
-
Our application actually now has things
-
in really nice subdirectories where they're
-
only being used when we need them.
-
Does that make a lot of sense?
-
Yes?
-
Let's do our index.
-
So now, we're going to want to
-
post dot... it rhymes with "mind."
-
STUDENT: Find.
-
SHORTY: Find. And what are we going to find?
-
Everything, right?
-
And that gets a callback function, which
-
gets an error, and...?
-
The collection of stuff.
-
The whole collection.
-
Whatever we've found.
-
Why don't we call that posts?
-
Is anybody weirded out by my
-
choice of variable name?
-
All right. That's just where the array of
-
post is going to go.
-
And in here, if err, log err.
-
Otherwise -- and this is very
-
common behavior.
-
Check to see if there's an error.
-
If there is, don't progress.
-
Just stop.
-
And if there isn't an error,
-
then do the required behavior.
-
Else...
-
we probably want to render something, right?
-
Res.render('posts/index')
-
and we should pass it what object?
-
STUDENT: Post object?
-
SHORTY: Ah! That's a real good question.
-
Maybe?
-
Posts is probably what type of object?
-
KRISTYN: So it's just the array that we're going to be...?
-
SHORTY: Posts is actually an array, isn't it?
-
STUDENT: So the client or user --
-
PostsArray...
-
Because it is an array,
-
right?
-
when we use find, it gets a collection of stuff.
-
A collection's default container is a...?
-
Array.
-
When we want to store a bunch of things
-
that are all the same kind of thing,
-
we put them in an array, right?
-
An array is an box that can store things.
-
An object requires named properties.
-
If I get back 20 posts,
-
what's going to be the name for each post,
-
if I've stored it in an object?
-
I don't know.
-
There wouldn't be one.
-
So let's call this posts array.
-
So we know what Matt's about to do
-
isn't insane.
-
I need to make a literal object
-
where the posts are the postsArray.
-
So now inside my ejs file,
-
posts is now a variable.
-
and it points to the array of posts.
-
As we want it to.
-
So remember, often, you'll have to create
-
an object on the spot
-
when you're rendering.
-
That actually has the name you care to use
-
pointing at the actual stop.
-
Does that make sense?
-
I feel like I'm almost at the edge
-
of your ability to pay attention at this point.
-
So let's wrap up
-
and actually render an index page.
-
So for now, this isn't going to do anything, is it?
-
Oh, also...
-
Let's redirect to posts instead of post new.
-
So we can just see the list of
-
all posts, yes?
-
Sarah!
-
Welcome to our recording.
-
How many staircases do we have?
-
Not too many yet, right?
-
STUDENT: Three?
-
SHORTY: Yeah. One, two, three steps?
-
So you're up -- I don't know.
-
You're up on the third-floor landing.
-
It's awful.
-
It's a walk-up.
-
We need to make our index file, right?
-
So in here, we have access to a
-
thing called...
-
Posts, right?
-
Dot, it's an array, forEach,
-
takes a callback function,
-
which grabs a post,
-
and its index.
-
And then we gotta wrap all this
-
nonsense in clown hats.
-
Scary clown hats.
-
So far so good, right?
-
KRISTYN: Is this all going into the body?
-
SHORTY: Yes.
-
KRISTYN: Do you have to do anything to get
-
it to recognize this ejs file or...?
-
SHORTY: So when I call inside my post controller,
-
render(posts/index),
-
it's going to go into posts/index.ejs
-
it's going to run this code.
-
It will finish compiling this.
-
And it will treat it like this text.
-
It makes, like, a string, right?
-
It then takes that string,
-
goes into layout.ejs,
-
and then puts it right here.
-
So why don't we add our h3
-
class = "title."
-
Ah, shoot.
-
Page title.
-
All the posts.
-
Does that sound good?
-
And we're going to iterate over the
-
post collection and render them.
-
Yeah?
-
Let's put them in, I don't know,
-
a div whose class is post.
-
So I can style it.
-
And then in there, have a header.
-
Which is the post title.
-
And then, in a small tag...
-
we'll have, like, by...
-
STUDENT: Put something.
-
SHORTY: Yeah, by...
-
Post_author.
-
And then end my small tag.
-
And end my h4.
-
And then here, in a paragraph,
-
we'll put the post.content.
-
And my paragraph tag.
-
Who feels that this is making sense --
-
the way that we're doing this, right?
-
Now, in some sense, this is a repeatable thing.
-
maybe later in a different part of our application
-
we're also going to want to render
-
our post.
-
Like, for example, in show.
-
If you're going to render it the same way
-
in both, in some sense, this can be
-
pushed into yet another
-
ejs file, which we call a partial.
-
A partial is just a part of a page
-
which is going to be used in
-
multiple places.
-
Really, what's the difference between the
-
new post form and the edit post form?
-
STUDENT: The existence of content?
-
SHORTY: The existence of values, right?
-
Those two forms can be encapsulated also
-
into a partial and things like that.
-
So what we want to do is we want to think about
-
every time we're doing something,
-
how can I do this just a little bit better?
-
How can I reuse things more often?
-
But for now this is good.
-
I don't really care.
-
We're just going to have a bunch of divs
-
with our posts.
-
Let's go quickly style that.
-
I want the post div to be --
-
to have a border.
-
I want that border to have a
-
little bit of a radius.
-
Right, be a little curved.
-
I want it to have some padding of an
-
em, so the post -- everything appears inside of it.
-
And that's just going wrap around my posts
-
and that's all I'm going to do.
-
That's the entirety of my styling.
-
Does that sound good for now?
-
STUDENT: Mm-hmm.
-
SHORTY: Okay. That way -- oh, maybe I want
-
everyone -- so maybe I want, like, a
-
post plus a post to have a margin top.
-
So do you guys remember how
-
this works?
-
If you have anything plus anything,
-
they have to be siblings of each other,
-
which means they have to be
-
at the same level in your dom tree
-
so we're going to render, like, 30 posts, right?
-
I want any post, which has a post before it
-
to have a little margin above it.
-
That way the two posts
-
aren't kissing each other.
-
Like that.
-
So this is everything but the first post
-
is going to get a top margin.
-
And does that make sense why
-
we don't want the top one to have?
-
It should just be at the top.
-
All right.
-
We're almost done.
-
Let's restart our server.
-
Well, let's just make another new post.
-
That way we'll have two to show, right?
-
Who's the author name on this post?
-
STUDENT: Jerry.
-
SHORTY: Jerry, what's your title of your post?
-
STUDENT: Hello.
-
SHORTY: Hello. What's up, Jerry?
-
Remember, you care.
-
STUDENT: I did not get my pizza yet.
-
SHORTY: I did not get my pizza yet.
-
Post it.
-
And here is all of our posts.
-
Who is excited?
-
[ Applause ]
-
All right!
-
We have a perfectly functional --
-
well, we have a boring website.
-
There's still not all of the
-
functionality.
-
But I'm going to leave that to you.
-
I really want to stop here.
-
So let me stop this.