Good morning, everyone.
So, uh.
today i just uh
My agenda for today is I want to
I want to talk about any questions you all have about assignment two. I'm happy to go through that.
solutions we'll discuss on Thursday.
And…
So just to recall, assignment two is due
Tomorrow evening.
But I'll accept it until just before class on Thursday.
But really should get it done tomorrow night.
And then…
So the midterm is on October 29th.
So it's Tuesday after the break
that will be…
So just in terms of like how the midterm will go.
It's Tuesday after the break.
It's through an assignment on Brightspace. I'll say, you know, be under a separate section that'll be exams and we'll say midterm, but the format
exactly the same as assignments, i.e.
you'll just submit a text file in exactly the same format.
as you did for the assignments.
That's part of the, so I try to keep things uniform.
I'll post a PDF on Brightspace.
So I'll have to figure out exactly the logistics of people who can't take it during class time because there's a second section and some people have conflicts, but I'm
hoping most people can take it during the class time.
So any question about the midterm, let me know but that's
kind of where we're heading right now because
you know this tuesday and thursday and then there's the break and then there's the midterm
So unless there's anything else, one thing I should mention um
TAs to hopefully get A1 and A2 graded before the midterm.
But it probably will be done by Thursday.
Of course.
So what I'm saying here is
If you look at my solutions.
for um
So you know um
I'm saying things, I actually give descriptions in my solutions about ways you could verify it.
I expect you to give something like that when you're talking about these verifications in assignment two.
If you have a question where
like the support sim the support serving PDS, how do you verify that your answer was correct
If you're saying things like.
if you're saying things like, oh, I can just
I looked at the code and that's what it's doing.
like that's not
enough. And in particular, like.
We're getting some weird answers, I think, on some of these two and three, where some of you are saying like.
having SimpleServer 2 serve PDFs without any changes
causes it to break.
or saying things like.
For question three that the
mime type
by changing it to async, that function causes the web server to break.
and thus doesn't serve content. This is not true and this does not happen if you
actually run the code. So I'm going like.
How'd you reach these conclusions?
did you run the code?
If I say that you modify the program and do this.
Yes, read the code and try to figure it out.
But if it's on an assignment, you test your answers.
On the midterm, you may not have time to actually test things.
And so I'm not expecting necessarily to run things on the midterm
But for the assignments, you should be running the code.
And if you're not, then you're not
like you're potentially getting things wrong i mean i
just yesterday when I was coming up with the solutions for assignment two, I was working on an answer to the last question and I made a mistake and I went like.
This code should work. Why isn't it working? And then I was like.
Oh.
That's why.
And it's like
there's no, I mean, I'm not saying they don't exist, but in general
you don't know what code does until you run it. And even when it run it, it may have bugs still, but…
predicting what code does without running it is
always
you know approximation.
of what the code does.
you should be talking about your experience, your concrete things.
And we told you, how would you change? You should be giving
not the full function, you're just giving code snippets and saying how they would get integrated and explain what they do and why you added that code.
you need to explain
What's true.
So, you know, if you're going to talk about things you did.
We spilled roughly be able to approximate what you did and get the same results.
So…
this is important.
Okay, any other questions about this? Otherwise, I'm going to uh
I've got like at least one question assignment two that I'm going to talk about.
while it's on.
And in question eight.
So when I talk about a valid date.
this is what I mean is like, this is not a valid date. These are validates
If you're saying you know um
So question, is it okay to put constraints in the form of the dates entered, like even if they gave day, month, year.
Really?
So the date format that you accept
can be very restrictive. It doesn't have to be general, but then you have to
you know adjust the interface to make these things clear.
I will say that JavaScript
Modern JavaScript.
has built-in methods.
for handling dates.
for doing things with. So if you use one of those
you can do a pretty quick little validation of things.
I think, well.
JavaScript HTML even has something so
you only have to give one method.
My answer is kind of long because I talk about the different ways you could do it
Buddhism.
Feb 30, 1999, a valid date? No, it's not.
It's not in a calendar, so it's not a valid date.
I'm saying you should be…
refer you solutions that are built in.
But if you want to use a library, you could.
just then you have to explain how you'd incorporate the library into the code and
how you would use it.
do I want exact code?
When I say, how would you, I want a detailed answer.
So yeah, that potentially means, you know, code fragments
So I want you to give the code fragrance, but also explanation for what they do.
Again, look at the solutions for assignment one
I, you know, show you what it is.
Are we supposed to look at reference period when we write the assignment or
are restrictions on internet searches meant to steer us away from stack reform. ChatGPT live stuff
I'm saying you can use whatever online resources you want.
If you look at the
what i said like in assignment one i say
Please solve each way, look at the answers.
Okay, so…
So having said for each question, please include what outside resource you use, including other students, man pages and web recycling AI search. You don't need to help them come from a minute.
I'm not saying you can't use any particular, oh, sorry, I'm not
Didn't show you that, sorry.
I just realized I was highlighting stuff on a page that you couldn't see.
If you look at the assignment text.
I say, I say having
Having said this for each question, please include what outside will use to complete your answers, including other students.
Man page and web resources. You can use whatever you want.
It's just, it should be your answer.
And you should understand it and you should explain it as such.
You can't just copy and paste from them.
Oh.
Yes. If you use a website for like to look up SQL commands or something like that, definitely.
include the link.
You know, include the link to the references you used.
Basically, how'd you figure it out?
The reason we want you to show how you figured it out is because we're
wanting to see, are you doing your work? Are you problem solving or are you just getting good at searches and framing questions to AIs?
I want to know what you understand.
not what someone else understands.
So that's…
So that's why you have to show us this. And I expect you to make a journey and like
If you just got the answer, there's no journey to the answer. It's just you got the answer.
So you should be trying to figure these out. And then looking up things for very specific things, not looking up the answers to the question.
But looking at, okay, to answer this question, I needed to be able to do A, B, and C.
So for example.
when you're working on this assignment, assignment one, you could look up
The page, you know, page not found template, the template should be loaded when the server starts
So this one, you should have been able to you shouldn't need outside references to this.
But then this question says.
how it directly extrapolates throughout the past is like you can use me built in our ministry facilities
does not include the protocol, hostname, port number, query, or fragment. This, to understand this, you would have to look at some reference.
Like you had to look up the definition of what a URL is to understand exactly what these were.
And I'd expect you to reference that.
For example.
So if you got stuff from places there but
You're saying, oh, this is just the solution here and stuff. It's like, well…
are you answering the question?
Other questions on assignment two? I'm happy to give hints.
Links are most of your resources are probably web resources, so links are good.
Yes. Please.
please include links.
But it doesn't have to be anything fancy.
Okay, so what I'm going to do now
Unless there's any other questions. I want to start going through the tutorials. Let's go back to the beginning.
to start looking like this is what's going to be on the midterm
So the way I try to keep things honest for the midterm
is I cover material
that are um
that I covered in the tutorials and the assignments.
So really the focus should be on the assignments, but if you look at the assignments.
Those come straight from the tutorials.
But it's good to look at the tutorials because the tutorials tend to be a little bit broader.
And they tend to cover a little more things conceptually. So you can look at those
And say, do I really understand this code? Do I understand what's going on here? What's the concepts that are here?
Ah, so one thing, so there's a question about web page titles. So where do web page titles show up?
Remember, they're always there. They're what makes the title of like so you see this
This whole thing, web fun, you know, tutorial on some of my notes. This is the title of this page.
If I want to verify who it is, if I view the page source.
And if you look here.
Here's the title.
That's why we try. It's in the head.
of the page, and there's all this other
stuff in there because it's more complicated but you see
The title is there. And the title corresponds to
what's right there. That's all I'm talking about when I'm talking about the title of the page.
But going back. So what did we, so first off, what we do is you got to get your VM started, get running that and things.
But then we were looking at this code here.
you know simple graph, simple graph async.
So what were these programs doing?
So remember, these are command line programs and you had to understand whether. So let's just walk through these here. You got deno args link.
Notice any object that's with Denno or something, these are things that are not specific
They're not general JavaScript things that are available in most browsers.
Denno is a Deno specific thing.
And it's generally for
for stuff that makes sense on the server.
So here, deno.args.length
is in 2401 and things you'll see that you get
When you have a C program, it has command line options and stuff.
You have Maine as argy and argv
that's what this is arg c
but slightly mangled because they trim out the first couple of arguments.
This is the command line arguments.
And here we start seeing print out. So you print a standard out or standard error, console.log is standard out.
console error is standard error.
And then we do that. And then just like you can run
the exit thing, the Unix thing to have a process exit, and this is the return value. So this is actually straight from C programming.
That's what it says, but we're doing this in JavaScript.
And Deno.
And here we get the two command line arguments.
The search term and the file name.
Then we have one file. This is the thing I love about JavaScript versus like programming something like C. I've written one command and it read the entire text file into a string.
Didn't have to allocate any memory, didn't have to loop anything, the buffers i guess
do one thing and it's there. And this read text file sync
means that there's nothing asynchronous about it. It's just going to run to completion
And then we get this file name. So the program will pause until this finishes, just like classic.
see most functions and see you call it and
when the function returns, the function is completed.
And we get the raw contents, then we split it.
Because it was just one string. We split it on the new line character. So now we have an array of lines.
Instead of one line. And then we
We now use this index of, so we're searching in the string
for this value.
And if it's greater than minus one, minus one means that the index of it was not there.
Then we print those. So this is just a simple
This is what GREP does. GREP does with regular expressions, but here we're just doing raw textual matches like
We're operating the lines that matched.
so um
So now async. So, uh.
Pascal, you just said async. You have a question about async?
I was going to talk about async now.
So here, first, you know, this part of it's exactly the same
We got our arguments, we assign our arguments, all same.
But now return matches
So first we do we get this
We see Denno read text file, and then we get this read
Promise.
So this completes immediately.
This promise comes back as basically saying
At some point, I'll have the values of the file there. I don't know where.
you keep doing things, check on this promise later and see if it's actually finished.
then we say this try
is to try to see it. So now it's actually going to try seeing if it can do it. And so when we say a wait for the promise was like.
Come on, I asked for the file contents.
given to me, I'm going to wait until it's done.
That's why it's explicitly a weight
And if that finishes successfully, we'll get the raw contents here and we return matches.
And this thing's exactly the same as otherwise.
But if there's a problem with reading the file, we'll get a console out reading the file and we'll get this.
Now notice…
What if there's an error here?
is this the same code? Not really, because we've got this try catch thing. And the whole point of try-catch
is this may throw an exception.
So who's going to catch the exception? We're saying we're going to catch the exception.
Here we get this error of what the exception is going to be.
And so we can report what it is and then exit gracefully.
This code, if you give it a file that doesn't exist, this will break out, but it doesn't have the try-catch.
And so this will um
just give a big error.
So this is really, this is just basic JavaScript code
what are the things that we've got if else statements. We'll kind of see this looping thing looks kind of like.
see, except we're declaring the variable in the loop, which you can kind of do in modern C.
So it's declaring it here, although this is a var thing
it'll actually be the scope of the whole thing. We probably, you know, let would be limited to this
this block here.
Backslash n is kind of like
is a C character, you know, that's an escape for new line
But we have a nice string manipulation things like split, which is notices a method
of raw contents is
a string.
And so strings have a method split.
And that's what you're using here. Again, Denno, the method is read text file.
This is again an object here with args with
accessing those. Again, strings have a process index of
The console object has a log method and an error method.
I'm trying to think anything else interesting about this as a JavaScript code thing.
We're declaring functions.
Notice we have these uh
Well, yeah, we didn't define any functions here. We just did a loop here. So here I'm declaring a function here. This is actually technically anonymous function.
And we're calling it Return Matches.
It's kind of a different syntax.
This is just getting us into
JavaScript. It's kind of what you do think 24.1, except the code's a lot simpler
Because JavaScript has some really powerful methods.
And thus we have no variable types or anything, we're just assigning
vars and stuff and
not saying about that. Now, if we program in TypeScript, we need to specify types for some of these things.
Although you have to do it for everything.
But this is like more like Python.
we don't do anything so so this is JavaScript.
Then he went on to simple web servers. Now we're going to use
Why is this taking a while to load?
This definitely demonstrates the blocking. The whole point is
the read text file sync is blocking
And retext file is non-blocking.
Non-blocking means that's why you return a promise.
Okay, this doesn't seem very weird. Why am I not
There we go. It's like…
Or was that taking a while? Not clear.
So.
A lot of people are watching videos from the wiki.
Not sure.
So here, this one's about simple server two.
And what are things to learn here to notice? First of all, notice how we run it.
We run it with Deno Run.
Quite simple enough. We give it the file.
But then we have these two things, allow net, allow, read.
If you tried running it without those, you would have seen it asks you explicitly
for whether it can access the network or access the file system every time it tries reading a file and every time it tries
hopefully a network connection.
this is part of Deno's security model. It's kind of like the browser.
in that the JavaScript by default starts fully sandboxed and has lots of ways controlling how it includes access. And this is a very useful
security mechanism.
And…
Then we go through
you know now we've got this, you know, run this code like what is this code simple server so this is a simple
static web server.
This is JavaScript.
this isn't even having anything to do with HTML.
Because HTML documents could be served
But this actually doesn't even have
It's just purely a web server that is serving files.
And to support serving files, we had to learn about what does a web server need to be able to do.
Well, it needs to
For a response.
And we can see this here, like there's
there's a lot of things to HTTP if you look at it in detail. And we'll talk about some of these other things about negotiating things but
This is focusing on the main things. The nice thing is deno
takes care of the most of the other parts
in a standard way so you don't have to really think about it.
And so what's doing the work? So first of all, we have this deno serve.
This is the built-in function to Denno that makes a web server.
all at once.
is a function that it will call
Whenever
an incoming web response happens.
So understand what actually technically happens when you run this code is it does this.
It evaluates its function, evaluates its function, calls this.
And then no more code here runs.
you're basically like sitting right here in effect and it's just sort of
the Deno server is just sitting there now waiting
for an incoming request.
And when that incoming request comes in.
for the web server, then it calls the handler function and this potentially calls other things.
But it just sits there and just there forever.
Until you kill it. There's no way for this thing to actually exit.
So it's got implicitly an infinite loop whenever you call this.
So you could put other code after this.
It would never run.
Because once you call DenoServe.
Why do we take it back? You can call DenoServe
it doesn't actually block things.
That's an important distinction.
So you'll call this and this thing ends, but there's in effect another
part of Deno that's just sitting there and looking for
work that remains to be done has a work queue.
And when you run DenoServe, it basically puts in the work queue saying, hey, listen for a network connection.
And when that network connection comes in, then it calls the code to handle the network connection
which potentially gets an incoming web request and then
goes, okay, hey, we have to handle this web request. And then it calls the handler for it and stuff. But it's always
It's event driven. It's waiting for events.
And all our code here is really just setting things up for the event panel to have something to do. The event letter has nothing more to do
Then Deno exits.
So we have this dental serve.
Then we go and look at
this handler function. What's this handler function do it has
defines a little bit of metadata, a little structure here.
Status 200. So what's status 200? We've learned that that is the
status of okay.
Every web request where it returns.
You have to say, was it okay or was there some problem?
to under the okay and then everything else is basically an error message.
And then we have to say what type of data are we sending back?
It's not just bytes. It's got a type associated. And we send back text plane. That's the default.
And so now what we do is we
get the path name. So this is the path
We take the request URL, which is the incoming URL, HB, you know.
local host or whatever domain and anything else.
We turn that into a URL object.
And that your object has basically it in parse times. And we take the path name field from it.
That's just the part.
after the domain. So it's this part right here.
is the
path name. You take the path name.
We append to it dot. Path name always starts with a forward slash.
Just like this does.
After the host name, there's a forward slash there.
puts that whole portion of the URL.
And that path name then has a dot append to it. So we're going to look in the current directory for files.
And then we have this variable content, so we haven't declared so its value is undefined there.
uh…
a 2XX status code good?
I'll…
So if you're looking, what are the status codes for HTTP?
So technically, informational responses, successful responses are 200, 299. Redirection messages are here.
client error responses.
And server responses are this.
This is telling you what it is.
you know, there's a lot of things, successful responses this is
the normal one.
This is if you created something, you've accepted but not yet acted upon.
non-authoritative information, no content, reset content, partial content.
multi-status already reported in, you know, imu
Yes, these are all technically, it wasn't an error, but it's not like
Done.
So yeah, that's there. Oh, sorry, I had a question here asking, will there be um
I'll just put this in the notes of the class.
So just recall, I put this in the notes, but remember
TAs will be having their office hours and tutorials this week.
T3 and T4 checkoffs, they'll have to be finished by the end of tomorrow.
So they'll be around to like help with tutorial five
Which is actually still worth to do, even though it's not directly covered in the midterm. If you understand T5, it will help you with the tutorial because it'll help you understand the
server versus client differences.
But you have to get checked off.
So we have here
a, so you have our contents. This is the data that we're actually going to return. There's nothing that's going to be undefined, so we need to make sure we put something in it.
And then what the content type is, we ask for the mind type of the path name. So we'll go up and look how we calculate the mind type in a sec.
then we try
to do this.
We do the A weight on deno read file.
And if we get an error, then the contents are just
No.
And then we say, if there are no contents.
Something happened, we just say file not found.
Could there be a permission error or something like that? Technically, you could afford things, but…
on a web server, you normally wouldn't want to give too detailed an error message because that can be used to compromise security.
you just um
give the base look. I don't know what this is. That's a classic 404 air.
So we set the status to 404 and then
Content type is plain because the contents is just this string.
And else console.log returning this of type this.
And then we just return a new response object.
And that's it. And then we go like how this works. The only other real code here is the code for determining the
mind type and we have this thing of defining all the different mime types.
These are not by any means comprehensive, but these are common ones.
And then we check to see
what you first say the extensions, you know, this, the file name
So we get the extension to be this.
And if we don't have a MIME type for the extension.
where we default to application octet string.
So note that while there's a mapping between file name extensions and this, MIME types and file name extensions are completely separate ways of identifying the type of a document. Here, because we're loading
files from disk and we don't have any other way of knowing the type.
We're just assuming based on the file name, but you could do other analysis of the file. There's this
command called file, which tells you all about a file and you can
potentially determine the mime type using that, although it gives you more detailed information
And of course, if there was a dynamically generated content, you could just return it and just tell the mime type and not have an extension at all.
And that's completely normal.
So these are completely separate mechanisms.
But if you give the browser
a file name extension, it may try using that
And then look at the mime type and then may have to decide if those conflict what it's going to do.
So that's tutorial two.
Now let's go to now remember assignment one was just
an elaboration on
on the code of the code
of SimpleServer. It just got reorganized a bit.
So what happened was is what happened was
The response type, that's all basically the same.
Here we now handle index.html. If we ask for a directory.
So for that.
We have a log, the console, which is a little more interesting
We append the WW directory to it
Instead.
And then we have some templates for simple basic pages
From the file not found, we return to HTML page and we build that up.
The mime type is otherwise the same so
It's kind of pretty so and we define the
statuses as constants.
Because it's always better to have constants rather than raw numbers in your code.
So what makes a static, so that's a good question. What makes a static server static?
A static server
So I'll…
So a static server, I'm just putting this in the notes so I can share this in a second, but I just want to type this up.
a static server
Which means…
So a static server just means that it serves files rather than code generated content.
static meaning the, I mean, normally you don't think of files. I mean, files can change, of course, but files are on disk and that's just what's being served as opposed to static versus dynamic.
Dynamic content.
dynamic content is dynamic
So generally, dynamic content means it's loaded from a database and generated.
So like you look at this page right here.
This is dynamically generated.
this page. It is based on PHP. You can actually tell it's based on PHP because if you look in the thing, index.php.
index.php is actually calling media wiki
And this is all things to MediaWiki saying what part of the wiki it is. In order to generate this page, it has to go to a MySQL database
do a query, get stuff for putting together the page, assemble the page
like grab things like this file and i think like
put it all together and then serve that.
that's dynamic. Static is, oh, here's a file.
Go.
Yeah, I think this will be a disco just a little cleaned up, but otherwise it's
basically the same thing.
database demo. I'm sorry, no, form demo. So let's go form demo
So form demo
Now we're starting to get into more of like what's going to happen on the client side. We want to start having some actual content.
And the big thing here
is you look at, so we have a style thing here this is
So we haven't really talked much about CSS, but basically you can specify
ways of referring to the document object model.
parts of the web page and like the body of the web page we're saying this is and links
which are a tags go this
But then we have this
HTML document.
The HVL document is being served.
And this HTML document.
You know, doc type HTML it's
You know, so this is actually how comments are there
you know this exclamation point
escalation dash dashes comments.
But this is a special thing doc type.
HTML and then
And so it's an HTML document. So it starts with HTML and ends with HTML.
Here.
It has a header and a body.
Add this here, ends here.
And inside of it, we have two things. We have a link
to the style, you know, relative style sheet, href this. So this is just how you include
a CSS style sheet and this is how you encode the title of the page.
which is shown up here.
the title of the patient. And then we have the body of it. We give a heading.
H1.
We have a start tag, we have an end tag.
And then we have these various divs for dividing it up just for
grouping things together.
And we have paragraphs, fill out your info.
And then we have this form.
Which goes here. And in this form we have little
inputs with labels associated with them this one's inputting
text and inputting text and then putting text and text.
And there's a name and there's an ID. The ID is used in the client side if we want to manipulate the form.
The name is what's used when the form is submitted via post to the server.
the value that was entered here will be given this name.
And so we use that now on our server to process this form and store it.
for it to be listed later.
So how does this work? Now we got this demo serve. We've made the dental serve a little more complicated. We've got now a port.
And a host name, instead of your default, this port 8000 was the default one.
This defaults to listening on 0000, which means listen on all interfaces.
No matter how you connect this computer by the network.
You can do this at least by IPv4
And we give it the handler function.
Same basic structure we've had.
And then we go to the handler function.
And we have this thing here now we have this
we've got time to do a few more things.
new URL path name, same thing. We've got the path name from it.
We've remembering the original path
So rigidmouth versus Path, we'll see that because we change path here.
And we want to log the original path.
And then we route.
So this is basically any dynamic content will be handled by the router. It basically says.
Can you handle this request? Handle it.
And then if R has not been handled so r is
null or something, but it's like, okay, it didn't handle the request
So we better look it up as a file.
So to look it up as a file, we go through here and we go
Well, first, let's do a little check before this does the most of the work
gets the file data for the path we've
Now that's separating a separate function, but it loads it
the data from there and gets a response and
Then we have a response object.
And if the path requested was slash, we just replace it with index.html. So as people are accessing a directory, we can't reply with the directory, we look for index.m.
that's the way you view a directory.
Now, there are web servers, of course.
that if there isn't an index, what they'll do is they'll do a directory listing. They'll actually build up a page
get a list of all the files and then make a little web page with it.
And it lets you navigate to that.
Our web server doesn't have that feature.
Get out of it.
wouldn't necessarily be that hard.
We get this
And then we log what we're going to do because at this point.
we should have a appropriate R.
This is either going to be we found the file or we
you know file not found or some other error.
So we log the status.
what the request method was, you know, get or put or whatever
And then what content type we got. So remember, this came from the request.
A ridge path came from the request as well, but we already parsed it out.
And the status.
and content type came from either file data or from route.
And then we return the response here where we specify the contents, where it was an object.
the status and the headers there. So there's lots of potential headers
and HTTP, this is the one we've been setting content type, here it is.
Then to figure out what's doing with these other things, let's look at, well.
this code should be very familiar at this point. This is exactly what
SimpleServer did.
So nothing interesting there.
But then route is the new thing we've really introduced. Now this is doing
dynamic pages rather than static pages.
So here we see, well, is the method get request
then we route the get. If it's a route post, route the post.
This is typically separated, gets and posts. And the reason why they're separate is because gets and posts
expect
with a get request.
we've gotten basically we've just gotten a URL and we parse it and then we give back what the URL is.
With a post request, we got a URL, but we also got
the whole body of the post.
all the things that came, like the form submission.
Which can be quite substantial, and that needs to be handled in a different way so
No, that will go to separate coding.
And so we look at route post-route, what is route post do?
that implements our add method. Now, where is this ad coming from?
Who would make this? This isn't something that people would normally do.
manually, that's being generated here.
By…
The submit button, when we hit submit.
We're saying the form should be submitted. Where is it going to be submitted?
it's going to be at the top of the form it says here.
It says form method post
action add. So submitting this form generates a post
slash add http
request to the server, which is handled
You know, it goes through route, goes through route post
and then gets to looks like it's odd.
And so then that gets a weight add record.
And so we then go to add record
This is what ad record does.
parses, does all these body gets.
which really
I find this slightly irritating.
Because the way of JavaScript, I shouldn't
feel like I should be able to just do body.name, body.city and something
But I think it's to prevent conflicts with other fields that could be there in the body.
But I'm a little annoyed at that syntax.
Because it's just a…
JavaScript object but
we get all the values of all the things. These names here correspond to the names here in this form.
So we have whatever the server got there, we now have it translated into a JavaScript object.
And we had created um
state is a…
just an array of objects.
And we push it on there like a stack. So now there's another object on. So that's the nice thing JavaScript arrays dynamically grow and shrink.
we can treat it as a stack and just push things onto it and pop them off.
So we pushed it onto there and then we
respond that, hey, we did fine.
And we say, yo, status. And then we say, what's the contents
we're going to generate a little page, template, add records.
So what's template ad records?
attempt to add record.
It has a header.
header is just this little thing, which gives the hot doc type. HTML ads here.
the title of the page.
And…
And then we get a person just added. And then here's our body
And in the body, we have a header just added and then we enter in the fields
And notice that we're using a back tick here so this allows
For multi-line strings and multi-line strings
can have this dollar curly brace syntax where we can put any JavaScript basically in there and evaluate the
value of it in order to find out what to put in there. So opshot name that
It's a name, city center. That's how we filled all these in.
Return that string back to the
this is returned as the value of this.
this template.
And we add record, that's going to be the contents of the thing. And so this will get go back to the
main loop the response and return back to the client.
Then we look at get to handle a get request. The only get request we understand
other than serving static files.
is list.
And list in this version of it, there's no explicit way to do list. A person just has to type in the URL to get list. There's no menu or anything.
I added a menu in later versions.
So that's built into the code, but this one it wasn't.
And here we're still getting the path name out. We get the list.
And then we call list records.
what does list records do? It then goes
And so here's list records it just
builds up a response object.
And the only interesting thing here is it gets this template list record state.
So list records state
is this thing. And so there's the top of the page
Which is this. There's the bottom of the page.
which is the um
bottom, which is the whole form thing this is a form
with a get method, this is how you can implement a button.
that goes somewhere.
There's of course other ways to do is JavaScript. This is the classic way of doing it with a form.
And so this makes the button for going home
This is the top and bottom. There's also of course the header
we're going to like template header
Page top, page bottom.
And then we join all the rows.
So we have to generate the rows.
this is where we put the actual
all the records.
And so it's an array.
we make a little function which marks up it, which basically puts a
This is a table data thing, so every element in the table should have this around it.
And so this is a row.
Start of a row, end of a row.
And then we put all these things in there.
City name, city, country, birthday, email.
And we have the titles up here, the header of the title, so you can look at the syntax of a table.
as a head of the table, the headings of it, and then the body.
a bunch of rows.
and these
we built this all up and then
Once you have this, we have this big string.
And this is what we return.
And this is handled by the list record and this becomes the content of the page that's returned.
Is the casing for template list records typical for JavaScript?
It seems like a mix of snake casing and camel casing. Yes.
So…
Most of my stuff is camel casing.
You know, up, down, up, down, you know, things.
Why did I name this here like this?
The reason I did that is because just to emphasize that these are templates and frankly.
this is not how you do templates.
In modern web development, you would use some package
Such as, um.
is it called, is the modern name mustache or handlebars
I think it's mustache now.
But there's all kinds of templating languages and all the templating languages are for is for taking some way of describing an HTML document and programmatically generating it.
I've used multiple ones.
normally use a templating
method for doing this and probably templates would be in separate files.
So you wouldn't do it this way. So I was kind of marking them as having this template underscore thing to kind of say.
This is kind of weird. We don't really do things this way, but we're doing it now just to
to show you how everything works.
But that's a
Yeah, cool, cool. That makes sense.
But good observation. Yes, I did specifically do that kind of weird.
the way you normally do these is have them as separate files.
in a directory and have something that would parse them and
insert the templates.
But for something this simple, you don't need anything that.
It's ugly as all heck.
But it works and puts everything there in one thing.
Okay, so sorry, what does a way route request return that makes R evaluate to true?
Okay, so this is a good question.
So what we're talking about here is we go back here.
We have this RAWA route
Now, why do we have an A weight here?
We have a weight here, remember, because this is an asynchronous function.
So we go up to route.
And so route, here's what route does and it returns a route get and route post.
Now, the key thing to know about these functions, if you trace through them.
is they will return
an appropriate request object.
And the request object.
So it's kind of interesting JavaScript. We often don't declare these things explicitly and more implicitly do it.
TypeScript kind of makes you be more explicit with it.
I don't know how I feel that. I kind of feel like
I kind of like this way I'm a little old-fashioned about it but
This goes back to the way dynamic languages traditionally do things, do things dynamically. But you'll look to see
what is an R? R has a few things. It has contents, it has a status, and it has a content type.
three fields that have to be defined.
as in as part of an object.
So if the not here means it's not an object.
it's like null or something. And that's when we go through here.
So when it returns true, it's returning that object. If it's returning false, it's returning null.
And so you look here
this is the return null if they haven't, and route get route post
And you'll notice both return post and returns null if that isn't there, otherwise it returns a weight this.
And a record returns response. Response is an object.
with these three files. You look at list records, response is an object with those three
properties.
So that's what it is. It's either going to be an object
with those content type status and contents.
or it's going to be null.
And that's what the if statement is going to be evaluating.
Does that make sense?
If you have questions.
Let me know.
So going back to the code here, so we were doing the list
in the list records, it generates this and that's
pretty much, you know, here's the return thing of like
When we add a record, the template for that that and then that
Here's the good old mine type that's still there.
And then we have our status codes. And then we have state, which is just a global array.
And the problem, this all works.
Except for one thing, when you kill the web server and restart it, state.
gets destroyed because it's just an in-memory
ephemeral variable. There's no persistence to it, so that's not so good.
And so that's why we
And that's why we have database demo.
database demo is
form demo with a database.
And so let's look at how, so if you go down to the bottom here you'll see
the forms here, the form's basically the same.
demo serve. I've added in a little bit of complexity of DenoServe here.
And this is basically to allow you to hit control C and shut down the server properly.
Right now, if you control C, it just kills it.
Which is fine, but here it actually
catches it and it catches it because control C generates sigint
an interrupt signal in Unix.
And if it gets that, it says second receive terminating.
And then it sends this message AC abort. You go like, what is this AC abort?
Well, it turns out DennoServe, while it's running, you specify the port and this is the host name, you're in a handler function.
We now also specify the signal.
This signal is an abort controller.
This is a way of telling DenoServe
Basically, when this signal
get set.
you know when this decides to do something, then it will actually stop the server from running.
And that's how you actually get a clean shutdown because it's actually choosing to end.
And this AC abort basically is saying.
is telling the signal thing saying, okay, it's time to abort.
This is a whole mechanism
that Denno has for controlling the execution of things.
that are running in the background with these whole signal things.
I haven't actually invested exactly how they operate and it doesn't really matter, but there's this weird thing like Unix signals are this and this is saying kind of a Deno signal.
to this but
the net result is you hit control C, AC abort gets set.
then this thing exits. And then when this gets exit.
then we get to run the servers finish then
this code runs because
this is basically sort of finished as a promise.
win this promise, then that promise resolves, then you do this.
And the main reason I want to do this is because that way you have a DB close.
Because if you're having a database
with persistent data, when you're done, you really want to close it properly. And the reason you want to close it is to make sure all the data that's maybe in process
has been sent off and
resolved. You don't want it getting lost.
So it's always good to close things like that or do whatever it is to
finalize things.
So going through this, so this code's all
form demo. It's nothing new here.
except now when we do things, we see this ad record
for this and then add record
does this add record db
instead of just adding things to a JavaScript array.
One thing I should note, in JavaScript and other languages, it's sometimes possible to overload objects.
to give them other properties.
So…
you know what you sometimes can do things like, oh, an array assignment actually does other things
Which is equivalent to this. And that is a philosophy of doing that. I don't typically like that sort of syntax so much overloading other operators being too fancy.
It depends on the application stuff. But when you make operators really fancy, then you're like.
what is this code actually doing?
And it can get confusing. If you use a function call, you know, okay, there's something else going on there. Let me go find it. If it's an operator, go like, whoa.
to any external code run or is it just doing the default stuff?
That's the problem I have with operator overloading.
It's all about readability.
How much state you have to keep in your head to follow what's going on when you read the code.
So this add record DB is kind of our new thing. And if we start, we look at list records
it has now this get all records. So get all records returns
an array of objects.
you know and add record takes an object and adds it there. So semantically, they're essentially the same as just adding it to an array or getting
getting it away and getting all its elements.
But we want to do it persistently and we're doing it with a SQL database
So what we instead have is this stuff at the top.
where we import DB from DenoLand SQLiteMata. So the first time you run this, it actually has to download this.
And then once you've done it, it stores it in the Deno cache. And then every time you start it up, it's got that version of the code.
So now we've got this DV module and then we make this into a new db object
which pays this DB object is the thing that allows us to interact with the SQL database.
It's the sqi database
And it has a whole API that we'll be using.
this DB query for the most part, but it also has a db execute
we executed this SQL command.
to create a table in it
if they're, you know, create table if not exists.
So since we create tale, if not exists, so if
people.dbR exists and has a people table in it. We're not doing anything with this command.
But if it doesn't, we create it from scratch.
integer or primary key auto increment. So this is saying this is the primary key so this is
the thing by which records will be organized in the database.
and the order by which things are going to be returned by default.
So this is just an account of the number of records that are in there.
you always need some sort of primary key and the primary key in a table should normally be unique.
I can't guarantee that the names will all be unique.
So that's why you typically want something like this.
And then we say the name, city, country, birthday, email.
Now, when creating this table, I could have created indices to make
sorting this in different ways faster and stuff and make certain queries faster and stuff.
We haven't done anything, so it's going to be slow, but we're not doing any real data processing, so who cares?
That's all efficiency optimization. It's not functionality.
required for functionality.
then we're
Now we look at how does add record db we have this little SQL statement.
multi-line string with the
with this thing and so
insert into table
Name, value, country, email, values, question mark, question mark.
So where these question marks get filled in.
db query db query
takes care of these things.
all city value puts them in for the values.
So this DB query query kind of sounds like you're asking a question of the database, but it also is used for doing things that modify the database.
that's just how that's that's the API they have set up.
So the main difference is db query
So DB execute just runs a command that's not going to return much in the way of data.
db query runs something that can return
data.
So we do this db query.
And we're returning that ad record that you know return something there
And then we say, and then we get all records.
this is we prepare this query
that we then finalize later and so we select
from the table that we have defined here as a global
people.
The select means I want all these things from the table and it's given me all of them.
And so the reason we do prepare query and this query finalize
is because it lets us iterate
through the query. So if you have lots and lots of records, you don't want to process it all at once.
And in fact.
you might actually want to place limits, maybe only do like 50 records per page or something. That's where this
Iteration allows you to do. So we're just
getting these
assigning these values to the return value query iter.
And then we can just make an object where the values of those variables become the key value pairs of this object. That's a nice thing.
Like we could just say ID colon ID name colon ID, but we can do the syntax now when we just
say this and that's implicitly what we're doing. We're taking the variable names
as the keys and the variable values, as the values in this object that we're dynamically creating here.
And we're pushing it onto state.
So the idea is that we're recreating the state
object that we're returning
from the query to the database.
They finalize that statement.
Mine, same, same.
Template, same, same.
that's all that's different here.
Confused what query iter. Okay, that's a reasonable thing to ask so
Let's go back here.
So.
Notice…
Logically, when you're doing an operation to a database.
You can think of, I normally like, okay, here's a command
I send it.
I get the result back.
And that's exactly what's happening.
with the DB query and the DB execute.
dbx cubed, there's no return value.
It's just like it goes and did it mean it's a task.
PB query, there's going to return something
until it returns the object that was added.
But what if we're going to get back a lot of data from the database?
we don't want to handle that.
if it's going to be a lot of data at the database.
if you just try getting it all in one chunk.
probably break things. You need to get it in pieces.
So what this whole prepare query
query iter or query finalize. So query finalized just means we're done with the query. We're not, you know, close it off. We're not going to get any more data from it.
This is saying, get things set up. And then the iter basically says, give me the results. Give me the next result. Give me the next result. It allows us to iterate. That's the iterism. I'm going to iterate through the query results.
And every time I call query iter, I get the next
One.
So that's what we're looping through. We're looping through the each result of query iter.
And…
we're only going to get this
basically this is only going to be evaluated
as needed. So like if i only
allow this loop to run for say 10 times.
I would only get 10 results. There might be a billion results.
But I'm not going to get a billion results and have to deal with all the memory and other things. I'm only going to get 10.
Because I only called this 10 times. So that's all I'm going to get there.
So this is a very important concept of just iteratively dealing with data as opposed to dealing with all one chunk.
Scott, does that make sense?
Yeah, okay, cool.
But these are things like
there's a lot of concepts in here with this database.
SQL is complex.
And dealing with SQL databases can get very complex.
The point here is not to understand SQL in full detail.
It's to get a little taste of SQL and see why you would incorporate it into a web application.
And the reason you incorporate is because it's a very sophisticated way
of dealing with persistent data of
storing it, organizing it, and accessing it.
That's what databases are good for. And what's even better is
Classic databases not
SQLite is only meant to really be executed.
access by one program at a time.
full databases.
I suppose a more embedded databases
are designed to have hundreds, thousands, millions of entities
make queries for them at the same time, change them at the same time. And they always provide a consistent value.
So the classic thing that relational databases were developed for was for airlines.
How do you make sure you keep your seat maps all up to date and that you know when you know
Different people are buying tickets for different flights and big payments. How do you make sure all that
stays consistent and organized.
That's the problem databases were designed to solve. They solve it very well.
Web applications typically don't need things quite so rich.
But it's such a but as a web application grows, you find you use more and more of those features, which is why it's often useful to have.
a SQL database and databases like SQL Lighter
can be embedded and very lightweight, or if your needs
become need for more concurrent access
you can still keep the same SQL commands for the most part and then move
to a more complex database.
Whether it's MySQL or Postgres or even things like
cloud databases, Oracle or whatever.
Okay, so…
And then from this, if we go from DB demo and then what's
DB, you know, what's assignment two
It's just db demo2.
And what did I do with Debo Demo 2?
It's essentially the same code.
There's a few little differences. You'll notice the SQL here is a little different.
There's on these other, there's this whole analysis record records
which do a few more SQL queries.
there's um there's
is all list records is basically the same, add records same
there's this whole analysis thing, which then shows a little more complex thing.
really the only thing different really is the analysis page.
But it's just doing SQL queries and showing the results.
And otherwise, it's basically DB demo.
And then we get into
This is not on the test.
It's not going to be the midterm.
But the big difference here is this just
DB demo2 demo
that code, but instead what we've done now is the codes actually are a little simplified
Because now we've made
We've added JavaScript
to the client.
And you see here, like we're building, instead of having the templates, the dynamic templates on the server.
At least for the list one, we're doing it on the client and it's just retrieving
the data from the
from the server.
And you see where is it retrieving data from the server?
is right here.
this a weight fetch.
That's the magic part of it.
And that A-weight fetch.
goes by always.
So that was a weight fetch of
List.
So what's list doing?
go through here, slide handle it here.
Where's list?
list is here in route get.
And it returns list records.
What does Listruckers do? It gets all the records.
Trends into a state object.
And then we turn state into a JSON object.
Well, it's an object. We just turn it into a string. We JSON string it. So this turns into a string that can then be parsed on the client back into a JavaScript object.
So this JavaScript object to string
string to JavaScript object happens implicitly by fetch.
on the client.
But that's all this adds.
So, uh.
So after reading week, we're going to start. So tutorial five and six
Yeah, after the midterm, we'll be working on that um
you know there'll be a new tutorial six which will build on this. But again, this is just
you can get checked off for tutorial five.
then and we'll have tutorial six and then
assignment three and things so
that's all going to be
later.
The big reason to look at this now is just look at
Oh, look, all this stuff we did in um
and database demo
with generating
So remember this list records where we do all this thing here and we're doing all this stuff here.
And it's like, couldn't we instead
just send a page to the server
And then we send the data. Can we all send this page to the client
And then send the data to the client and have the client take that data and build out the page for us
rather than having to do all this work on the server.
That's all we're doing.
So we're about out of time.
That was a quick overview of what we kind of covered. So on Thursday.
I will go through the solutions for assignment two.
And…
we will then um
They'll answer your questions for the midterm.
And then the midterm will be um
After the break.
So good luck with your site. Remember.
Please.
Please, in your answers.
explain how you got the answer and it shouldn't generally be just one sentence.
It shouldn't be I ran the code or I read the code.
give me more. It takes me more effort to figure this stuff out when I've read
And I'm running my solutions and I wrote the code originally.
it'll take you some effort to do this. And I need you to document your process.
Tell me how you got there.
And…
any problems and then we can give you points for that. If you don't do that, I can't give you points
Okay. What day is the midterm? It's on tuesday
October 29th, the Tuesday after fall break.
during class time.
Okay, thanks a lot. I will see you on Thursday. Good luck finishing up assignment two.