const nodemailer = require("nodemailer"); router.sendMail = (req, res) => { const stmpconfig = { host: "smtpAddress", port: "465", secure: true, auth: { user: "abc@def.com", pass: "123456" } }; const from = "발신자명 < abc@def.com >"; const to = "수신자 이메일 주소"; const subject = "제목"; const html = "<p>내용</p>"; let mailOptions = { from, to, subject, html }; const transporter = nodemailer.createTransport(stmpconfig); transporter.verify((err, success) => { if (err) console.error(err); console.log("Your config is correct / " + success); }); transporter.sendMail(mailOptions, function(err, res) { if (err) { console.error("🤕 NodeMailer test failed with error:\n", err); } else { console.log("this is a new password: " + password); console.log("📬 Successfully sent NodeMailer test with result:\n", res); } }); transporter.close; res.send("it's over"); };


router.updateQA = (req, res) => {
    const data = (req.method == 'POST') ? req.body : req.query;
    const id = req.query._id;
    const fields = 'name, profile.qa'
    UserData.model
        .findById(id)
        .exec((err, user) => {
            if (err) return res.apiError(err);
            if (!user) return res.apiResponse({ message: "no user" });
            user.getUpdateHandler(req).process(
                data,
                { 
                    flashErrors: true, 
                    fields: fields,
                    errorMessage: 'error!!'
                },
                err => {
                    if (err) return res.apiError("error", err);
                    res.apiResponse({
                        status: "success",
                        result: user
                    });
                }
            );
        })
}

https://keystonejs.com/api/list/update-item/

fields: String|Array

A list of fields to attempt to update. All other fields will not be updated even if values are provided. 
If a string is passed, it will attempt to use list-to-array to transform the string.

즉 fields 에 주어진 필드들 외에 필드들은 값이 주어지더라도 업데이트 안함. 그리고 주어진 필드중의 필드를 업데이트 하지 않아도 상관없음.
그러나 업데이트 할 Document 의 필드 속성중 Relationship Type 필드들은 업데이트시 값을 주지 않으면 값이 날라감. 그외 필드들은 영향 없음
그래서 RelationshipType이 들어가는 Document 업데이트는 무조건 사용해야할듯



Ex)
-User Model

User.add({
    ... ,
	password: { type: Types.Password, initial: true, required: true },
	name: { type: Types.Name },
	birthday: { type: Types.Date, index: true, default: Date.now },
	gender: { type: Types.Select, options: 'M, W', default: 'M' },
	nationality: { type: Types.Relationship, ref: 'Nationality', initial: true },
    ...
})

let fields = 'password, name, gender, birthday';
if (data.nationality) fields += ', nationality';

password, name, gender, birthday 필드들은 relationship 타입이 아니라 값을 넣어도 되고 안넣어도 됨.
하지만 relationship 타입인 nationality 가 fields 에 들어있고 api 날릴때 key, value 값이 주어지지 않으면 null 값이 들어가 원래 값이 날라감.
그래서 User update 할 때 data 에 nationality 키가 포함 되어있으면 fields 에 포함시키고 아니면 포함 안 시킴.


'IT > KeystonJS' 카테고리의 다른 글

nodemailer 로 메일 보내기 + Keystonejs  (0) 2018.12.28
Keystone + Next js Routing 설정  (0) 2018.12.10
Keystonejs + Nextjs Production mode 설정  (0) 2018.12.05

1. 해당 EC2의 security group 에서 inbound 포트를 mongodb 포트로 열어준다


2. mongodb 를 실행중이라면


> sudo service mongod stop


으로 정지 시킨다


(간혹 위 명령어가 안 먹힐때가 있는데 그때는 


> cd /run/mongodb 로 해당 폴더로 이동하여


> ls 를 입력하면 mongod.pid 파일이 존재한다. 이유는 ec2 로컬에서 이미 mongod 로 서비스 중이라 그렇다.


우리는 sudo service mongod 를 사용할 예정이므로


> sudo rm -rf mongod.pid 로 해당 파일을 삭제한다)


3. 정지 시킨뒤 sudo vi /etc/mongod.conf 로 conf 파일을 아래와 같이 수정한다




bindIp 앞의 #을 지워주고 bindIp 를 위와 같이 0.0.0.0 으로 바꿔준다


원래 127.0.0.1 로 되어있는데 이건 해당 ec2 로컬에서만 접속가능하게 하기 위해서 이므로 bindIp 변경이 필수다.


혹시나 

해당 부분에 #이 안되어 있으면 #을 꼭 해줘야 본인 컴퓨터 로컬에서 접속이 가능하다


4. conf 파일을 저장하고 (혹시나 모른다면 esc -> wq -> enter 로 변경사항 저장후 나가기 이다)


> sudo service mongod restart 로 mongodb 를 재시작 해준다.


5. 로컬 컴퓨터에서 compass 를 켠다.


Hostname : elasticip

Port : mongodb port


그리고 connect 를 하면 접속 성공


6. 혹시나 그래도 compass 에서 접속시 에러가 나서 접속이 불가능 하다면 ec2 로컬에서 

> mongo 

로 db에 접속하여 admin 이나 root 계정을 만들어준다



모든 element의 position의 default 는 static 이다


static

이 말은 내가 element의 위치를 정해주면 그 자리에 보여준다는 뜻이다.

ex) position: static;


fixed

해당 element가 화면의 위치에 fixed 되어서 스크롤을 하더라도 그 위치에 고정되어있다. (즉 화면 최상단에 element 가 고정됨)


position:fixed 를 사용하면 여러가지 properties 를 추가로 사용 할 수 있는데

top, bottom, left, right 으로 해당 방향 에 간격을 줄 수 있다.

ex) 

position: fixed;

top: 10px;

left: 10px;

right: 5px;

bottom: 20px;


absolute


fixed 랑 비슷한데 스크롤하면 사라짐

역시 top, bottom, left, right 사용 가능


absolute에서 중요한건 postion: absolute; 를 사용하면

html 상에서 해당 element 와 관계가 있는데 (position: relative) element 를 살펴보고 이에 상응해서 포지션이 결정됨


relative

단 position relative 가 없다면 그냥 설정한 그대로 놓여짐. 

(즉, 자식 element가 absolute 이고 그 위에 부모 element가 relative 이면 자식 element는 부모 element를 기준으로 움직이고, 

relative가 아예 없다면 body에 바로 올라감.)



'IT > HTML+CSS' 카테고리의 다른 글

CSS display block, Inline, Inline-block  (0) 2018.12.11
CSS margin, padding, border 간략 설명 + Shortcut  (0) 2018.12.11

display에서


block 은 해당 컨텐트 하나를 제외하고 그 옆에는 아무것도 없고

inlie-block 은 컨텐트 들이 서로서로 붙는 것

inline 은 block이 아니라 text가 됨. 그래서 높이, 폭이 존재하지않음, 컨텐츠의 길이만 존재

즉, 해당 컨텐트의 css의 property들을 다 지움


'IT > HTML+CSS' 카테고리의 다른 글

CSS position property  (0) 2018.12.11
CSS margin, padding, border 간략 설명 + Shortcut  (0) 2018.12.11

margin

border

padding

content

식으로 margin은 border 밖이고 padding은 border 안.

그리고 border 안에 content가 있음


Padding, margin


padding(or margin): top-bottom left-right;

ex) padding: 10px 20px;

padding(or margin): top right bottom left; (top부터 시계방향)

ex) margin: 20px 5px 10px 15px


border


border: width style color

ex) border: 5px dashed red;

'IT > HTML+CSS' 카테고리의 다른 글

CSS position property  (0) 2018.12.11
CSS display block, Inline, Inline-block  (0) 2018.12.11

Keystone 이 Routing 하지 않고 Next가 하게 하려면

1.

kestone.js 를


require('dotenv').config();

const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });


var keystone = require('keystone');

keystone.init({
    'name': 'keystone_next_react',
    'brand': 'keystone_next_react',
    'auto update': true,
    'session': true,
    'auth': true,
    'user model': 'User',
});


keystone.import('models');

app.prepare()
    .then(() => {
        keystone.set('locals', {
            _: require('lodash'),
            env: keystone.get('env'),
            utils: keystone.utils,
            editable: keystone.content.editable,
        });
        
        keystone.set('routes', require('./routes')(app));
        
        keystone.set('nav', {
            posts: ['posts', 'post-categories'],
            users: 'users',
        });
        
        keystone.start();
    })


이렇게 바꾼다.


keystone.set('routes', require('./routes')(app));


이부분이 keytone의 라우팅을 next가 하게 해주는 부분이다.


next가 라우팅을 하게 하려면

프로젝트의 root 에서 pages 폴더를 만들어 그 안에 보여줄 화면들을 만든다. 

https://youtu.be/x3rhCJWGFc4 를 보며 공부하고, 이해하기 위해 정리 중입니다.


map() 메소드는 파라미터로 전달 된 함수를 통하여 배열 내의 각 요소를 처리해서 그 결과로 새로운 배열을 생성합니다.


사용 문법

arr.map(callback, [thisArg])


callback 새로운 배열의 요소를 생성하는 함수로서, 다음 세가지 인수를 가집니다.

currentValue 현재 처리되고 있는 요소

index 현재 처리되고 있는 요소의 index 값

array 메소드가 불려진 배열

thisArg (선택항목) callback 함수 내부에서 사용 할 this 값을 설정


Ex)

let numbers = [1,2,3,4,5];


let result = numbers.map((num) => {

return num*num;

});


결과값: [1, 4, 9, 16, 25]


똑같은 원리로 배열을 매핑 할수 있다.

데이터 배열을 렌더링 할때는 map으로 간단하게.





render() { const mapToComponents = (data) =>{ return data.map((contact, i)=>{ return(<ContactInfo contact={contact} key={i}/>) }) }; return(<ContactInfo contact={contact} key={i}/>) ;


에서 key 를 포함 하는 이유는 리액트에서는 array에서 키로 아이템을 identify 해서 어떤 아이템의 상태변화가 있을때, 바로 알 수 있게 한다고 한다.


(참조:
https://reactjs.org/docs/lists-and-keys.html#keys )


Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity:


const numbers = [1, 2, 3, 4, 5];

const listItems = numbers.map((number) =>

<li key={number.toString()}>

${number}

</li>

);


가장 좋은 방법은 아이템에 유니크한 id를 키로 부여하는 방법이다 (id가 있다면)


const todoItems = todos.map((todo) =>

<li key={todo.id}>

{todo.text}

</li>

);


아이템의 정렬 순서가 바뀔지도 모르기 때문에 인덱스를 키로 사용하는걸 권장하지 않는다. 하지만 key를 설정하지 않으면 default로 인덱스를 키로 사용한다.
















'IT > ReactJS' 카테고리의 다른 글

state 란?  (0) 2018.12.07
props 란?  (0) 2018.12.07
react-redux는?  (0) 2018.12.07
Redux의 Store  (0) 2018.12.07
React 는 뭘까?  (0) 2018.12.05

https://youtu.be/i_ooWEUtCMc 를 보며 공부하며 정리 겸 작성하는 글입니다.


컴포넌트에서 유동적인 데이터를 보여줄때 사용됨

초기값 설정이 필수, 생성자(constructor) 에서 this.state = {} 로 설정


값을 수정할 때에는 렌더링 된 후에 this.setState({...} 가능. (즉 constructor 안에서, 렌더링 전에는 setState를 사용 불가능)

그리고 렌더링 된 후에는 this.state = 로 절대 수정 하지 말것 

(속도 및 React의 장점인 바뀐 부분만 업데이트 하는 걸 버리는 행위임 (forceUpdate 라는 메소드로 강제 업데이트가 가능하긴함))


예시)

class Counter extends Component {

  

  constructor(props) {

    super(props); 

    // super 를 통하여 부모인 Component의 생성자를 먼저 실행하고 할 작업들을 함.

    // super(props); 를 먼저 실행해줘야 이 메소드 안에서 this.state 라던지 props 라던지 를 접근할 수 있음.

    this.state = {

      value: 0

    };

    this.handleClick = this.handleClick.bind(this);

  }

  handleClick() {

    this.setState({

      value: this.state.value + 1

    });

  }

  render() {

    return (

      <div>

        <h2>{this.state.value}</h2>

        <button onClick={this.handleClick}>Press Me</button>

      </div>

    );

  }

}


class App extends Component {

  render() {

    return (

      <Counter />

    );

  }

};


ReactDOM.render(

  <App></App>,

  document.getElementById("root")

);


 

'IT > ReactJS' 카테고리의 다른 글

컴포넌트 매핑 (Component Mapping)  (0) 2018.12.07
props 란?  (0) 2018.12.07
react-redux는?  (0) 2018.12.07
Redux의 Store  (0) 2018.12.07
React 는 뭘까?  (0) 2018.12.05

https://youtu.be/atSIfMAmSic 에서 공부하며 안까먹고 나중에 다시 보기위해 정리한 내용 입니다.


props는


컴포넌트 내부의 Immutable Data 를 처리할때 사용 합니다.

props가 보여질

JSX 내부에 { this.props.propsName }

컴포넌트를 사용 할 때, < > 괄호 안에 propsName="value"

this.props.children 은 기본적으로 갖고있는 props로서, <Cpnt>여기에 있는 값이 들어간다.</Cpnt>


이런 식으로.


상위 컴포넌트 에서 하위 컴포넌트로 전달하는 법은

(이 상황에서는 

App 컴포넌트가 상위 컴포넌트

Codelab 컴포넌트가 하위 컴포넌트)


ReactDOM 렌더링 할때 App 컴포넌트에 name 과 <App></App> 사이에 값을 넣고,

App 컴포넌트 리턴 하는 부분에 하위 컴포넌트인 Codelab의 name과 <Codelab></Codelab> 사이에 각각 {this.props.name} 과 {this.props.children} 을 넣어 주고

Codelab 컴포넌트 리턴 하는 부분에 {this.props.name} 과 {this.props.children} 을 넣으면 전달 완료!

 


props의 기본값을 설정하는 방법


컴포넌트의 선언이 끝난 뒤, 


컴포넌트명.defaultProps = {

value: 0

};

으로 설정하면 된다.


Type 검증 하는 방법

특정 props 값이 특정 props 타입이 아니거나,  필수 props인데 입력하지 않았을 경우 개발자 콘솔에서 경고 띄우게 할수 있음


방법은,

컴포넌트의 선언이 끝난 뒤,

(React v15.5 부터 React.PropTypes 가 deprecated 되어서 prop-types 라이브러리 추가해야함)


컴포넌트명.propTypes = {

value: PropTypes.String,

secondValue: PropTypes.number,

thirdValue: PropTypes.any.isRequired

};


propTypes는 필수가 아니지만 유지보수 할때 남이 봤을때 한번에 알아볼수 있게 해야하므로 필요함.






'IT > ReactJS' 카테고리의 다른 글

컴포넌트 매핑 (Component Mapping)  (0) 2018.12.07
state 란?  (0) 2018.12.07
react-redux는?  (0) 2018.12.07
Redux의 Store  (0) 2018.12.07
React 는 뭘까?  (0) 2018.12.05

+ Recent posts