const [todos, count] = await this.repository.createQueryBuilder('todo')
.leftJoinAndSelect('todo.subtodos', 'subtodo')
.where('todo.user = :userId', { userId })
.orderBy('todo.createdAt', 'DESC')
.skip(skip)
.take(limit)
.getManyAndCount();
전체 글
- [TypeOrm] leftjoin and pagination 2023.03.09
- [Android] Fragment onCreate vs onCreateView 2023.03.05
- [Nest.js] what is Provider? 2023.03.01
- [Nest.js] Property 'user' does not exist on type 'Request'.25 return req.user; 2023.02.23
- [Nest.js] class-validator가 동작 안할 때 2023.02.22
- [Nest.js] eslintrc, prettierrc 들여쓰기 4칸으로 설정하기, 괄호 내부 띄어쓰기 허용하기 2023.02.21
- Oracle Apex Phone number format setting 2023.01.10
- [PlayWright] 웹페이지 크롤링 및 json 데이터 만들기 2023.01.07
[TypeOrm] leftjoin and pagination
[Android] Fragment onCreate vs onCreateView
onCreate is called on initial creation of the fragment. You do your non graphical initializations here. It finishes even before the layout is inflated and the fragment is visible.
onCreateView is called to inflate the layout of the fragment i.e graphical initialization usually takes place here. It is always called some time after the onCreate method.
'Android' 카테고리의 다른 글
retrofit multipart활용해 서버와 통신시 따옴표가 포함되는 문제 해결 방법 (0) | 2022.11.11 |
---|---|
안드로이드 쓰레드와 핸들러 사용방법 (0) | 2022.10.22 |
안드로이드 정리 (0) | 2022.10.20 |
[안드로이드 & 코틀린] 레트로핏과 인터셉터를 이용하여 API 호출하기 (0) | 2022.10.02 |
[Kotlin] 매개변수가 존재하는 싱글턴 만들기 (0) | 2022.10.01 |
[Nest.js] what is Provider?
In NestJS, providers are a fundamental concept of the Dependency Injection (DI) system.
Providers are classes or values that are defined within the module and can be injected into other classes
(components, controllers, other providers) within the same module or in other modules.
In other words, providers are objects or functions that can be injected into other objects or functions to provide them with some functionality or data. Providers are used to manage the dependencies of your application and to promote code reuse by allowing you to define and share common services across multiple components or modules.
To define a provider in NestJS, you need to use the @Injectable() decorator.
This decorator tells the NestJS DI system that the class can be injected into other classes as a dependency.
Once a provider is defined, it can be injected into other classes using the constructor() function.
Here's an example of a simple provider:
@Injectable()
export class LoggerService {
log(message: string) {
console.log(message);
}
}
In this example, the LoggerService class is defined as a provider using the @Injectable() decorator.
This means that it can be injected into other classes that require a logging service.
The log() method can be called to log a message to the console.
To use this provider in another class, you can inject it in the constructor like this:
@Injectable()
export class MyService {
constructor(private readonly logger: LoggerService) {}
doSomething() {
this.logger.log('Doing something...');
}
}
In this example, the MyService class injects the LoggerService provider in the constructor.
The doSomething() method can then call the log() method of the logger to log a message.
Providers are a powerful feature of NestJS that allow you to build modular and reusable applications.
'Nest.js' 카테고리의 다른 글
[Nest.js] Property 'user' does not exist on type 'Request'.25 return req.user; (0) | 2023.02.23 |
---|---|
[Nest.js] class-validator가 동작 안할 때 (0) | 2023.02.22 |
[Nest.js] eslintrc, prettierrc 들여쓰기 4칸으로 설정하기, 괄호 내부 띄어쓰기 허용하기 (0) | 2023.02.21 |
Nest js를 활용하여 Jwt 토큰을 발급받고 인증하는 과정을 공부하던 중에
req.user에 오류가 발생했다.
타입스크립트 passport 라이브러리를 다시 설치하고 다른 코드에 잘못 쓴게 있는지 한참을 찾아봤는데
도통 원인을 발견할 수 없었다.
https://stackoverflow.com/questions/64234974/ts2339-property-user-does-not-exist-on-type-request
그러다 위 글을 보고 문제를 해결했다.
req: Request로 타입을 지정해줬는데
Request를 import 하지 않아 어떤 타입인지 읽지 못해
req.user를 읽을 수 없던 것이었다.
import { Request } from 'express';
를 추가해주니 문제가 해결되었다.
'Nest.js' 카테고리의 다른 글
[Nest.js] what is Provider? (0) | 2023.03.01 |
---|---|
[Nest.js] class-validator가 동작 안할 때 (0) | 2023.02.22 |
[Nest.js] eslintrc, prettierrc 들여쓰기 4칸으로 설정하기, 괄호 내부 띄어쓰기 허용하기 (0) | 2023.02.21 |
[Nest.js] class-validator가 동작 안할 때
If class-validator is not working in your Nest.js application, there are a few things you can try:
- Ensure that you have installed the class-validator package by running npm install class-validator or yarn add class-validator.
- Ensure that you have imported the ValidationPipe from the @nestjs/common package and added it to the main.ts file in your application. The ValidationPipe will automatically use class-validator to validate incoming requests. Here's an example of what the main.ts file might look like:
-
javascriptCopy code
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(3000);
}
bootstrap();
4. Ensure that you have added the @UsePipes decorator to your controller methods that need validation. Here's an example of how you might use the @UsePipes decorator:In this example, the @UsePipes decorator is used to apply the ValidationPipe to the create method of the CatsController. The ValidationPipe will automatically validate the catRequestDto parameter using the validation rules defined in the CatRequestDto class.
5.lessCopy code
import { Controller, Post, UsePipes, Body } from '@nestjs/common';
import { CatRequestDto } from './dto/cat-request.dto';
import { ValidationPipe } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Post()
@UsePipes(new ValidationPipe())
async create(@Body() catRequestDto: CatRequestDto) {
// code to create a new cat
}
}
I hope these tips help resolve your issue with class-validator in your Nest.js application. If you're still having trouble, feel free to provide more details and I'll do my best to assist you further.
'Nest.js' 카테고리의 다른 글
[Nest.js] what is Provider? (0) | 2023.03.01 |
---|---|
[Nest.js] Property 'user' does not exist on type 'Request'.25 return req.user; (0) | 2023.02.23 |
[Nest.js] eslintrc, prettierrc 들여쓰기 4칸으로 설정하기, 괄호 내부 띄어쓰기 허용하기 (0) | 2023.02.21 |
[Nest.js] eslintrc, prettierrc 들여쓰기 4칸으로 설정하기, 괄호 내부 띄어쓰기 허용하기
Nest.js 프레임워크를 설치하면 자동으로 eslintrc, prettierrc 파일이 따라온다.
eslint와 prettier은 코드 컨벤션을 유지하기 위해 코드를 포맷팅해주고,
설정된 코드 컨벤션에 위반되는 코드가 존재하면 빨간줄을 그어 경고를 한다.
1. 들여쓰기 4칸으로 설정
나는 평소에 vscode에서 들여쓰기를 할 때 4칸을 띄우는 세팅을 이용하는데
eslint와 prettier의 기본 세팅은 2칸을 띄우는 걸 적용하여 4칸을 띄우면 빨간줄을 띄운다.
4칸을 띄우는 걸 기본 세팅으로 바꾸려면 .prettierrc 파일에 "tabWidth" : 4 를 추가하면 된다.
{
"singleQuote": true,
"tabWidth": 4,
"trailingComma": "all"
}
여기서 탭 정렬을 몇칸으로 설정할 건지는 하단의 링크를 보고 따라하면 된다.
https://dubaiyu.tistory.com/180
2. 괄호 내부 띄어쓰기
초기 세팅에서는 괄호 안에 그냥 띄어쓰기를 쓰면 위와 같이 빨간줄을 그어서 신경이 쓰인다.
괄호 내부 띄어쓰기를 허용하려면
위 코드를 .eslintrc.js에 추가해주면 된다.
.eslintrc.js
module.exports = {
parser: "@typescript-eslint/parser",
parserOptions: {
project: "tsconfig.json",
tsconfigRootDir: __dirname,
sourceType: "module",
},
plugins: ["@typescript-eslint/eslint-plugin"],
extends: [
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: [".eslintrc.js"],
rules: {
"prettier/prettier": ["error", { "endOfLine": "off" }],
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "off",
},
};
'Nest.js' 카테고리의 다른 글
[Nest.js] what is Provider? (0) | 2023.03.01 |
---|---|
[Nest.js] Property 'user' does not exist on type 'Request'.25 return req.user; (0) | 2023.02.23 |
[Nest.js] class-validator가 동작 안할 때 (0) | 2023.02.22 |
Oracle Apex Phone number format setting
document.getElementById('P300_전화번호').addEventListener('input',function(y)
{
var output = y.target.value.replace(/\D/g,'').match(/(\d{0,3})(\d{0,4})(\d{0,4})/);
y.target.value = !output[2]?output[1]:output[1]+'-'+output[2]+(output[3]?'-'+output[3]:'');
});
document.getElementById('P300_사업자번호').addEventListener('input',function(y)
{
var output = y.target.value.replace(/\D/g,'').match(/(\d{0,3})(\d{0,2})(\d{0,5})/);
y.target.value = !output[2]?output[1]:output[1]+'-'+output[2]+(output[3]?'-'+output[3]:'');
});
[PlayWright] 웹페이지 크롤링 및 json 데이터 만들기
https://blog.apify.com/how-to-scrape-the-web-with-playwright-ece1ced75f73/
import { chromium } from "playwright";
const browser = await chromium.launch({
headless: false
})
const context = await browser.newContext({
bypassCSP: true
});
const page = await context.newPage();
await page.goto("https://github.com/topics/javascript")
for (let i = 1; i < 10; i++) {
await page.click('text=Load more');
}
const repos = await page.$$eval('article.border', (repoCards) => {
return repoCards.map(card => {
const [user, repo] = card.querySelectorAll('h3 a');
const stars = card.querySelector('#repo-stars-counter-star')
.getAttribute('title');
const description = card.querySelector('div.px-3 > p');
const topics = card.querySelectorAll('a.topic-tag')
const toText = (element) => element && element.innerText.trim();
const parseNumber = (text) => Number(text.replace(/,/g, ''))
return {
user: toText(user),
repo: toText(repo),
url: repo.href,
stars: parseNumber(stars),
description: toText(description),
topics: Array.from(topics).map((t) => toText(t))
}
})
})
console.log(`We extracted ${repos.length} repositories.`);
// console.dir(repos);
await page.pause();
await page.waitForTimeout(10000);
await browser.close()
crawlee 활용
import { Configuration, PlaywrightCrawler } from "crawlee";
Configuration.set('headless', false)
const crawler = new PlaywrightCrawler({
requestHandler: async ({ page, infiniteScroll }) => {
const title = await page.title()
console.log(title)
await infiniteScroll({
buttonSelector: 'text=Load more',
stopScrollCallback: async () => {
const repos = await page.$$('article.border');
return repos.length >= 100;
},
})
const repos = await page.$$eval('article.border', (repoCards) => {
return repoCards.map(card => {
const [user, repo] = card.querySelectorAll('h3 a');
const stars = card.querySelector('#repo-stars-counter-star')
.getAttribute('title');
const description = card.querySelector('div.px-3 > p');
const topics = card.querySelectorAll('a.topic-tag');
const toText = (element) => element && element.innerText.trim();
const parseNumber = (text) => Number(text.replace(/,/g, ''));
return {
user: toText(user),
repo: toText(repo),
url: repo.href,
stars: parseNumber(stars),
description: toText(description),
topics: Array.from(topics).map((t) => toText(t)),
};
});
});
console.log('Repository count:', repos.length);
console.dir(repos);
await page.waitForTimeout(10000)
}
})
await crawler.run(['https://github.com/topics/javascript'])
router 활용하여 깔끔하게 코드 작성
// crawlee.js
import { Dataset, PlaywrightCrawler } from 'crawlee';
import { router } from './router.js';
const crawler = new PlaywrightCrawler({
requestHandler: router
})
await crawler.run(['https://github.com/topics/javascript'])
await Dataset.exportToCSV('repositories');
// router.js
import { createPlaywrightRouter, Dataset, Request } from 'crawlee';
export const router = createPlaywrightRouter();
const REPO_COUNT = 20;
router.use(async ({ page }) => {
const title = await page.title()
console.log(title);
})
router.addHandler('repository', async ({ page, request }) => {
const commitText = await page
.getByRole('listitem', )
.filter({ hasText: 'commits'})
.textContent()
const numberStrings = commitText.match(/\d+/g);
const commitCount = Number(numberStrings.join(''));
await Dataset.pushData({
...request.userData,
commitCount,
});
});
router.addDefaultHandler(async ({ page, infiniteScroll, crawler }) => {
await infiniteScroll({
buttonSelector: 'text=Load more',
stopScrollCallback: async () => {
const repos = await page.$$('article.border');
return repos.length >= REPO_COUNT;
},
});
const repos = await page.$$eval('article.border', (repoCards) => {
return repoCards.map(card => {
const [user, repo] = card.querySelectorAll('h3 a');
const stars = card.querySelector('#repo-stars-counter-star')
.getAttribute('title');
const description = card.querySelector('div.px-3 > p');
const topics = card.querySelectorAll('a.topic-tag');
const toText = (element) => element && element.innerText.trim();
const parseNumber = (text) => Number(text.replace(/,/g, ''));
return {
user: toText(user),
repo: toText(repo),
url: repo.href,
stars: parseNumber(stars),
description: toText(description),
topics: Array.from(topics)
.map((t) => toText(t)),
};
});
});
console.log('Repository count:', repos.length);
const requests = repos.map(repo => new Request({
url: repo.url,
label: 'repository',
userData: repo,
}));
await crawler.addRequests(requests);
})