Now let's create the ability to list and show all of our todos.
So what we'll do is we'll go to the app > dashboard > todo's page here.
And this is where we wanna pull in all of our to do's, and we wanna render them.
So let's do that.
Before we do that, it's probably a good idea just to make a helper function,
cuz in order to use prisma, we have to create an instance of the SDK.
We don't wanna have to recreate that every single time.
So let's just make a file that creates one so that we can import it everywhere.
So let's do that.
I like to store those types of things in a folder called utils.
I'm just gonna put it on the root.
You can put them in app with underscore,
you can put them in app without underscore, however you wanna do it.
I'm just gonna put it under root.
And I'm gonna make a new file called db.ts, and it's ts,
not tsx because there's no React in here, it's just a regular JavaScript
file that does regular JavaScript things, there's no React in here.
And I already have a lot of that, Kinda done.
So I'm just gonna copy it from my repo and
I'm gonna talk about why this is the way that it is.
Basically, the reason why we do it this way where we're checking to see if we're
in a certain environment variable and creating a client and attaching it to
global, it's mostly because of serverless environments and connection pooling.
It's an advanced thing, but basically, databases were not meant to be in
a serverless environment by default, they don't like to maintain long lived,
in a service environment, your service spins up, it executes, and it shuts down.
So every time you do that, you have to start a new database connection.
Eventually your database is like, I can't handle all these connections.
If you have 100,000 requests in a minute,
that's 100,000 connections somewhere, give or take.
Most databases can't handle that, and they're not meant for that.
They're meant to be running on a server that's long live that has like one or
two connections.
That's it.
But luckily for us, we don't have to worry about that cuz one reason is SQLite.
And we're not in production.
But two, there's real serverless databases now that account for that.
But in order for the client here, every time we make a new client,
it makes a new connection to the database.
So instead what we're doing is we're caching that connection by attaching it to
the global.
And only if it's not there that we create a new one.
That's basically what we're doing now.
It's just to make sure we're reusing the same connection.
None of this matters right now, cuz we're not in production.
We're all using SQLite, which is not a server.
It's a file.
And there are true serverless databases out there now that you don't really
need to do this.
So, but I just do this as a habit every time, so that's why that's here.
Okay, so now that we have that, what we can do is we can go into our todos and
let's get some data.
So we can say const.
You don't have to call this getData, by the way.
You can call this whatever you want.
It's just a function.
You can call it getTodos, you can do whatever you want.
I'm gonna say this is async, and then I'm gonna import and
db, import db from '@utils/db'.
And then I'm gonna say, give me all the todos.
So I'm gonna say const todos = await db., and this is where Prisma is cool.
It's type checked, so
it already knows that something called todo on the database.
It knows that because we wrote it in the schema, Here.
And every time you sync the schema, it updates this module here.
So you have a module here called @prisma/client.
This client is gonna be unique to the schema that you've written.
It gets generated every single time.
So it's not like a typical Node module that it's written and it's done.
Now, this module gets regenerated every single time,
depending on when you change your schema.
So it's always type-checked.
So it knows about todos.
So let me go back to that.
So we have todo, and then we just wanna findMany,
which is a function to pass in an empty object.
So this should just say, give me all the todos.
Pretty simple, and I just wanna return the todos like that.
Okay, so we got that.
Now we can just grab this data in our components.
Now I can say async, and then I can grab my todos here,
and I can await getData, like that.
Now I have my todos.
But I don't wanna just render the todos in the todo's page.
I'm gonna just separate that logic out into separate components.
So I have my NewTodoForm, my todo, and my TodoList.
So what I wanna do is I wanna pass down these todos to my TodoList component.
So let's do that.
So I'm gonna go to my TodoList component, I'm gonna make that,
TodoList, Like this.
And it's going to take in a list of todos as a prop.
And all it's gonna do is just map over them.
So nothing crazy, it's just gonna say todos.map, grab me a todo.
And what this is gonna do is render, you guessed it, a todo component.
So we gotta go make that too.
So I'm gonna pause there and go make that.
So now I'm gonna go Todo.tsx and make a todo component.
And I'm keeping these components vary simple, there's no styling,
there's not really much logic going on in any of them.
And all I'm gonna do is just render todo.content.
Here we go.
So we have those, have our todo component.
If we take this todo component and
go back to the TodoList component, we can just render it here,
Todo, and we can pass in our todo as todo, like that.
This thing's freaking out cuz it wants a key.
We can give it a key, todo.id.
Need to make sure we import our todo at the top.
There we go.
So we have that, like I said, very simple, just mapping over the,
array of todos, and rendering out a todo component for each one.
And then now if we head back to our todo's page, we can pass that stuff in, right?
So now I can go here, I can say TodoList, and
then pass in the todos here, Like that.
And if you did this right, you should see nothing on the page [LAUGH].
But it shouldn't break, cuz we don't have any todos in the database, so
nothing should show.
So it's just gonna map over an empty array, which is what I believe.
findMany returns by default if nothing was in it, if we did it right.
But do we ever do it right on the first try?
I don't know.
Let's see.
So I go over to todos.
Yeah, so it looks like it worked.
We don't see anything, cuz we don't have any todos.
So we should fix that problem.
We can verify that, right?
If I just log todos here, by the way, where's this log gonna show up?
Is it gonna show up in the terminal?
Is it gonna show up in the browser?
>> Right now should be the terminal, right?
On the server.
>> I don't know, is it?
Why do you say that?
What makes you think that.
>> Seeing no hooks?
Are these client praqma?
>> Yeah, that's probably the best way to know, [LAUGH].
Yeah, there is no use client and there are no hooks.
So this is probably completely server rendered, yeah.
The other way you can tell is that, well, where's this function being used?
It's being used in a component that's using async?
Yeah, that's definitely server.
You can't do that on a client.
So, yeah,
those are all big hands that this is probably gonna happen on the server.
So if we were to look at this, yeah, you could see we just get back empty array
from Prisma and SQL, cuz we don't have any todos yet, so it's just an empty array.