#making class based router

294 messages · Page 1 of 1 (latest)

clear folio
#

what is wrong i don't understand

topaz oracle
#

!screenshot

quaint owlBOT
#
`!screenshot`:

Rather than screenshots, please provide either code formatted as:

```ts
// code here
```
Or even better, as an example on the TypeScript playground that is as simple as possible and reproduces the issue. This makes it easier to help you and increases the chances of getting an answer.

topaz oracle
# clear folio

you did not specify the type for the UserController parameter

clear folio
#

do i have to manually write a type for it?

topaz oracle
#

everything has a type

clear folio
#

what is usercontroller's type?

topaz oracle
clear folio
#

damn

topaz oracle
#

!hb classes

quaint owlBOT
clear folio
topaz oracle
#

also use camelCase for the name of your parameters

clear folio
#

parameters?

#

ok

topaz oracle
#

parameter of the constrctor

#

oh, wait

clear folio
#

also what would i wrote in constructor of UserController

topaz oracle
#

you want to pass a class and instantiate it

#

can you paste your code in a playground?

clear folio
clear folio
#

or give github

topaz oracle
clear folio
#

i can put u in

#

this doesn't has multiple files?

topaz oracle
quaint owlBOT
#
advertised#0576

Preview:```ts
import {Router} from "express"
import {PrismaClient, User} from "@prisma/client"
const prisma = new PrismaClient()

export default class UserController {
constructor() {}
static async getUsers(
req: Request,
res: Response
): Promise<User[]> {
const users: User[] = await pri
...```

clear folio
#

u wanna see user type?

topaz oracle
#

no

#

not relevant to your problem

clear folio
#

ok

#

just mention me

quaint owlBOT
#
ascor8522#0

Preview:```ts
import express, {
Request,
Response,
Router,
NextFunction,
} from "express"
import {PrismaClient, User} from "@prisma/client"

const prisma = new PrismaClient()

export class UserController {
constructor() {}

static async getUsers(
req: Request,
res: Respo
...```

topaz oracle
#

@clear folio

clear folio
#

my entire problem was

#

typeof

topaz oracle
#

yes

#

also the naming of a few elements was bad

clear folio
#

what for example?>

topaz oracle
#
-constructor(UserController: UserController, Request: Request, Response: Response)
+public constructor(userController: typeof UserController, request: Request, response: Response)
#

Request, Response

clear folio
topaz oracle
#

also access modified were missing

topaz oracle
#

right, your static method is async

#

you need to await the result

#

however, you are inside of the constructor, so you can't

clear folio
#

oh so

clear folio
#

so basically

#

typeof means

#

this is the type of that

#

5 is the type of 5

#

because they both are integers

#

?

topaz oracle
#

no

clear folio
topaz oracle
#

UserController is the type for an instance of the UserController class

#

typeof UserController is the type for the UserController class itself

clear folio
#

so basically

#

UserController is a class

#

but typeof UserController is the type of UserController

topaz oracle
#

yes

#

UserController alone would be the type for instances

clear folio
#

oh

#

yeah

#

i get it

#

what about the other error @topaz oracle

topaz oracle
clear folio
#

ur saying im insided cnstructor tho

topaz oracle
#

yes,

router.get("/users", userController.getUsers(request, response));

is inside

    public constructor(userController: typeof UserController, request: Request, response: Response) {
        this.userController = new userController()

        router.get("/users", userController.getUsers(request, response));
    }
clear folio
#

yeah

#

what do we do 🤷‍♂️

topaz oracle
#

move

router.get("/users", userController.getUsers(request, response));

to a separate method

#

then call that methods every time after calling the constructor for the UserRouter class

clear folio
#

oh

#

i get

#

it

topaz oracle
#

so instad of

class UserRouter {
    private userController: UserController;

    public constructor(userController: typeof UserController, request: Request, response: Response) {
        this.userController = new userController()

        router.get("/users", userController.getUsers(request, response));
    }
}

const myRouter = new UserRouter(UserController, myRequest, myResponse);

have

class UserRouter {
    private userController: UserController;

    public constructor(userController: typeof UserController) {
        this.userController = new userController()
    }

    public async init(userController: typeof UserController, request: Request, response: Response) {
        router.get("/users", await userController.getUsers(request, response));
        return this;
    }
}

const myRouter = await new UserRouter(UserController)
    .init(UserController, myRequest, myResponse);
clear folio
#

what the hell is this

#

imreading this holdon

#

what is init

topaz oracle
#

a new method

#

since you cannot use await inside of constructors

clear folio
#

am i able to put all of my routes in that

#

beeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeer

topaz oracle
#

wait

#

ok, understood what you're trying to do

clear folio
topaz oracle
#

you just need

class UserRouter {
    private userController: UserController;

    public constructor(userController: typeof UserController) {
        this.userController = new userController()
        router.get("/users", userController.getUsers);
    }
}
#

also, I don't know why you want to store an instance of the userController

#

this.userController = new userController() this line doesn't make much sense

#

also, why pass the UserController as parameter, since there is no inheritance possible because of the static methods

#

might as well use the class directly

#

like so

#
    public constructor() {
        router.get("/users", UserController.getUsers);
    }
#

idk, most of the code you've shown so far doesn't make much sense

#

should read the express doc

clear folio
clear folio
topaz oracle
#

anyway

clear folio
topaz oracle
#

wdym "needs ()"?

#

that is how you pass a method in JS

#

you are not calling that method yourself

clear folio
#

where do you pass the request and response

topaz oracle
#

you are just passing it

#

router.get need 2 parameters

#
  • the route (a string)
  • a callback, a function to execute, that function will be called and passed the request and response
#

you can either provide the function direclty, with a lmbda (req, res) => {}

#

but you can also pass a reference to a different function or method that could be called

#

like UserController.getUsers

#

UserController.getUsers() would calle that function, UserController.getUsers is a reference to it, but not calling it

#

but please, have a look at the JS docs before trying to correct others

clear folio
#

like im coding the controller

#

if request doesn't come in

#

it'll throw error

#

also don't get it wrong im not correcting you we're just talking

topaz oracle
#

tldr. you don't need to call UserController.getUsers, router.get will do it for you

#

@clear folio

topaz oracle
#

wdym?

clear folio
topaz oracle
#

calling router.get registers the route

#

you pass the route and a handler

#

and the handler will be called by the router object when a route matches

clear folio
topaz oracle
#

so you need to pass a function as handler, not call a function

clear folio
#

in the main entry

#

in here

topaz oracle
#

I don't get why you are writing classes

#

nothing you do requires classes

#

it makes the whole thing more complicated

clear folio
clear folio
clear folio
#

@topaz oracle if i explain why i use classes

#

will u help me?

topaz oracle
#

I mean, i'm not going to write the whole code for you 😅

clear folio
#

this is the last step

topaz oracle
#

pass the router?

clear folio
#

yeah

#

we made a UserRouter

#

remember

#

i need to pass that in

topaz oracle
#

yeah

clear folio
#

app.use('/user', UserRouter)

#

like this

topaz oracle
#

yes

topaz oracle
#

but that would mean extracting the router from UserRouter and creating a wrapper method in App just for use

#

that's a lot of duplicate code

#

lots of wrapper code

#

for no real added benefit

clear folio
#

i use classes because it loks sexier

#

it makes me look like a professional

topaz oracle
#

how about you give it a try first?

clear folio
#

try to what

#

bro

topaz oracle
clear folio
topaz oracle
#

alright alright

#

can you just send that piece of code with the App class?

#

@clear folio

clear folio
#

here bro

#

@topaz oracle

topaz oracle
#

!screenshot

quaint owlBOT
#
`!screenshot`:

Rather than screenshots, please provide either code formatted as:

```ts
// code here
```
Or even better, as an example on the TypeScript playground that is as simple as possible and reproduces the issue. This makes it easier to help you and increases the chances of getting an answer.

clear folio
#
import dotenv from "dotenv";
import express, {Application, Request, Response} from "express";
import { EnvError } from "./error";
import UserRouter from "./routers/users";
import UserController from "./controllers/users";

class App {
    private _app: Application

    public constructor() {
        this._app = express()
    }

    public start() {
        dotenv.config();

        const port = process.env.PORT;
        const host = process.env.HOST;
        const date = new Date();
        const time = `${date.getHours()}:${date.getMinutes()}`;
        
        if(!host || !port) throw new EnvError("Failed to read enviroment table.");

        this._app.use("/user", )
        
        this._app.listen(port, () => {
            console.log(`${time} | [STARTUP]: Server is running at: http://${host}:${port}`)
        });

        
    }
}

export default App;
#

@quaint owl

quaint owlBOT
#
advertised#0576

Preview:ts import dotenv from "dotenv" import express, { Application, Request, Response, } from "express" import {EnvError} from "./error" import UserRouter from "./routers/users" import UserController from "./controlle ...

clear folio
#

@topaz oracle here

topaz oracle
#

yes

quaint owlBOT
#
ascor8522#0

Preview:```ts
import dotenv from "dotenv"
import express, {
Application,
Request,
Response,
Router,
} from "express"
import {PrismaClient, User} from "@prisma/client"

declare interface User {}

///////////////////////

export class App {
private
...```

topaz oracle
#

there

#

this code is ridiculous, but anyway

#

@clear folio

clear folio
#

lol what

topaz oracle
#

no, what you have here is already peak programming in term of class based REST API

clear folio
#

actually no

#

look at his code

topaz oracle
#

well, it's not class based

#

also Deno Catto

clear folio
#

whats the difference between deno and t his though

topaz oracle
#

not for the routers or middlewares

topaz oracle
clear folio
#

thats ridiculous

topaz oracle
#

your code's ridiculous

clear folio
#

im gonna have to recode all this

clear folio
#

i make only

#

the controller class based

topaz oracle
#

and what are you trying to achieve with that?

clear folio
#

you could just say

#

UserController.getUsers()

#

and get the getUsers func

topaz oracle
#

could also just have a file with a bunch of functions

#

and when importing that file, name it "UserController"

clear folio
#

Usercontroller.getUsers() though

topaz oracle
#

yes

#
import * as UserController from "./user-controller";

// [...]

router.get("/users", UserController.getUsers);
topaz oracle
#

it's expecting an instance

#

and you are passing a class

clear folio
#

what is an instance bro

#

im not apassing a class

topaz oracle
#

yes, you are

clear folio
#

no?

topaz oracle
#
class Foo {} // Foo is a class

const foo = new Foo(); // foo is an instance of Foo
#

now replace Foo by Request

clear folio
#

what do i pass then

topaz oracle
#

nothing

#

but please, if you don't understand something, go look up the related documentation

#

for express as well as for js

clear folio
#

if i don't pass anything where does it get the request thats coming ftom

topaz oracle
#

that's the thing

#

the app recieves a connection from an user

clear folio
#

im gonna kill myself

#

i dont undewrstand

topaz oracle
#

so the app creates the request object

clear folio
#

app recieves a connection from a user?

topaz oracle
#

and pass it to the router

clear folio
#

app creates a request object?

topaz oracle
#

wich pass it to your controller

clear folio
#

will this app do that?

topaz oracle
topaz oracle
#

(usually named "app")

#

@clear folio look

#
const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})
#

you don't need to create a requet yourself

clear folio
#

is this right

topaz oracle
#

the app recieves an incoming request from a browser, it passes it to the router you registered (using app.use) (not present in this example), which in turn calls the handler you registered (using .get)

#

yes

topaz oracle
#
app.get('/', (req, res) => {
  res.send('Hello World!')
})
#

like, you are passing 2 parameters

#

the path for the handler

#

and the handler itself (a function)

#

and that function will be called when a request arrives for that path

#

you don't need to createand pass a request

clear folio
#

then what the hell is this

topaz oracle
#

just create your express app, your express router, and register routes

topaz oracle
#

in the UserController, there is the getUsers method, what are its types?

clear folio
topaz oracle
#

right, this is wrong

clear folio
#

WHA HOW

topaz oracle
#

you need to import Request and Response from express in your UserController file

topaz oracle
#

it's another one with the same name

clear folio
#

FINALYLLFtheres no

#

what about this part

topaz oracle
clear folio
#

NO

#

WAIT

#

i did that

#

but what the fck

topaz oracle
#

it's relative paths

clear folio
#

its not working

topaz oracle
#

but also, you should be getting errors if the path in wrong

#

errors in TS code, in your editor

clear folio
#

thats what i don't understand

#

it does this

#

also path is clearly right

magic yarrow
#

relative paths need to start with . or ..

#

if you start a path with text like that it is called a bare import (specifier), and refers to a package that should be in node_modules